kuber_kit 0.5.1 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +5 -5
- data/TODO.md +5 -5
- data/example/configurations/review.rb +1 -1
- data/example/services/docker_app.rb +2 -1
- data/example/services/env_file.rb +1 -1
- data/example/services/ruby_app.rb +2 -1
- data/lib/kuber_kit.rb +10 -0
- data/lib/kuber_kit/actions/kubectl_get.rb +32 -0
- data/lib/kuber_kit/actions/service_checker.rb +5 -0
- data/lib/kuber_kit/actions/service_deployer.rb +85 -61
- data/lib/kuber_kit/cli.rb +14 -3
- data/lib/kuber_kit/configs.rb +10 -6
- data/lib/kuber_kit/container.rb +20 -0
- data/lib/kuber_kit/core/artifacts/artifact_store.rb +3 -0
- data/lib/kuber_kit/core/configuration.rb +4 -2
- data/lib/kuber_kit/core/configuration_definition.rb +7 -0
- data/lib/kuber_kit/core/configuration_factory.rb +1 -0
- data/lib/kuber_kit/core/dependencies/abstract_dependency_resolver.rb +75 -0
- data/lib/kuber_kit/core/env_files/abstract_env_file.rb +4 -0
- data/lib/kuber_kit/core/env_files/artifact_file.rb +4 -0
- data/lib/kuber_kit/core/env_files/env_file_store.rb +3 -0
- data/lib/kuber_kit/core/env_files/env_group.rb +12 -0
- data/lib/kuber_kit/core/image.rb +2 -1
- data/lib/kuber_kit/core/registries/registry_store.rb +3 -0
- data/lib/kuber_kit/core/service.rb +4 -2
- data/lib/kuber_kit/core/service_definition.rb +13 -6
- data/lib/kuber_kit/core/service_factory.rb +1 -0
- data/lib/kuber_kit/core/templates/template_store.rb +3 -0
- data/lib/kuber_kit/env_file_reader/env_file_parser.rb +51 -0
- data/lib/kuber_kit/env_file_reader/env_file_tempfile_creator.rb +17 -0
- data/lib/kuber_kit/env_file_reader/reader.rb +2 -0
- data/lib/kuber_kit/env_file_reader/strategies/artifact_file.rb +9 -65
- data/lib/kuber_kit/env_file_reader/strategies/env_group.rb +21 -0
- data/lib/kuber_kit/image_compiler/image_dependency_resolver.rb +5 -53
- data/lib/kuber_kit/service_deployer/service_dependency_resolver.rb +14 -0
- data/lib/kuber_kit/service_deployer/service_list_resolver.rb +11 -6
- data/lib/kuber_kit/service_deployer/strategies/docker.rb +31 -12
- data/lib/kuber_kit/service_deployer/strategies/kubernetes.rb +9 -2
- data/lib/kuber_kit/shell/commands/kubectl_commands.rb +8 -0
- data/lib/kuber_kit/shell/local_shell.rb +15 -1
- data/lib/kuber_kit/template_reader/strategies/artifact_file.rb +3 -3
- data/lib/kuber_kit/tools/logger_factory.rb +14 -0
- data/lib/kuber_kit/version.rb +1 -1
- metadata +10 -2
    
        data/lib/kuber_kit/configs.rb
    CHANGED
    
    | @@ -4,8 +4,8 @@ class KuberKit::Configs | |
| 4 4 | 
             
              AVAILABLE_CONFIGS = [
         | 
| 5 5 | 
             
                :image_dockerfile_name, :image_build_context_dir, :image_tag, :docker_ignore_list, :image_compile_dir, 
         | 
| 6 6 | 
             
                :kuber_kit_dirname, :kuber_kit_min_version, :images_dirname, :services_dirname, :infra_dirname, :configurations_dirname,
         | 
| 7 | 
            -
                :artifact_clone_dir, :service_config_dir, :deployer_strategy, :compile_simultaneous_limit,
         | 
| 8 | 
            -
                :additional_images_paths, :deprecation_warnings_disabled, :log_file_path
         | 
| 7 | 
            +
                :artifact_clone_dir, :service_config_dir, :deployer_strategy, :compile_simultaneous_limit, :deploy_simultaneous_limit,
         | 
| 8 | 
            +
                :additional_images_paths, :deprecation_warnings_disabled, :log_file_path, :env_file_compile_dir
         | 
| 9 9 | 
             
              ]
         | 
