require 'json-schema' require 'yaml' require_relative 'compose/types' module Siren class Compose attr_reader :name, :xports, :xdomains, :xenv def self.load (filename) new(YAML.load(File.read(filename)).deep_compact, filename) end def namify (*items) items.flatten.compact.join("-").downcase.gsub(/[^a-z\d]/, '-').gsub(/-+/, "-") end def initialize (data, filename) @filename = filename @services = {} @networks = {} @configs = {} @secrets = {} @xports = [] @xdomains = [] @xenv = {} @name = data["x-name"] || namify(File.basename(filename.chomp(File.extname(filename)))) data = data schema = YAML.load(File.read(File.join(Siren::ROOT, "schemas/docker-compose.yaml"))) begin JSON::Validator.validate!(schema, data) rescue JSON::Schema::ValidationError => e # puts filename p e exit 1 end data["x-ports"]&.each do |data| next unless data["outside"] @xports << data end data["x-domains"]&.each do |data| data["name"].gsub! ".altaire.xyz", ".k9.altaire.xyz" next unless data["name"] =~ /k9.altaire.xyz$/ data.delete("path") if data["path"] == "" @xdomains << data end data["x-env"]&.each do |key, value| @xenv[key] = value end data["services"].each do |name, data| @services[name] = Service.new(self, {name: name}.merge(data)) end if data["services"] data["networks"].each do |name, data| @networks[name] = Network.new(self, {name: name}.merge(data)) end if data["networks"] data["configs"].each do |name, data| @configs[name] = Config.new(self, {name: name}.merge(data)) end if data["configs"] data["secrets"].each do |name, data| @secrets[name] = Secret.new(self, {name: name}.merge(data)) end if data["secrets"] end def to_stack () stack = Stack.new stack << { kind: "Namespace", apiVersion: "v1", metadata: { name: name }, } stack << { kind: "Secret", apiVersion: "v1", metadata: { namespace: name, name: "image-pull-secrets", }, data: { ".dockerconfigjson": "ewoJImF1dGhzIjogewoJCSJodHRwczovL2FzaWEtbWlycm9yLmdjci5pbyI6IHsKCQkJImF1dGgiOiAiYjJGMWRHZ3lZV05qWlhOemRHOXJaVzQ2ZVdFeU9TNUhiSG95UWtGdk1tTnlZWEJJUkZabllWWTViak5oVFdKWFpFVkNZVWd3UlZNM2RIQXdjVUZzT1ZsdUxUWlRiVVZ5UjFoR1pXUXhhaTAwYlhCMVJYcDFlVlJNU0RSV1dGVlZaMnRyV0VwR1FuZEJhbk5zV2xsYU9HeFJTWFk0VFRKblVUVm5OVEk1TVUxTVQydG9abWN0V2s1VGFVVmpXVWszWld4ZlZIYz0iLAoJCQkiZW1haWwiOiAibm90QHZhbC5pZCIKCQl9LAoJCSJodHRwczovL2FzaWEuZ2NyLmlvIjogewoJCQkiYXV0aCI6ICJiMkYxZEdneVlXTmpaWE56ZEc5clpXNDZlV0V5T1M1SGJIb3lRa0Z2TW1OeVlYQklSRlpuWVZZNWJqTmhUV0pYWkVWQ1lVZ3dSVk0zZEhBd2NVRnNPVmx1TFRaVGJVVnlSMWhHWldReGFpMDBiWEIxUlhwMWVWUk1TRFJXV0ZWVloydHJXRXBHUW5kQmFuTnNXbGxhT0d4UlNYWTRUVEpuVVRWbk5USTVNVTFNVDJ0b1ptY3RXazVUYVVWaldVazNaV3hmVkhjPSIsCgkJCSJlbWFpbCI6ICJub3RAdmFsLmlkIgoJCX0sCgkJImh0dHBzOi8vZXUtbWlycm9yLmdjci5pbyI6IHsKCQkJImF1dGgiOiAiYjJGMWRHZ3lZV05qWlhOemRHOXJaVzQ2ZVdFeU9TNUhiSG95UWtGdk1tTnlZWEJJUkZabllWWTViak5oVFdKWFpFVkNZVWd3UlZNM2RIQXdjVUZzT1ZsdUxUWlRiVVZ5UjFoR1pXUXhhaTAwYlhCMVJYcDFlVlJNU0RSV1dGVlZaMnRyV0VwR1FuZEJhbk5zV2xsYU9HeFJTWFk0VFRKblVUVm5OVEk1TVUxTVQydG9abWN0V2s1VGFVVmpXVWszWld4ZlZIYz0iLAoJCQkiZW1haWwiOiAibm90QHZhbC5pZCIKCQl9LAoJCSJodHRwczovL2V1Lmdjci5pbyI6IHsKCQkJImF1dGgiOiAiYjJGMWRHZ3lZV05qWlhOemRHOXJaVzQ2ZVdFeU9TNUhiSG95UWtGdk1tTnlZWEJJUkZabllWWTViak5oVFdKWFpFVkNZVWd3UlZNM2RIQXdjVUZzT1ZsdUxUWlRiVVZ5UjFoR1pXUXhhaTAwYlhCMVJYcDFlVlJNU0RSV1dGVlZaMnRyV0VwR1FuZEJhbk5zV2xsYU9HeFJTWFk0VFRKblVUVm5OVEk1TVUxTVQydG9abWN0V2s1VGFVVmpXVWszWld4ZlZIYz0iLAoJCQkiZW1haWwiOiAibm90QHZhbC5pZCIKCQl9LAoJCSJodHRwczovL2djci5pbyI6IHsKCQkJImF1dGgiOiAiYjJGMWRHZ3lZV05qWlhOemRHOXJaVzQ2ZVdFeU9TNUhiSG95UWtGdk1tTnlZWEJJUkZabllWWTViak5oVFdKWFpFVkNZVWd3UlZNM2RIQXdjVUZzT1ZsdUxUWlRiVVZ5UjFoR1pXUXhhaTAwYlhCMVJYcDFlVlJNU0RSV1dGVlZaMnRyV0VwR1FuZEJhbk5zV2xsYU9HeFJTWFk0VFRKblVUVm5OVEk1TVUxTVQydG9abWN0V2s1VGFVVmpXVWszWld4ZlZIYz0iLAoJCQkiZW1haWwiOiAibm90QHZhbC5pZCIKCQl9LAoJCSJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOiB7CgkJCSJhdXRoIjogIllXeDBZV2x5Wld4MFpEcGFkbWhpYTNnelJHMTFaMjAwTkVWRVdIUjBlQT09IgoJCX0sCgkJImh0dHBzOi8vbC5nY3IuaW8iOiB7CgkJCSJhdXRoIjogImIyRjFkR2d5WVdOalpYTnpkRzlyWlc0NmVXRXlPUzVIYkhveVFrRnZNbU55WVhCSVJGWm5ZVlk1YmpOaFRXSlhaRVZDWVVnd1JWTTNkSEF3Y1VGc09WbHVMVFpUYlVWeVIxaEdaV1F4YWkwMGJYQjFSWHAxZVZSTVNEUldXRlZWWjJ0cldFcEdRbmRCYW5Oc1dsbGFPR3hSU1hZNFRUSm5VVFZuTlRJNU1VMU1UMnRvWm1jdFdrNVRhVVZqV1VrM1pXeGZWSGM9IiwKCQkJImVtYWlsIjogIm5vdEB2YWwuaWQiCgkJfSwKCQkiaHR0cHM6Ly9sYXVuY2hlci5nY3IuaW8iOiB7CgkJCSJhdXRoIjogImIyRjFkR2d5WVdOalpYTnpkRzlyWlc0NmVXRXlPUzVIYkhveVFrRnZNbU55WVhCSVJGWm5ZVlk1YmpOaFRXSlhaRVZDWVVnd1JWTTNkSEF3Y1VGc09WbHVMVFpUYlVWeVIxaEdaV1F4YWkwMGJYQjFSWHAxZVZSTVNEUldXRlZWWjJ0cldFcEdRbmRCYW5Oc1dsbGFPR3hSU1hZNFRUSm5VVFZuTlRJNU1VMU1UMnRvWm1jdFdrNVRhVVZqV1VrM1pXeGZWSGM9IiwKCQkJImVtYWlsIjogIm5vdEB2YWwuaWQiCgkJfSwKCQkiaHR0cHM6Ly9taXJyb3IuZ2NyLmlvIjogewoJCQkiYXV0aCI6ICJiMkYxZEdneVlXTmpaWE56ZEc5clpXNDZlV0V5T1M1SGJIb3lRa0Z2TW1OeVlYQklSRlpuWVZZNWJqTmhUV0pYWkVWQ1lVZ3dSVk0zZEhBd2NVRnNPVmx1TFRaVGJVVnlSMWhHWldReGFpMDBiWEIxUlhwMWVWUk1TRFJXV0ZWVloydHJXRXBHUW5kQmFuTnNXbGxhT0d4UlNYWTRUVEpuVVRWbk5USTVNVTFNVDJ0b1ptY3RXazVUYVVWaldVazNaV3hmVkhjPSIsCgkJCSJlbWFpbCI6ICJub3RAdmFsLmlkIgoJCX0sCgkJImh0dHBzOi8vdXMtbWlycm9yLmdjci5pbyI6IHsKCQkJImF1dGgiOiAiYjJGMWRHZ3lZV05qWlhOemRHOXJaVzQ2ZVdFeU9TNUhiSG95UWtGdk1tTnlZWEJJUkZabllWWTViak5oVFdKWFpFVkNZVWd3UlZNM2RIQXdjVUZzT1ZsdUxUWlRiVVZ5UjFoR1pXUXhhaTAwYlhCMVJYcDFlVlJNU0RSV1dGVlZaMnRyV0VwR1FuZEJhbk5zV2xsYU9HeFJTWFk0VFRKblVUVm5OVEk1TVUxTVQydG9abWN0V2s1VGFVVmpXVWszWld4ZlZIYz0iLAoJCQkiZW1haWwiOiAibm90QHZhbC5pZCIKCQl9LAoJCSJodHRwczovL3VzLmdjci5pbyI6IHsKCQkJImF1dGgiOiAiYjJGMWRHZ3lZV05qWlhOemRHOXJaVzQ2ZVdFeU9TNUhiSG95UWtGdk1tTnlZWEJJUkZabllWWTViak5oVFdKWFpFVkNZVWd3UlZNM2RIQXdjVUZzT1ZsdUxUWlRiVVZ5UjFoR1pXUXhhaTAwYlhCMVJYcDFlVlJNU0RSV1dGVlZaMnRyV0VwR1FuZEJhbk5zV2xsYU9HeFJTWFk0VFRKblVUVm5OVEk1TVUxTVQydG9abWN0V2s1VGFVVmpXVWszWld4ZlZIYz0iLAoJCQkiZW1haWwiOiAibm90QHZhbC5pZCIKCQl9LAoJCSJyZWdpc3RyeS5hbHRhaXJlLnRlY2g6NTAwMCI6IHsKCQkJImF1dGgiOiAiYm1GMGFHRnVPbTVoZEdoaGJnPT0iCgkJfSwKCQkicmVnaXN0cnkuYWx0YWlyZS54eXoiOiB7CgkJCSJhdXRoIjogIlpHOWphMlZ5T201bGVtNWhkRzFsZFdOamFXZHZZblJ2ZDJwcGJVZHZhbkJoZEhCdmIzSjAiCgkJfQoJfSwKCSJIdHRwSGVhZGVycyI6IHsKCQkiVXNlci1BZ2VudCI6ICJEb2NrZXItQ2xpZW50LzE4LjA5LjUtY2UgKGxpbnV4KSIKCX0KfQ==" }, type: "kubernetes.io/dockerconfigjson" } @services.each do |name, service| service.to_stack(stack) end @networks.each do |name, network| network.to_stack(stack) end @configs.each do |name, config| config.to_stack(stack) end @secrets.each do |name, secret| secret.to_stack(stack) end stack end end end