class Siren::Song
Attributes
env[R]
services[R]
Public Class Methods
load(filename)
click to toggle source
# File lib/siren/song.rb, line 9 def self.load (filename) new(YAML.load(File.read(filename))) end
new(data)
click to toggle source
# File lib/siren/song.rb, line 13 def initialize (data) @name = data["metadata"]["name"] @ns = data["metadata"]["namespace"] || @name @spec = data["spec"] process() end
Public Instance Methods
annotations()
click to toggle source
# File lib/siren/song.rb, line 60 def annotations { "siren.altaire.xyz/song": @name, } end
env_to_k8s(hash)
click to toggle source
# File lib/siren/song.rb, line 52 def env_to_k8s (hash) res = [] hash.each do |name, value| res << { name: name, value: value } end res end
get(what, key)
click to toggle source
# File lib/siren/song.rb, line 20 def get (what, key) return [] unless what.has_key?(key) val = what[key] if val.is_a?(Array) if val.count{|v|v.is_a?(Hash) && !(v.has_key?(:name) || v.has_key?("name") || v.has_key?(:fullName) || v.has_key?("fullName"))} > 1 raise "`#{key}`: only one can be anonymous" end return val end return [val] end
makename(base, obj, name = "name", fullName = "fullName", suffix = nil)
click to toggle source
# File lib/siren/song.rb, line 66 def makename (base, obj, name = "name", fullName = "fullName", suffix = nil) return obj[fullName] if obj[fullName] [base, name ? obj[name] : nil, suffix].compact.join("-") end
process()
click to toggle source
# File lib/siren/song.rb, line 32 def process () @env = {} @env.merge! process_env(@spec["env"] || {}) @services = get(@spec, "service").map do |svc| svc end end
process_env(hash)
click to toggle source
# File lib/siren/song.rb, line 40 def process_env (hash) hash = hash.dup hash.map do |name, value| next unless value.is_a?(Hash) case value.keys[0] when "encrypt" hash[name] = { "secure" => Siren::Crypto.encrypt(value.values[0]) } end end return hash end
to_certificate(svc)
click to toggle source
# File lib/siren/song.rb, line 135 def to_certificate (svc) name = makename(@name, svc) get(svc, "publish").map do |publish| get(publish, "domain").map do |domain| @stack.things << { apiVersion: "cert-manager.io/v1alpha2", kind: "Certificate", metadata: { annotations: annotations, name: name, namespace: @ns, }.compact, spec: { secretName: [name, get(publish, "domain").length > 1 ? domain : nil, "tls"].compact.join("-"), duration: "2160h", renewBefore: "360h", commonName: domain, dnsNames: [domain], issuerRef: {kind: "ClusterIssuer", name: "letsencrypt-production"}, }, } end end end
to_deployment(svc)
click to toggle source
# File lib/siren/song.rb, line 72 def to_deployment (svc) name = makename(@name, svc) @stack.things << { apiVersion: "apps/v1", kind: "Deployment", metadata: { annotations: annotations, name: name, namespace: @ns, }.compact, spec: { selector: { matchLabels: { service: name } }, template: { metadata: { annotations: annotations, labels: { service: name } }, spec: { containers: [ image: svc["image"], env: env_to_k8s(env.merge(svc["env"] || {})), ], imagePullSecrets: [{ name: "regcred" }], } }, }, } end
to_domain(svc)
click to toggle source
# File lib/siren/song.rb, line 160 def to_domain (svc) name = makename(@name, svc) get(svc, "publish").map do |publish| get(publish, "domain").map do |domain| @stack.things << { apiVersion: "altaire.com/v1alpha1", kind: "Domain", metadata: { annotations: annotations, name: [name, get(publish, "domain").length > 1 ? domain : nil].compact.join("-"), namespace: @ns, }.compact, spec: { domain: domain, service: publish["loadBalancer"] ? makename(name, publish["loadBalancer"]) : "traefik", } } end end end
to_ingress_route(svc)
click to toggle source
# File lib/siren/song.rb, line 181 def to_ingress_route (svc) name = makename(@name, svc) get(svc, "publish").map do |publish| next if publish["loadBalancer"] get(publish, "domain").map do |domain| @stack.things << { apiVersion: "traefik.containo.us/v1alpha1", kind: "IngressRoute", metadata: { annotations: annotations, name: [name, get(publish, "domain").length > 1 ? domain : nil].compact.join("-"), namespace: @ns, }.compact, spec: { tls: { secretName: [name, get(publish, "domain").length > 1 ? domain : nil, "tls"].compact.join("-") }, routes: [ { match: "Host(`#{domain}`)", kind: "Rule", services: [ { name: name, port: 80, } ], middlewares: publish["auth"] ? [{name: "altaire-auth"}] : [] } ] } } end end end
to_namespace()
click to toggle source
# File lib/siren/song.rb, line 215 def to_namespace () return if @ns == nil @stack.things << { apiVersion: "v1", kind: "Namespace", metadata: { annotations: annotations, name: @ns, }.compact, } end
to_service(svc)
click to toggle source
# File lib/siren/song.rb, line 107 def to_service (svc) svcname = makename(@name, svc) get(svc, "publish").group_by{|x|x["loadBalancer"]}.each do |loadbalancer, publish| name = makename(svcname, publish[0], "loadBalancer") @stack.things << { apiVersion: "v1", kind: "Service", metadata: { annotations: annotations, name: name, namespace: @ns, }.compact, spec: { selector: { service: svcname, }, ports: publish.map do |publish| { targetPort: publish["port"] || 80, port: publish["externalPort"] || publish["port"] || 80, } end, type: loadbalancer ? "LoadBalancer" : nil }.compact, } end end
to_stack()
click to toggle source
# File lib/siren/song.rb, line 227 def to_stack () @stack = Stack.new to_namespace() @services.each do |svc| to_deployment(svc) to_service(svc) to_certificate(svc) to_domain(svc) to_ingress_route(svc) end @stack end