| 10 10 | 
             
              DOCKER_IGNORE_LIST = [
         | 
| 11 11 | 
             
                'Dockerfile',
         | 
| @@ -34,10 +34,12 @@ class KuberKit::Configs | |
| 34 34 | 
             
              end
         | 
| 35 35 |  | 
| 36 36 | 
             
              def add_default_configs
         | 
| 37 | 
            +
                home_kuber_kit_path = File.expand_path(File.join("~", ".kuber_kit"))
         | 
| 38 | 
            +
                
         | 
| 37 39 | 
             
                set :image_dockerfile_name,   "Dockerfile"
         | 
| 38 40 | 
             
                set :image_build_context_dir, "build_context"
         | 
| 39 41 | 
             
                set :image_tag,               'latest'
         | 
| 40 | 
            -
                set :image_compile_dir,       " | 
| 42 | 
            +
                set :image_compile_dir,       File.join(home_kuber_kit_path, "image_builds")
         | 
| 41 43 | 
             
                set :docker_ignore_list,      DOCKER_IGNORE_LIST
         | 
| 42 44 | 
             
                set :kuber_kit_dirname,       "kuber_kit"
         | 
| 43 45 | 
             
                set :kuber_kit_min_version,   KuberKit::VERSION
         | 
| @@ -45,13 +47,15 @@ class KuberKit::Configs | |
| 45 47 | 
             
                set :services_dirname,        "services"
         | 
| 46 48 | 
             
                set :infra_dirname,           "infrastructure"
         | 
| 47 49 | 
             
                set :configurations_dirname,  "configurations"
         | 
| 48 | 
            -
                set :artifact_clone_dir,      " | 
| 49 | 
            -
                set :service_config_dir,      " | 
| 50 | 
            +
                set :artifact_clone_dir,      File.join(home_kuber_kit_path, "artifacts")
         | 
| 51 | 
            +
                set :service_config_dir,      File.join(home_kuber_kit_path, "services")
         | 
| 50 52 | 
             
                set :deployer_strategy,         :kubernetes
         | 
| 51 53 | 
             
                set :compile_simultaneous_limit, 5
         | 
| 54 | 
            +
                set :deploy_simultaneous_limit,  5
         | 
| 52 55 | 
             
                set :additional_images_paths, []
         | 
| 53 56 | 
             
                set :deprecation_warnings_disabled, false
         | 
| 54 | 
            -
                set :log_file_path,           " | 
| 57 | 
            +
                set :log_file_path,           File.join(home_kuber_kit_path, "deploy.log")
         | 
| 58 | 
            +
                set :env_file_compile_dir,    File.join(home_kuber_kit_path, "env_files")
         | 
| 55 59 | 
             
              end
         | 
| 56 60 |  | 
| 57 61 | 
             
              def items
         | 
    
        data/lib/kuber_kit/container.rb
    CHANGED
    
    | @@ -45,6 +45,10 @@ class KuberKit::Container | |
| 45 45 | 
             
                KuberKit::Actions::KubectlDescribe.new
         | 
| 46 46 | 
             
              end
         | 
| 47 47 |  | 
| 48 | 
            +
              register "actions.kubectl_get" do
         | 
| 49 | 
            +
                KuberKit::Actions::KubectlGet.new
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 48 52 | 
             
              register "actions.kubectl_logs" do
         | 
| 49 53 | 
             
                KuberKit::Actions::KubectlLogs.new
         | 
| 50 54 | 
             
              end
         | 
| @@ -225,10 +229,22 @@ class KuberKit::Container | |
| 225 229 | 
             
                KuberKit::EnvFileReader::Reader.new
         | 
| 226 230 | 
             
              end
         | 
| 227 231 |  | 
| 232 | 
            +
              register "env_file_reader.env_file_parser" do
         | 
| 233 | 
            +
                KuberKit::EnvFileReader::EnvFileParser.new
         | 
| 234 | 
            +
              end
         | 
| 235 | 
            +
             | 
| 236 | 
            +
              register "env_file_reader.env_file_tempfile_creator" do
         | 
| 237 | 
            +
                KuberKit::EnvFileReader::EnvFileTempfileCreator.new
         | 
| 238 | 
            +
              end
         | 
| 239 | 
            +
             | 
| 228 240 | 
             
              register "env_file_reader.strategies.artifact_file" do
         | 
| 229 241 | 
             
                KuberKit::EnvFileReader::Strategies::ArtifactFile.new
         | 
| 230 242 | 
             
              end
         | 
| 231 243 |  | 
| 244 | 
            +
              register "env_file_reader.strategies.env_group" do
         | 
| 245 | 
            +
                KuberKit::EnvFileReader::Strategies::EnvGroup.new
         | 
| 246 | 
            +
              end
         | 
| 247 | 
            +
             | 
| 232 248 | 
             
              register "template_reader.action_handler" do
         | 
| 233 249 | 
             
                KuberKit::TemplateReader::ActionHandler.new
         | 
| 234 250 | 
             
              end
         | 
| @@ -257,6 +273,10 @@ class KuberKit::Container | |
| 257 273 | 
             
                KuberKit::ServiceDeployer::ServiceListResolver.new
         | 
| 258 274 | 
             
              end
         | 
| 259 275 |  | 
| 276 | 
            +
              register "service_deployer.service_dependency_resolver" do
         | 
| 277 | 
            +
                KuberKit::ServiceDeployer::ServiceDependencyResolver.new
         | 
| 278 | 
            +
              end
         | 
| 279 | 
            +
             | 
| 260 280 | 
             
              register "service_deployer.strategies.kubernetes" do
         | 
| 261 281 | 
             
                KuberKit::ServiceDeployer::Strategies::Kubernetes.new
         | 
| 262 282 | 
             
              end
         | 
| @@ -3,6 +3,7 @@ class KuberKit::Core::Artifacts::ArtifactStore | |
| 3 3 | 
             
                store.add(artifact.name, artifact)
         | 
| 4 4 | 
             
              end
         | 
| 5 5 |  | 
| 6 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Artifacts::AbstractArtifact]
         | 
| 6 7 | 
             
              def get(artifact_name)
         | 
| 7 8 | 
             
                artifact = get_from_configuration(artifact_name) || 
         | 
| 8 9 | 
             
                           get_global(artifact_name)
         | 
| @@ -10,10 +11,12 @@ class KuberKit::Core::Artifacts::ArtifactStore | |
| 10 11 | 
             
                artifact
         | 
| 11 12 | 
             
              end
         | 
| 12 13 |  | 
| 14 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Artifacts::AbstractArtifact]
         | 
| 13 15 | 
             
              def get_global(artifact_name)
         | 
| 14 16 | 
             
                store.get(artifact_name)
         | 
| 15 17 | 
             
              end
         | 
| 16 18 |  | 
| 19 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Artifacts::AbstractArtifact]
         | 
| 17 20 | 
             
              def get_from_configuration(artifact_name)
         | 
| 18 21 | 
             
                artifacts = KuberKit.current_configuration.artifacts
         | 
| 19 22 | 
             
                artifacts[artifact_name]
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            class KuberKit::Core::Configuration
         | 
| 2 2 | 
             
              attr_reader :name, :artifacts, :registries, :env_files, :templates, :kubeconfig_path, 
         | 
| 3 | 
            -
                          :services_attributes, :enabled_services, :build_servers, :global_build_vars,
         | 
| 3 | 
            +
                          :services_attributes, :enabled_services, :disabled_services, :build_servers, :global_build_vars,
         | 
| 4 4 | 
             
                          :deployer_strategy, :deployer_namespace, :deployer_require_confirimation
         | 
| 5 5 |  | 
| 6 6 | 
             
              Contract KeywordArgs[
         | 
| @@ -12,6 +12,7 @@ class KuberKit::Core::Configuration | |
| 12 12 | 
             
                kubeconfig_path:      Maybe[String],
         | 
| 13 13 | 
             
                services_attributes:  HashOf[Symbol => Hash],
         | 
| 14 14 | 
             
                enabled_services:     ArrayOf[Symbol],
         | 
| 15 | 
            +
                disabled_services:    ArrayOf[Symbol],
         | 
| 15 16 | 
             
                build_servers:        ArrayOf[KuberKit::Core::BuildServers::AbstractBuildServer],
         | 
| 16 17 | 
             
                global_build_vars:    HashOf[Symbol => Any],
         | 
| 17 18 | 
             
                deployer_strategy:              Symbol,
         | 
| @@ -19,7 +20,7 @@ class KuberKit::Core::Configuration | |
| 19 20 | 
             
                deployer_require_confirimation: Bool,
         | 
| 20 21 | 
             
              ] => Any
         | 
| 21 22 | 
             
              def initialize(name:, artifacts:, registries:, env_files:, templates:, kubeconfig_path:, 
         | 
| 22 | 
            -
                             services_attributes:, enabled_services:, build_servers:, global_build_vars:,
         | 
| 23 | 
            +
                             services_attributes:, enabled_services:, disabled_services:, build_servers:, global_build_vars:,
         | 
| 23 24 | 
             
                             deployer_strategy:, deployer_namespace:, deployer_require_confirimation:)
         | 
| 24 25 | 
             
                @name                 = name
         | 
| 25 26 | 
             
                @artifacts            = artifacts
         | 
| @@ -30,6 +31,7 @@ class KuberKit::Core::Configuration | |
| 30 31 | 
             
                @build_servers        = build_servers
         | 
| 31 32 | 
             
                @services_attributes  = services_attributes
         | 
| 32 33 | 
             
                @enabled_services     = enabled_services
         | 
| 34 | 
            +
                @disabled_services    = disabled_services
         | 
| 33 35 | 
             
                @global_build_vars    = global_build_vars
         | 
| 34 36 | 
             
                @deployer_strategy              = deployer_strategy
         | 
| 35 37 | 
             
                @deployer_namespace             = deployer_namespace
         | 
| @@ -12,6 +12,7 @@ class KuberKit::Core::ConfigurationDefinition | |
| 12 12 | 
             
                @templates  = {}
         | 
| 13 13 | 
             
                @build_servers      = []
         | 
| 14 14 | 
             
                @enabled_services   = []
         | 
| 15 | 
            +
                @disabled_services  = []
         | 
| 15 16 | 
             
                @services_attributes = {}
         | 
| 16 17 | 
             
              end
         | 
| 17 18 |  | 
| @@ -24,6 +25,7 @@ class KuberKit::Core::ConfigurationDefinition | |
| 24 25 | 
             
                  templates:            @templates,
         | 
| 25 26 | 
             
                  kubeconfig_path:      @kubeconfig_path,
         | 
| 26 27 | 
             
                  enabled_services:     @enabled_services,
         | 
| 28 | 
            +
                  disabled_services:    @disabled_services,
         | 
| 27 29 | 
             
                  build_servers:        @build_servers,
         | 
| 28 30 | 
             
                  services_attributes:  @services_attributes,
         | 
| 29 31 | 
             
                  global_build_vars:    @global_build_vars,
         | 
| @@ -116,6 +118,11 @@ class KuberKit::Core::ConfigurationDefinition | |
| 116 118 | 
             
                raise KuberKit::Error, "#enabled_services method accepts only Array or Hash"
         | 
| 117 119 | 
             
              end
         | 
| 118 120 |  | 
| 121 | 
            +
              def disabled_services(services)
         | 
| 122 | 
            +
                @disabled_services += services.map(&:to_sym)
         | 
| 123 | 
            +
                return self
         | 
| 124 | 
            +
              end
         | 
| 125 | 
            +
             | 
| 119 126 | 
             
              def service_attributes(services)
         | 
| 120 127 | 
             
                @services_attributes = @services_attributes.merge(services)
         | 
| 121 128 | 
             
                self
         | 
| @@ -29,6 +29,7 @@ class KuberKit::Core::ConfigurationFactory | |
| 29 29 | 
             
                  build_servers:        build_servers,
         | 
| 30 30 | 
             
                  services_attributes:  configuration_attrs.services_attributes,
         | 
| 31 31 | 
             
                  enabled_services:     configuration_attrs.enabled_services,
         | 
| 32 | 
            +
                  disabled_services:    configuration_attrs.disabled_services,
         | 
| 32 33 | 
             
                  global_build_vars:    configuration_attrs.global_build_vars || {},
         | 
| 33 34 | 
             
                  deployer_strategy:              configuration_attrs.deployer_strategy || configs.deployer_strategy,
         | 
| 34 35 | 
             
                  deployer_namespace:             configuration_attrs.deployer_namespace,
         | 
| @@ -0,0 +1,75 @@ | |
| 1 | 
            +
            class KuberKit::Core::Dependencies::AbstractDependencyResolver
         | 
| 2 | 
            +
              CircularDependencyError = Class.new(KuberKit::Error)
         | 
| 3 | 
            +
              DependencyNotFoundError = Class.new(KuberKit::NotFoundError)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              # Iterate over list of dependencies for items (including the items themself).
         | 
| 6 | 
            +
              # Iteration will send the list to the callback block function
         | 
| 7 | 
            +
              Contract Or[Symbol, ArrayOf[Symbol]], Proc => Any
         | 
| 8 | 
            +
              def each_with_deps(item_names, &block)
         | 
| 9 | 
            +
                resolved_dependencies = []
         | 
| 10 | 
            +
                # Get first list of dependencies ready to resolve
         | 
| 11 | 
            +
                next_dependencies = get_next(item_names, limit: dependency_batch_size)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # Call the block for each list of dependencies ready to resolve, then calculate the next list
         | 
| 14 | 
            +
                while (next_dependencies - resolved_dependencies).any?
         | 
| 15 | 
            +
                  block.call(next_dependencies)
         | 
| 16 | 
            +
                  resolved_dependencies += next_dependencies
         | 
| 17 | 
            +
                  next_dependencies = get_next(item_names, resolved: resolved_dependencies, limit: dependency_batch_size)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                (item_names - resolved_dependencies).each_slice(dependency_batch_size) do |group|
         | 
| 21 | 
            +
                  block.call(group)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
              
         | 
| 25 | 
            +
              # Returns next list of dependencies ready to resolve.
         | 
| 26 | 
            +
              # Item is not ready to resolve if it has personal dependency.
         | 
| 27 | 
            +
              # E.g. if "A" depends on "B" and "C", "C" depends on "D", then only "B" and "D" will be returned. 
         | 
| 28 | 
            +
              Contract Or[Symbol, ArrayOf[Symbol]], KeywordArgs[
         | 
| 29 | 
            +
                resolved: Optional[ArrayOf[Symbol]],
         | 
| 30 | 
            +
                limit:    Optional[Maybe[Num]]
         | 
| 31 | 
            +
              ] => Any
         | 
| 32 | 
            +
              def get_next(item_names, resolved: [], limit: nil)
         | 
| 33 | 
            +
                deps = Array(item_names).map { |i| get_recursive_deps(i) }.flatten.uniq
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                # Find out which dependencies are ready to resolve, 
         | 
| 36 | 
            +
                # they should not have unresolved personal dependencies
         | 
| 37 | 
            +
                ready_to_resolve = deps.select do |dep_name|
         | 
| 38 | 
            +
                  unresolved_deps = get_deps(dep_name) - resolved
         | 
| 39 | 
            +
                  unresolved_deps.empty?
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
                unresolved_deps = ready_to_resolve - resolved
         | 
| 42 | 
            +
                unresolved_deps = unresolved_deps.take(limit) if limit
         | 
| 43 | 
            +
                unresolved_deps
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              # Get all dependencies for items (including the items themself), without any limitations
         | 
| 47 | 
            +
              Contract Or[Symbol, ArrayOf[Symbol]] => Any
         | 
| 48 | 
            +
              def get_all(item_names)
         | 
| 49 | 
            +
                deps = Array(item_names).map { |i| get_recursive_deps(i) }.flatten
         | 
| 50 | 
            +
                (deps + item_names).uniq
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              def get_recursive_deps(item_name, dependency_tree: [])
         | 
| 54 | 
            +
                deps = get_deps(item_name)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                if dependency_tree.include?(item_name)
         | 
| 57 | 
            +
                  raise CircularDependencyError, "Circular dependency found for #{item_name}. Dependency tree: #{dependency_tree.inspect}"
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                child_deps = []
         | 
| 61 | 
            +
                deps.each do |i| 
         | 
| 62 | 
            +
                  child_deps += get_recursive_deps(i, dependency_tree: dependency_tree + [item_name])
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                (deps + child_deps).uniq
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              def get_deps(item_name)
         | 
| 69 | 
            +
                raise "This method should be overriden"
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              def dependency_batch_size
         | 
| 73 | 
            +
                raise "This method should be overriden"
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
            end
         | 
| @@ -3,6 +3,7 @@ class KuberKit::Core::EnvFiles::EnvFileStore | |
| 3 3 | 
             
                store.add(env_file.name, env_file)
         | 
| 4 4 | 
             
              end
         | 
| 5 5 |  | 
| 6 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::EnvFiles::AbstractEnvFile]
         | 
| 6 7 | 
             
              def get(env_file_name)
         | 
| 7 8 | 
             
                env_file = get_from_configuration(env_file_name) || 
         | 
| 8 9 | 
             
                           get_global(env_file_name)
         | 
| @@ -10,10 +11,12 @@ class KuberKit::Core::EnvFiles::EnvFileStore | |
| 10 11 | 
             
                env_file
         | 
| 11 12 | 
             
              end
         | 
| 12 13 |  | 
| 14 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::EnvFiles::AbstractEnvFile]
         | 
| 13 15 | 
             
              def get_global(env_file_name)
         | 
| 14 16 | 
             
                store.get(env_file_name)
         | 
| 15 17 | 
             
              end
         | 
| 16 18 |  | 
| 19 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::EnvFiles::AbstractEnvFile]
         | 
| 17 20 | 
             
              def get_from_configuration(env_file_name)
         | 
| 18 21 | 
             
                env_files = KuberKit.current_configuration.env_files
         | 
| 19 22 | 
             
                env_files[env_file_name]
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            class KuberKit::Core::EnvFiles::EnvGroup < KuberKit::Core::EnvFiles::AbstractEnvFile
         | 
| 2 | 
            +
              attr_reader :env_files
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              def initialize(env_group_name, env_files:)
         | 
| 5 | 
            +
                super(env_group_name)
         | 
| 6 | 
            +
                @env_files = env_files
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def uniq_name
         | 
| 10 | 
            +
                "env-group-#{@name.to_s}"
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
    
        data/lib/kuber_kit/core/image.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            class KuberKit::Core::Image
         | 
| 2 | 
            -
              attr_reader :name, :dependencies, :registry, :dockerfile_path, :build_vars, :build_context_dir, :tag,  | 
| 2 | 
            +
              attr_reader :name, :dependencies, :registry, :dockerfile_path, :build_vars, :build_context_dir, :tag, 
         | 
| 3 | 
            +
                          :before_build_callback, :after_build_callback
         | 
| 3 4 |  | 
| 4 5 | 
             
              Contract KeywordArgs[
         | 
| 5 6 | 
             
                name:               Symbol,
         | 
| @@ -3,6 +3,7 @@ class KuberKit::Core::Registries::RegistryStore | |
| 3 3 | 
             
                store.add(registry.name, registry)
         | 
| 4 4 | 
             
              end
         | 
| 5 5 |  | 
| 6 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Registries::AbstractRegistry]
         | 
| 6 7 | 
             
              def get(registry_name)
         | 
| 7 8 | 
             
                registry = get_from_configuration(registry_name) || 
         | 
| 8 9 | 
             
                           get_global(registry_name)
         | 
| @@ -10,10 +11,12 @@ class KuberKit::Core::Registries::RegistryStore | |
| 10 11 | 
             
                registry
         | 
| 11 12 | 
             
              end
         | 
| 12 13 |  | 
| 14 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Registries::AbstractRegistry]
         | 
| 13 15 | 
             
              def get_global(registry_name)
         | 
| 14 16 | 
             
                store.get(registry_name)
         | 
| 15 17 | 
             
              end
         | 
| 16 18 |  | 
| 19 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Registries::AbstractRegistry]
         | 
| 17 20 | 
             
              def get_from_configuration(registry_name)
         | 
| 18 21 | 
             
                registries = KuberKit.current_configuration.registries
         | 
| 19 22 | 
             
                registries[registry_name]
         | 
| @@ -1,18 +1,20 @@ | |
| 1 1 | 
             
            class KuberKit::Core::Service
         | 
| 2 2 | 
             
              AttributeNotSet = Class.new(Indocker::Error)
         | 
| 3 3 |  | 
| 4 | 
            -
              attr_reader :name, :template_name, :tags, :images, :attributes, :deployer_strategy
         | 
| 4 | 
            +
              attr_reader :name, :dependencies, :template_name, :tags, :images, :attributes, :deployer_strategy
         | 
| 5 5 |  | 
| 6 6 | 
             
              Contract KeywordArgs[
         | 
| 7 7 | 
             
                name:               Symbol,
         | 
| 8 | 
            +
                dependencies:       ArrayOf[Symbol],
         | 
| 8 9 | 
             
                template_name:      Maybe[Symbol],
         | 
| 9 10 | 
             
                tags:               ArrayOf[Symbol],
         | 
| 10 11 | 
             
                images:             ArrayOf[Symbol],
         | 
| 11 12 | 
             
                attributes:         HashOf[Symbol => Any],
         | 
| 12 13 | 
             
                deployer_strategy:  Maybe[Symbol]
         | 
| 13 14 | 
             
              ] => Any
         | 
| 14 | 
            -
              def initialize(name:, template_name:, tags:, images:, attributes:, deployer_strategy:)
         | 
| 15 | 
            +
              def initialize(name:, dependencies:, template_name:, tags:, images:, attributes:, deployer_strategy:)
         | 
| 15 16 | 
             
                @name = name
         | 
| 17 | 
            +
                @dependencies = dependencies
         | 
| 16 18 | 
             
                @template_name = template_name
         | 
| 17 19 | 
             
                @tags = tags
         | 
| 18 20 | 
             
                @images = images
         | 
| @@ -1,22 +1,29 @@ | |
| 1 1 | 
             
            class KuberKit::Core::ServiceDefinition
         | 
| 2 | 
            -
              attr_reader :service_name, :template_name
         | 
| 2 | 
            +
              attr_reader :service_name, :template_name, :dependencies
         | 
| 3 3 |  | 
| 4 4 | 
             
              Contract Or[Symbol, String] => Any
         | 
| 5 5 | 
             
              def initialize(service_name)
         | 
| 6 6 | 
             
                @service_name = service_name.to_sym
         | 
| 7 | 
            +
                @dependencies = []
         | 
| 7 8 | 
             
              end
         | 
| 8 9 |  | 
| 9 10 | 
             
              def to_service_attrs
         | 
| 10 11 | 
             
                OpenStruct.new(
         | 
| 11 | 
            -
                  name: | 
| 12 | 
            -
                   | 
| 13 | 
            -
                   | 
| 14 | 
            -
                   | 
| 15 | 
            -
                   | 
| 12 | 
            +
                  name:               @service_name,
         | 
| 13 | 
            +
                  dependencies:       @dependencies,
         | 
| 14 | 
            +
                  template_name:      get_value(@template_name),
         | 
| 15 | 
            +
                  tags:               Array(get_value(@tags)).map(&:to_sym),
         | 
| 16 | 
            +
                  images:             Array(get_value(@images)).map(&:to_sym),
         | 
| 17 | 
            +
                  attributes:         get_value(@attributes),
         | 
| 16 18 | 
             
                  deployer_strategy:  get_value(@deployer_strategy),
         | 
| 17 19 | 
             
                )
         | 
| 18 20 | 
             
              end
         | 
| 19 21 |  | 
| 22 | 
            +
              def depends_on(*value, &block)
         | 
| 23 | 
            +
                @dependencies = Array(value).flatten
         | 
| 24 | 
            +
                self
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 20 27 | 
             
              def template(value = nil, &block)
         | 
| 21 28 | 
             
                @template_name = block_given? ? block : value
         | 
| 22 29 |  | 
| @@ -3,6 +3,7 @@ class KuberKit::Core::Templates::TemplateStore | |
| 3 3 | 
             
                store.add(template.name, template)
         | 
| 4 4 | 
             
              end
         | 
| 5 5 |  | 
| 6 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Templates::AbstractTemplate]
         | 
| 6 7 | 
             
              def get(template_name)
         | 
| 7 8 | 
             
                template = get_from_configuration(template_name) || 
         | 
| 8 9 | 
             
                           get_global(template_name)
         | 
| @@ -10,10 +11,12 @@ class KuberKit::Core::Templates::TemplateStore | |
| 10 11 | 
             
                template
         | 
| 11 12 | 
             
              end
         | 
| 12 13 |  | 
| 14 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Templates::AbstractTemplate]
         | 
| 13 15 | 
             
              def get_global(template_name)
         | 
| 14 16 | 
             
                store.get(template_name)
         | 
| 15 17 | 
             
              end
         | 
| 16 18 |  | 
| 19 | 
            +
              Contract Symbol => Maybe[KuberKit::Core::Templates::AbstractTemplate]
         | 
| 17 20 | 
             
              def get_from_configuration(template_name)
         | 
| 18 21 | 
             
                templates = KuberKit.current_configuration.templates
         | 
| 19 22 | 
             
                templates[template_name]
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            class KuberKit::EnvFileReader::EnvFileParser
         | 
| 2 | 
            +
              # Parser is based on:
         | 
| 3 | 
            +
              # https://github.com/bkeepers/dotenv/blob/master/lib/dotenv/parser.rb
         | 
| 4 | 
            +
              LINE = /
         | 
| 5 | 
            +
                (?:^|\A)              # beginning of line
         | 
| 6 | 
            +
                \s*                   # leading whitespace
         | 
| 7 | 
            +
                (?:export\s+)?        # optional export
         | 
| 8 | 
            +
                ([\w\.]+)             # key
         | 
| 9 | 
            +
                (?:\s*=\s*?|:\s+?)    # separator
         | 
| 10 | 
            +
                (                     # optional value begin
         | 
| 11 | 
            +
                  \s*'(?:\\'|[^'])*'  #   single quoted value
         | 
| 12 | 
            +
                  |                   #   or
         | 
| 13 | 
            +
                  \s*"(?:\\"|[^"])*"  #   double quoted value
         | 
| 14 | 
            +
                  |                   #   or
         | 
| 15 | 
            +
                  [^\#\r\n]+          #   unquoted value
         | 
| 16 | 
            +
                )?                    # value end
         | 
| 17 | 
            +
                \s*                   # trailing whitespace
         | 
| 18 | 
            +
                (?:\#.*)?             # optional comment
         | 
| 19 | 
            +
                (?:$|\z)              # end of line
         | 
| 20 | 
            +
              /x
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              Contract String => Hash
         | 
| 23 | 
            +
              def call(string)
         | 
| 24 | 
            +
                hash = {}
         | 
| 25 | 
            +
                string.gsub(/\r\n?/, "\n").scan(LINE).each do |key, value|
         | 
| 26 | 
            +
                  hash[key] = parse_value(value || "")
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
                hash
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              private
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              def parse_value(value)
         | 
| 34 | 
            +
                # Remove surrounding quotes
         | 
| 35 | 
            +
                value = value.strip.sub(/\A(['"])(.*)\1\z/m, '\2')
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                if Regexp.last_match(1) == '"'
         | 
| 38 | 
            +
                  value = unescape_characters(expand_newlines(value))
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                value
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def unescape_characters(value)
         | 
| 45 | 
            +
                value.gsub(/\\([^$])/, '\1')
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              def expand_newlines(value)
         | 
| 49 | 
            +
                value.gsub('\n', "\n").gsub('\r', "\r")
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         |