kuber_kit 0.3.7 → 0.4.0
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/.github/workflows/rspec.yml +35 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/TODO.md +2 -1
- data/example/infrastructure/artifacts.rb +1 -1
- data/example/services/docker_app.rb +12 -0
- data/lib/kuber_kit.rb +6 -4
- data/lib/kuber_kit/actions/configuration_loader.rb +12 -19
- data/lib/kuber_kit/actions/env_file_reader.rb +1 -0
- data/lib/kuber_kit/actions/image_compiler.rb +10 -6
- data/lib/kuber_kit/actions/service_deployer.rb +10 -7
- data/lib/kuber_kit/actions/template_reader.rb +1 -0
- data/lib/kuber_kit/artifacts_sync/artifacts_updater.rb +3 -2
- data/lib/kuber_kit/cli.rb +38 -25
- data/lib/kuber_kit/configs.rb +2 -1
- data/lib/kuber_kit/container.rb +6 -2
- data/lib/kuber_kit/core/configuration_store.rb +2 -2
- data/lib/kuber_kit/core/image_store.rb +2 -2
- data/lib/kuber_kit/core/service.rb +5 -5
- data/lib/kuber_kit/core/service_factory.rb +0 -6
- data/lib/kuber_kit/core/service_store.rb +2 -2
- data/lib/kuber_kit/image_compiler/compiler.rb +3 -1
- data/lib/kuber_kit/image_compiler/image_builder.rb +9 -1
- data/lib/kuber_kit/service_deployer/strategies/docker.rb +14 -8
- data/lib/kuber_kit/service_deployer/strategies/docker_compose.rb +5 -1
- data/lib/kuber_kit/service_deployer/strategies/kubernetes.rb +3 -1
- data/lib/kuber_kit/service_reader/reader.rb +6 -0
- data/lib/kuber_kit/shell/commands/docker_commands.rb +15 -10
- data/lib/kuber_kit/shell/commands/docker_compose_commands.rb +5 -6
- data/lib/kuber_kit/shell/local_shell.rb +6 -6
- data/lib/kuber_kit/shell/ssh_shell.rb +4 -4
- data/lib/kuber_kit/tools/logger_factory.rb +7 -3
- data/lib/kuber_kit/ui/api.rb +48 -0
- data/lib/kuber_kit/ui/debug.rb +31 -0
- data/lib/kuber_kit/ui/interactive.rb +15 -0
- data/lib/kuber_kit/ui/simple.rb +34 -5
- data/lib/kuber_kit/version.rb +1 -1
- metadata +6 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 88b8c2ffe3973bc966b245ceba37047030243d88119fd672db31efb002c67f86
         | 
| 4 | 
            +
              data.tar.gz: 5fafd218e63a669da3951b723f7167700704902006d4dd4fef13541e8ad1559b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a1c79c0056820500948580504c533be1ba2f9ceafe282802a0bbe44021a34196706c23eb97b05e6905efc26f565719fd9a1c668ec99afdbda642261ad6e8b6e1
         | 
| 7 | 
            +
              data.tar.gz: 3e4e33cc19ff7917ee5210dcdecae40ed22cb29d93f884bdb27adf3ec8565d3397ee8715ed8e89e75ae0316a0cf9192075d5afd66ba55caf3fe4f060064c88b9
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            # This workflow uses actions that are not certified by GitHub.
         | 
| 2 | 
            +
            # They are provided by a third-party and are governed by
         | 
| 3 | 
            +
            # separate terms of service, privacy policy, and support
         | 
| 4 | 
            +
            # documentation.
         | 
| 5 | 
            +
            # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
         | 
| 6 | 
            +
            # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            name: Rspec
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            on:
         | 
| 11 | 
            +
              push:
         | 
| 12 | 
            +
                branches: [ main ]
         | 
| 13 | 
            +
              pull_request:
         | 
| 14 | 
            +
                branches: [ main ]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            jobs:
         | 
| 17 | 
            +
              test:
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                runs-on: ubuntu-latest
         | 
| 20 | 
            +
                strategy:
         | 
| 21 | 
            +
                  matrix:
         | 
| 22 | 
            +
                    ruby-version: ['2.5', '2.7']
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                steps:
         | 
| 25 | 
            +
                - uses: actions/checkout@v2
         | 
| 26 | 
            +
                - name: Set up Ruby
         | 
| 27 | 
            +
                # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
         | 
| 28 | 
            +
                # change this to (see https://github.com/ruby/setup-ruby#versioning):
         | 
| 29 | 
            +
                # uses: ruby/setup-ruby@v1
         | 
| 30 | 
            +
                  uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
         | 
| 31 | 
            +
                  with:
         | 
| 32 | 
            +
                    ruby-version: ${{ matrix.ruby-version }}
         | 
| 33 | 
            +
                    bundler-cache: true # runs 'bundle install' and caches installed gems automatically
         | 
| 34 | 
            +
                - name: Run tests
         | 
| 35 | 
            +
                  run: bundle exec rspec spec/
         | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # KuberKit
         | 
| 2 2 |  | 
| 3 | 
            -
            [](https://github.com/ArtStation/kuber_kit/actions?query=workflow%3ARspec)
         | 
| 4 4 |  | 
| 5 5 | 
             
            Solution for building & deploying applications on Kubernetes, written in Ruby.
         | 
| 6 6 |  | 
    
        data/TODO.md
    CHANGED
    
    | @@ -5,4 +5,5 @@ | |
| 5 5 | 
             
            - allow deploying only services enabled for specific configuration
         | 
| 6 6 | 
             
            - find a way to always deploy some service, e.g. for migrations and env_files
         | 
| 7 7 | 
             
            - template should be able to set default attributes
         | 
| 8 | 
            -
            - template should be able to depend on image?
         | 
| 8 | 
            +
            - template should be able to depend on image?
         | 
| 9 | 
            +
            - cleanup image builds older than some date
         | 
    
        data/lib/kuber_kit.rb
    CHANGED
    
    | @@ -177,6 +177,8 @@ module KuberKit | |
| 177 177 | 
             
              module UI
         | 
| 178 178 | 
             
                autoload :Interactive, 'ui/interactive'
         | 
| 179 179 | 
             
                autoload :Simple, 'ui/simple'
         | 
| 180 | 
            +
                autoload :Debug, 'ui/debug'
         | 
| 181 | 
            +
                autoload :Api, 'ui/api'
         | 
| 180 182 | 
             
              end
         | 
| 181 183 |  | 
| 182 184 | 
             
              autoload :CLI, 'cli'
         | 
| @@ -205,12 +207,12 @@ module KuberKit | |
| 205 207 | 
             
                  @current_configuration = nil
         | 
| 206 208 | 
             
                end
         | 
| 207 209 |  | 
| 208 | 
            -
                def  | 
| 209 | 
            -
                  @ | 
| 210 | 
            +
                def set_ui_mode(value)
         | 
| 211 | 
            +
                  @ui_mode = value
         | 
| 210 212 | 
             
                end
         | 
| 211 213 |  | 
| 212 | 
            -
                def  | 
| 213 | 
            -
                   | 
| 214 | 
            +
                def ui_mode
         | 
| 215 | 
            +
                  @ui_mode
         | 
| 214 216 | 
             
                end
         | 
| 215 217 |  | 
| 216 218 | 
             
                def deprecation_warnings_disabled?
         | 
| @@ -1,13 +1,10 @@ | |
| 1 1 | 
             
            class KuberKit::Actions::ConfigurationLoader
         | 
| 2 | 
            -
              APP_CONFIG_FILENAME = "config.rb".freeze
         | 
| 3 | 
            -
             | 
| 4 2 | 
             
              include KuberKit::Import[
         | 
| 5 3 | 
             
                "core.registry_store",
         | 
| 6 4 | 
             
                "core.image_store",
         | 
| 7 5 | 
             
                "core.service_store",
         | 
| 8 6 | 
             
                "core.configuration_store",
         | 
| 9 7 | 
             
                "artifacts_sync.artifacts_updater",
         | 
| 10 | 
            -
                "tools.logger",
         | 
| 11 8 | 
             
                "shell.local_shell",
         | 
| 12 9 | 
             
                "ui",
         | 
| 13 10 | 
             
                "configs"
         | 
| @@ -16,29 +13,24 @@ class KuberKit::Actions::ConfigurationLoader | |
| 16 13 | 
             
              Contract Hash => Any
         | 
| 17 14 | 
             
              def call(options)
         | 
| 18 15 | 
             
                root_path     = options[:path] || File.join(Dir.pwd, configs.kuber_kit_dirname)
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                # require config file first, in case if other dirs are overriden in config
         | 
| 21 | 
            -
                config_file_path = File.join(root_path, APP_CONFIG_FILENAME)
         | 
| 22 | 
            -
                if File.exists?(config_file_path)
         | 
| 23 | 
            -
                  require config_file_path
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
             | 
| 26 16 | 
             
                images_path   = options[:images_path] || File.join(root_path, configs.images_dirname)
         | 
| 27 17 | 
             
                services_path = options[:services_path] || File.join(root_path, configs.services_dirname)
         | 
| 28 18 | 
             
                infra_path    = options[:infra_path]  || File.join(root_path, configs.infra_dirname)
         | 
| 29 19 | 
             
                configurations_path  = options[:configurations_path]  || File.join(root_path, configs.configurations_dirname)
         | 
| 30 20 | 
             
                configuration_name   = ENV["KUBER_KIT_CONFIGURATION"] || options[:configuration]
         | 
| 31 21 |  | 
| 32 | 
            -
                 | 
| 33 | 
            -
                 | 
| 34 | 
            -
                 | 
| 35 | 
            -
                 | 
| 36 | 
            -
                 | 
| 37 | 
            -
                 | 
| 38 | 
            -
                 | 
| 22 | 
            +
                ui.print_debug "ConfigurationLoader", "Launching kuber_kit with:"
         | 
| 23 | 
            +
                ui.print_debug "ConfigurationLoader", "  Root path: #{root_path.to_s.yellow}"
         | 
| 24 | 
            +
                ui.print_debug "ConfigurationLoader", "  Images path: #{images_path.to_s.yellow}"
         | 
| 25 | 
            +
                ui.print_debug "ConfigurationLoader", "  Services path: #{services_path.to_s.yellow}"
         | 
| 26 | 
            +
                ui.print_debug "ConfigurationLoader", "  Infrastructure path: #{infra_path.to_s.yellow}"
         | 
| 27 | 
            +
                ui.print_debug "ConfigurationLoader", "  Configurations path: #{configurations_path.to_s.yellow}"
         | 
| 28 | 
            +
                ui.print_debug "ConfigurationLoader", "  Configuration name: #{configuration_name.to_s.yellow}"
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                ui.print_info("Logs", "See logs at: #{configs.log_file_path}")
         | 
| 39 31 |  | 
| 40 32 | 
             
                unless File.exists?(root_path)
         | 
| 41 | 
            -
                  ui.print_warning " | 
| 33 | 
            +
                  ui.print_warning "ConfigurationLoader", "KuberKit root path #{root_path} doesn't exist. You may want to pass it --path parameter."
         | 
| 42 34 | 
             
                end
         | 
| 43 35 |  | 
| 44 36 | 
             
                if Gem::Version.new(KuberKit::VERSION) < Gem::Version.new(configs.kuber_kit_min_version)
         | 
| @@ -72,6 +64,7 @@ class KuberKit::Actions::ConfigurationLoader | |
| 72 64 | 
             
                true
         | 
| 73 65 | 
             
              rescue KuberKit::Error => e
         | 
| 74 66 | 
             
                ui.print_error("Error", e.message)
         | 
| 67 | 
            +
                
         | 
| 75 68 | 
             
                false
         | 
| 76 69 | 
             
              end
         | 
| 77 70 |  | 
| @@ -104,6 +97,6 @@ class KuberKit::Actions::ConfigurationLoader | |
| 104 97 | 
             
                  require(path)
         | 
| 105 98 | 
             
                end
         | 
| 106 99 | 
             
              rescue KuberKit::Shell::AbstractShell::DirNotFoundError
         | 
| 107 | 
            -
                 | 
| 100 | 
            +
                ui.print_warning("ConfigurationLoader", "Directory with infrastructure not found: #{infra_path}")
         | 
| 108 101 | 
             
              end
         | 
| 109 102 | 
             
            end
         | 
| @@ -3,7 +3,6 @@ class KuberKit::Actions::ImageCompiler | |
| 3 3 | 
             
                "image_compiler.image_dependency_resolver",
         | 
| 4 4 | 
             
                "image_compiler.build_server_pool_factory",
         | 
| 5 5 | 
             
                "shell.local_shell",
         | 
| 6 | 
            -
                "tools.logger",
         | 
| 7 6 | 
             
                "ui",
         | 
| 8 7 | 
             
                image_compiler: "image_compiler.action_handler",
         | 
| 9 8 | 
             
              ]
         | 
| @@ -13,14 +12,17 @@ class KuberKit::Actions::ImageCompiler | |
| 13 12 | 
             
                build_id = generate_build_id
         | 
| 14 13 | 
             
                build_server_pool = build_server_pool_factory.create()
         | 
| 15 14 |  | 
| 15 | 
            +
                compiled_images = []
         | 
| 16 | 
            +
                compilation_result = {}
         | 
| 16 17 | 
             
                image_dependency_resolver.each_with_deps(image_names) do |dep_image_names|
         | 
| 17 18 | 
             
                  result = compile_simultaneously(dep_image_names, build_id, build_server_pool)
         | 
| 18 | 
            -
                   | 
| 19 | 
            +
                  compiled_images += dep_image_names
         | 
| 20 | 
            +
                  compilation_result = compilation_result.merge(result)
         | 
| 19 21 | 
             
                end
         | 
| 20 22 |  | 
| 21 23 | 
             
                build_server_pool.disconnect_all
         | 
| 22 24 |  | 
| 23 | 
            -
                 | 
| 25 | 
            +
                { images: compiled_images, compilation: compilation_result }
         | 
| 24 26 | 
             
              rescue KuberKit::Error => e
         | 
| 25 27 | 
             
                ui.print_error("Error", e.message)
         | 
| 26 28 |  | 
| @@ -30,20 +32,22 @@ class KuberKit::Actions::ImageCompiler | |
| 30 32 | 
             
              private
         | 
| 31 33 | 
             
                def compile_simultaneously(image_names, build_id, build_server_pool)
         | 
| 32 34 | 
             
                  task_group = ui.create_task_group
         | 
| 35 | 
            +
                  compiler_result = {}
         | 
| 33 36 | 
             
                  image_names.map do |image_name|
         | 
| 34 37 |  | 
| 35 | 
            -
                     | 
| 38 | 
            +
                    ui.print_debug("ImageCompiler", "Started compiling: #{image_name.to_s.green}")
         | 
| 36 39 | 
             
                    task_group.add("Compiling #{image_name.to_s.yellow}") do |task|
         | 
| 37 40 | 
             
                      shell = build_server_pool.get_shell
         | 
| 38 41 |  | 
| 39 | 
            -
                      image_compiler.call(shell, image_name, build_id)
         | 
| 42 | 
            +
                      compiler_result[image_name] = image_compiler.call(shell, image_name, build_id)
         | 
| 40 43 |  | 
| 41 44 | 
             
                      task.update_title("Compiled #{image_name.to_s.green}")
         | 
| 42 | 
            -
                       | 
| 45 | 
            +
                      ui.print_debug("ImageCompiler", "Finished compiling: #{image_name}")
         | 
| 43 46 | 
             
                    end
         | 
| 44 47 |  | 
| 45 48 | 
             
                  end
         | 
| 46 49 | 
             
                  task_group.wait
         | 
| 50 | 
            +
                  compiler_result
         | 
| 47 51 | 
             
                end
         | 
| 48 52 |  | 
| 49 53 | 
             
                def generate_build_id
         | 
| @@ -4,7 +4,6 @@ class KuberKit::Actions::ServiceDeployer | |
| 4 4 | 
             
                "service_deployer.service_list_resolver",
         | 
| 5 5 | 
             
                "core.service_store",
         | 
| 6 6 | 
             
                "shell.local_shell",
         | 
| 7 | 
            -
                "tools.logger",
         | 
| 8 7 | 
             
                "ui",
         | 
| 9 8 | 
             
                service_deployer: "service_deployer.action_handler",
         | 
| 10 9 | 
             
              ]
         | 
| @@ -25,7 +24,7 @@ class KuberKit::Actions::ServiceDeployer | |
| 25 24 | 
             
                )
         | 
| 26 25 |  | 
| 27 26 | 
             
                unless service_names.any?
         | 
| 28 | 
            -
                  ui.print_warning " | 
| 27 | 
            +
                  ui.print_warning "ServiceDeployer", "No service found with given options, nothing will be deployed."
         | 
| 29 28 | 
             
                end
         | 
| 30 29 |  | 
| 31 30 | 
             
                services = service_names.map do |service_name|
         | 
| @@ -35,9 +34,9 @@ class KuberKit::Actions::ServiceDeployer | |
| 35 34 | 
             
                images_names = services.map(&:images).flatten.uniq
         | 
| 36 35 |  | 
| 37 36 | 
             
                compile_images(images_names) unless skip_compile
         | 
| 38 | 
            -
                deploy_services(service_names)
         | 
| 37 | 
            +
                deployment_result = deploy_services(service_names)
         | 
| 39 38 |  | 
| 40 | 
            -
                 | 
| 39 | 
            +
                { services: service_names, deployment: deployment_result }
         | 
| 41 40 | 
             
              rescue KuberKit::Error => e
         | 
| 42 41 | 
             
                ui.print_error("Error", e.message)
         | 
| 43 42 |  | 
| @@ -47,18 +46,22 @@ class KuberKit::Actions::ServiceDeployer | |
| 47 46 | 
             
              def deploy_services(service_names)
         | 
| 48 47 | 
             
                task_group = ui.create_task_group
         | 
| 49 48 |  | 
| 49 | 
            +
                deployer_result = {}
         | 
| 50 | 
            +
             | 
| 50 51 | 
             
                service_names.each do |service_name|
         | 
| 51 52 |  | 
| 52 | 
            -
                   | 
| 53 | 
            +
                  ui.print_debug("ServiceDeployer", "Started deploying: #{service_name.to_s.green}")
         | 
| 53 54 | 
             
                  task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
         | 
| 54 | 
            -
                    service_deployer.call(local_shell, service_name.to_sym)
         | 
| 55 | 
            +
                    deployer_result[service_name] = service_deployer.call(local_shell, service_name.to_sym)
         | 
| 55 56 |  | 
| 56 57 | 
             
                    task.update_title("Deployed #{service_name.to_s.green}")
         | 
| 57 | 
            -
                     | 
| 58 | 
            +
                    ui.print_debug("ServiceDeployer", "Finished deploying: #{service_name.to_s.green}")
         | 
| 58 59 | 
             
                  end
         | 
| 59 60 | 
             
                end
         | 
| 60 61 |  | 
| 61 62 | 
             
                task_group.wait
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                deployer_result
         | 
| 62 65 | 
             
              end
         | 
| 63 66 |  | 
| 64 67 | 
             
              def compile_images(images_names)
         | 
| @@ -4,7 +4,8 @@ class KuberKit::ArtifactsSync::ArtifactsUpdater | |
| 4 4 | 
             
              include KuberKit::Import[
         | 
| 5 5 | 
             
                "artifacts_sync.git_artifact_resolver",
         | 
| 6 6 | 
             
                "artifacts_sync.null_artifact_resolver",
         | 
| 7 | 
            -
             | 
| 7 | 
            +
             | 
| 8 | 
            +
                "ui"
         | 
| 8 9 | 
             
              ]
         | 
| 9 10 |  | 
| 10 11 | 
             
              def use_resolver(artifact_resolver, artifact_class:)
         | 
| @@ -23,7 +24,7 @@ class KuberKit::ArtifactsSync::ArtifactsUpdater | |
| 23 24 | 
             
                artifacts.each do |artifact|
         | 
| 24 25 | 
             
                  resolver = @@resolvers[artifact.class]
         | 
| 25 26 |  | 
| 26 | 
            -
                   | 
| 27 | 
            +
                  ui.print_debug "ArtifactUpdater", "Updating artifact #{artifact.name.to_s.green}"
         | 
| 27 28 |  | 
| 28 29 | 
             
                  raise ResolverNotFoundError, "Can't find resolver for artifact #{artifact}" if resolver.nil?
         | 
| 29 30 |  | 
    
        data/lib/kuber_kit/cli.rb
    CHANGED
    
    | @@ -1,16 +1,19 @@ | |
| 1 1 | 
             
            require 'thor'
         | 
| 2 2 |  | 
| 3 3 | 
             
            class KuberKit::CLI < Thor
         | 
| 4 | 
            +
              APP_CONFIG_FILENAME = "config.rb".freeze
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
              class_option :path, :type => :string
         | 
| 5 7 | 
             
              class_option :images_path, :type => :string
         | 
| 6 8 | 
             
              class_option :infra_path, :type => :string
         | 
| 7 9 | 
             
              class_option :configurations_path, :type => :string
         | 
| 10 | 
            +
              class_option :ui, :type => :string, :desc => "UI mode (interactive|debug|simple)"
         | 
| 8 11 | 
             
              class_option :debug, :type => :boolean, aliases: ["-d"]
         | 
| 9 12 | 
             
              class_option :configuration, :type => :string, aliases: ["-C"]
         | 
| 10 13 |  | 
| 11 14 | 
             
              desc "compile IMAGE_NAMES", "Compile image with IMAGE_NAMES (comma-separated)"
         | 
| 12 15 | 
             
              def compile(image_names_str)
         | 
| 13 | 
            -
                 | 
| 16 | 
            +
                setup(options)
         | 
| 14 17 |  | 
| 15 18 | 
             
                image_names = image_names_str.split(",").map(&:strip).map(&:to_sym)
         | 
| 16 19 |  | 
| @@ -18,15 +21,10 @@ class KuberKit::CLI < Thor | |
| 18 21 | 
             
                  result = KuberKit::Container['actions.image_compiler'].call(image_names, options)
         | 
| 19 22 | 
             
                end
         | 
| 20 23 |  | 
| 21 | 
            -
                logger = KuberKit::Container['tools.logger']
         | 
| 22 24 | 
             
                if result
         | 
| 23 | 
            -
                   | 
| 24 | 
            -
                  logger.info("Image compilation finished!")
         | 
| 25 | 
            -
                  logger.info("---------------------------")
         | 
| 25 | 
            +
                  print_result("Image compilation finished!", result: result)
         | 
| 26 26 | 
             
                else
         | 
| 27 | 
            -
                   | 
| 28 | 
            -
                  logger.info("Image compilation failed!".red)
         | 
| 29 | 
            -
                  logger.info("-------------------------".red)
         | 
| 27 | 
            +
                  exit 1
         | 
| 30 28 | 
             
                end
         | 
| 31 29 | 
             
              end
         | 
| 32 30 |  | 
| @@ -35,7 +33,7 @@ class KuberKit::CLI < Thor | |
| 35 33 | 
             
              method_option :tags,          :type => :array,    aliases: ["-t"]
         | 
| 36 34 | 
             
              method_option :skip_compile,  :type => :boolean,  aliases: ["-B"]
         | 
| 37 35 | 
             
              def deploy
         | 
| 38 | 
            -
                 | 
| 36 | 
            +
                setup(options)
         | 
| 39 37 |  | 
| 40 38 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 41 39 | 
             
                  result = KuberKit::Container['actions.service_deployer'].call(
         | 
| @@ -45,21 +43,16 @@ class KuberKit::CLI < Thor | |
| 45 43 | 
             
                  )
         | 
| 46 44 | 
             
                end
         | 
| 47 45 |  | 
| 48 | 
            -
                logger = KuberKit::Container['tools.logger']
         | 
| 49 46 | 
             
                if result
         | 
| 50 | 
            -
                   | 
| 51 | 
            -
                  logger.info("Service deployment finished!")
         | 
| 52 | 
            -
                  logger.info("---------------------------")
         | 
| 47 | 
            +
                  print_result("Service deployment finished!", result: result)
         | 
| 53 48 | 
             
                else
         | 
| 54 | 
            -
                   | 
| 55 | 
            -
                  logger.info("Service deployment failed!".red)
         | 
| 56 | 
            -
                  logger.info("-------------------------".red)
         | 
| 49 | 
            +
                  exit 1
         | 
| 57 50 | 
             
                end
         | 
| 58 51 | 
             
              end
         | 
| 59 52 |  | 
| 60 53 | 
             
              desc "env ENV_FILE_NAME", "Return content of Env File ENV_FILE_NAME"
         | 
| 61 54 | 
             
              def env(env_file_name)
         | 
| 62 | 
            -
                 | 
| 55 | 
            +
                setup(options)
         | 
| 63 56 |  | 
| 64 57 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 65 58 | 
             
                  KuberKit::Container['actions.env_file_reader'].call(env_file_name.to_sym, options)
         | 
| @@ -68,7 +61,7 @@ class KuberKit::CLI < Thor | |
| 68 61 |  | 
| 69 62 | 
             
              desc "template TEMPLATE_NAME", "Return content of Template TEMPLATE_NAME"
         | 
| 70 63 | 
             
              def template(template_name)
         | 
| 71 | 
            -
                 | 
| 64 | 
            +
                setup(options)
         | 
| 72 65 |  | 
| 73 66 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 74 67 | 
             
                  KuberKit::Container['actions.template_reader'].call(template_name.to_sym, options)
         | 
| @@ -77,7 +70,7 @@ class KuberKit::CLI < Thor | |
| 77 70 |  | 
| 78 71 | 
             
              desc "service SERVICE_NAME", "Return content of Service SERVICE_NAME"
         | 
| 79 72 | 
             
              def service(service_name)
         | 
| 80 | 
            -
                 | 
| 73 | 
            +
                setup(options)
         | 
| 81 74 |  | 
| 82 75 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 83 76 | 
             
                  KuberKit::Container['actions.service_reader'].call(service_name.to_sym, options)
         | 
| @@ -86,7 +79,7 @@ class KuberKit::CLI < Thor | |
| 86 79 |  | 
| 87 80 | 
             
              desc "apply FILE_PATH", "Apply FILE_PATH with kubectl"
         | 
| 88 81 | 
             
              def apply(file_path)
         | 
| 89 | 
            -
                 | 
| 82 | 
            +
                setup(options)
         | 
| 90 83 |  | 
| 91 84 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 92 85 | 
             
                  KuberKit::Container['actions.kubectl_applier'].call(File.expand_path(file_path), options)
         | 
| @@ -95,26 +88,26 @@ class KuberKit::CLI < Thor | |
| 95 88 |  | 
| 96 89 | 
             
              desc "attach POD_NAME", "Attach to POD_NAME using kubectl"
         | 
| 97 90 | 
             
              def attach(pod_name = nil)
         | 
| 98 | 
            -
                 | 
| 91 | 
            +
                setup(options)
         | 
| 99 92 |  | 
| 100 93 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 101 94 | 
             
                  KuberKit::Container['actions.kubectl_attacher'].call(pod_name, options)
         | 
| 102 95 | 
             
                end
         | 
| 103 96 | 
             
              end
         | 
| 104 97 |  | 
| 105 | 
            -
              desc " | 
| 98 | 
            +
              desc "console POD_NAME", "Attach to POD_NAME using kubectl & launch bin/console"
         | 
| 106 99 | 
             
              def console(pod_name = nil)
         | 
| 107 | 
            -
                 | 
| 100 | 
            +
                setup(options)
         | 
| 108 101 |  | 
| 109 102 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 110 103 | 
             
                  KuberKit::Container['actions.kubectl_console'].call(pod_name, options)
         | 
| 111 104 | 
             
                end
         | 
| 112 105 | 
             
              end
         | 
| 113 106 |  | 
| 114 | 
            -
              desc " | 
| 107 | 
            +
              desc "logs POD_NAME", "Show logs for POD_NAME using kubectl"
         | 
| 115 108 | 
             
              method_option :follow,  :type => :boolean,  aliases: ["-f"]
         | 
| 116 109 | 
             
              def logs(pod_name = nil)
         | 
| 117 | 
            -
                 | 
| 110 | 
            +
                setup(options)
         | 
| 118 111 |  | 
| 119 112 | 
             
                if KuberKit::Container['actions.configuration_loader'].call(options)
         | 
| 120 113 | 
             
                  KuberKit::Container['actions.kubectl_logs'].call(pod_name, options)
         | 
| @@ -129,4 +122,24 @@ class KuberKit::CLI < Thor | |
| 129 122 | 
             
              def self.exit_on_failure?
         | 
| 130 123 | 
             
                true
         | 
| 131 124 | 
             
              end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
              private
         | 
| 127 | 
            +
                def setup(options)
         | 
| 128 | 
            +
                  if options[:debug]
         | 
| 129 | 
            +
                    KuberKit.set_ui_mode(:debug)
         | 
| 130 | 
            +
                  elsif options[:ui]
         | 
| 131 | 
            +
                    KuberKit.set_ui_mode(options[:ui].to_sym)
         | 
| 132 | 
            +
                  end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                  # We should load config before loading any bean, to make sure that bean won't be built with default config
         | 
| 135 | 
            +
                  root_path     = options[:path] || File.join(Dir.pwd, KuberKit::Container['configs'].kuber_kit_dirname)
         | 
| 136 | 
            +
                  config_file_path = File.join(root_path, APP_CONFIG_FILENAME)
         | 
| 137 | 
            +
                  if File.exists?(config_file_path)
         | 
| 138 | 
            +
                    require config_file_path
         | 
| 139 | 
            +
                  end
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                def print_result(message, data = {})
         | 
| 143 | 
            +
                  KuberKit::Container['ui'].print_result(message, data)
         | 
| 144 | 
            +
                end
         | 
| 132 145 | 
             
            end
         | 
    
        data/lib/kuber_kit/configs.rb
    CHANGED
    
    | @@ -5,7 +5,7 @@ class KuberKit::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 7 | 
             
                :artifact_clone_dir, :service_config_dir, :deployer_strategy, :compile_simultaneous_limit,
         | 
| 8 | 
            -
                :additional_images_paths, :deprecation_warnings_disabled
         | 
| 8 | 
            +
                :additional_images_paths, :deprecation_warnings_disabled, :log_file_path
         | 
| 9 9 | 
             
              ]
         | 
| 10 10 | 
             
              DOCKER_IGNORE_LIST = [
         | 
| 11 11 | 
             
                'Dockerfile',
         | 
| @@ -51,6 +51,7 @@ class KuberKit::Configs | |
| 51 51 | 
             
                set :compile_simultaneous_limit, 5
         | 
| 52 52 | 
             
                set :additional_images_paths, []
         | 
| 53 53 | 
             
                set :deprecation_warnings_disabled, false
         | 
| 54 | 
            +
                set :log_file_path,           "/tmp/kuber_kit.log"
         | 
| 54 55 | 
             
              end
         | 
| 55 56 |  | 
| 56 57 | 
             
              def items
         | 
    
        data/lib/kuber_kit/container.rb
    CHANGED
    
    | @@ -114,7 +114,7 @@ class KuberKit::Container | |
| 114 114 | 
             
              end
         | 
| 115 115 |  | 
| 116 116 | 
             
              register "tools.logger" do
         | 
| 117 | 
            -
                KuberKit::Container["tools.logger_factory"].create( | 
| 117 | 
            +
                KuberKit::Container["tools.logger_factory"].create()
         | 
| 118 118 | 
             
              end
         | 
| 119 119 |  | 
| 120 120 | 
             
              register "shell.bash_commands" do
         | 
| @@ -258,8 +258,12 @@ class KuberKit::Container | |
| 258 258 | 
             
              end
         | 
| 259 259 |  | 
| 260 260 | 
             
              register "ui" do
         | 
| 261 | 
            -
                if KuberKit. | 
| 261 | 
            +
                if KuberKit.ui_mode == :debug
         | 
| 262 | 
            +
                  KuberKit::UI::Debug.new
         | 
| 263 | 
            +
                elsif KuberKit.ui_mode == :simple
         | 
| 262 264 | 
             
                  KuberKit::UI::Simple.new
         | 
| 265 | 
            +
                elsif KuberKit.ui_mode == :api
         | 
| 266 | 
            +
                  KuberKit::UI::Api.new
         | 
| 263 267 | 
             
                else
         | 
| 264 268 | 
             
                  KuberKit::UI::Interactive.new
         | 
| 265 269 | 
             
                end
         | 
| @@ -3,7 +3,7 @@ class KuberKit::Core::ConfigurationStore | |
| 3 3 | 
             
                "core.configuration_factory",
         | 
| 4 4 | 
             
                "core.configuration_definition_factory",
         | 
| 5 5 | 
             
                "shell.local_shell",
         | 
| 6 | 
            -
                " | 
| 6 | 
            +
                "ui"
         | 
| 7 7 | 
             
              ]
         | 
| 8 8 |  | 
| 9 9 | 
             
              def define(configuration_name)
         | 
| @@ -33,7 +33,7 @@ class KuberKit::Core::ConfigurationStore | |
| 33 33 | 
             
                  load_definition(path)
         | 
| 34 34 | 
             
                end
         | 
| 35 35 | 
             
              rescue KuberKit::Shell::AbstractShell::DirNotFoundError
         | 
| 36 | 
            -
                 | 
| 36 | 
            +
                ui.print_warning("ConfigurationStore", "Directory with configurations not found: #{dir_path}")
         | 
| 37 37 | 
             
                []
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| @@ -3,7 +3,7 @@ class KuberKit::Core::ImageStore | |
| 3 3 | 
             
                "core.image_factory",
         | 
| 4 4 | 
             
                "core.image_definition_factory",
         | 
| 5 5 | 
             
                "shell.local_shell",
         | 
| 6 | 
            -
                " | 
| 6 | 
            +
                "ui"
         | 
| 7 7 | 
             
              ]
         | 
| 8 8 |  | 
| 9 9 | 
             
              def define(image_name, image_dir = nil)
         | 
| @@ -33,7 +33,7 @@ class KuberKit::Core::ImageStore | |
| 33 33 | 
             
                  load_definition(path)
         | 
| 34 34 | 
             
                end
         | 
| 35 35 | 
             
              rescue KuberKit::Shell::AbstractShell::DirNotFoundError
         | 
| 36 | 
            -
                 | 
| 36 | 
            +
                ui.print_warning("ImageStore", "Directory with images not found: #{dir_path}")
         | 
| 37 37 | 
             
                []
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| @@ -4,11 +4,11 @@ class KuberKit::Core::Service | |
| 4 4 | 
             
              attr_reader :name, :template_name, :tags, :images, :attributes, :deployer_strategy
         | 
| 5 5 |  | 
| 6 6 | 
             
              Contract KeywordArgs[
         | 
| 7 | 
            -
                name: | 
| 8 | 
            -
                template_name: | 
| 9 | 
            -
                tags: | 
| 10 | 
            -
                images: | 
| 11 | 
            -
                attributes: | 
| 7 | 
            +
                name:               Symbol,
         | 
| 8 | 
            +
                template_name:      Maybe[Symbol],
         | 
| 9 | 
            +
                tags:               ArrayOf[Symbol],
         | 
| 10 | 
            +
                images:             ArrayOf[Symbol],
         | 
| 11 | 
            +
                attributes:         HashOf[Symbol => Any],
         | 
| 12 12 | 
             
                deployer_strategy:  Maybe[Symbol]
         | 
| 13 13 | 
             
              ] => Any
         | 
| 14 14 | 
             
              def initialize(name:, template_name:, tags:, images:, attributes:, deployer_strategy:)
         | 
| @@ -1,13 +1,7 @@ | |
| 1 1 | 
             
            class KuberKit::Core::ServiceFactory
         | 
| 2 | 
            -
              AttributeNotSetError = Class.new(KuberKit::Error)
         | 
| 3 | 
            -
             | 
| 4 2 | 
             
              def create(definition)
         | 
| 5 3 | 
             
                service_attrs = definition.to_service_attrs
         | 
| 6 4 |  | 
| 7 | 
            -
                if service_attrs.template_name.nil?
         | 
| 8 | 
            -
                  raise AttributeNotSetError, "Please set template for service using #template method"
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 5 | 
             
                configuration_attributes = KuberKit.current_configuration.service_attributes(service_attrs.name)
         | 
| 12 6 | 
             
                attributes = (service_attrs.attributes || {}).merge(configuration_attributes)
         | 
| 13 7 |  | 
| @@ -3,7 +3,7 @@ class KuberKit::Core::ServiceStore | |
| 3 3 | 
             
                "core.service_factory",
         | 
| 4 4 | 
             
                "core.service_definition_factory",
         | 
| 5 5 | 
             
                "shell.local_shell",
         | 
| 6 | 
            -
                " | 
| 6 | 
            +
                "ui",
         | 
| 7 7 | 
             
              ]
         | 
| 8 8 |  | 
| 9 9 | 
             
              def define(service_name)
         | 
| @@ -33,7 +33,7 @@ class KuberKit::Core::ServiceStore | |
| 33 33 | 
             
                  load_definition(path)
         | 
| 34 34 | 
             
                end
         | 
| 35 35 | 
             
              rescue KuberKit::Shell::AbstractShell::DirNotFoundError
         | 
| 36 | 
            -
                 | 
| 36 | 
            +
                ui.print_warning("ServiceStore", "Directory with services not found: #{dir_path}")
         | 
| 37 37 | 
             
                []
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| @@ -12,7 +12,9 @@ class KuberKit::ImageCompiler::Compiler | |
| 12 12 | 
             
                context_helper = context_helper_factory.build_image_context(shell, image)
         | 
| 13 13 | 
             
                image_build_dir_creator.create(shell, image, image_build_dir, context_helper: context_helper)
         | 
| 14 14 |  | 
| 15 | 
            -
                image_builder.build(shell, image, image_build_dir, context_helper: context_helper)
         | 
| 15 | 
            +
                result = image_builder.build(shell, image, image_build_dir, context_helper: context_helper)
         | 
| 16 16 | 
             
                image_build_dir_creator.cleanup(shell, image_build_dir)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                result
         | 
| 17 19 | 
             
              end
         | 
| 18 20 | 
             
            end
         | 
| @@ -10,7 +10,13 @@ class KuberKit::ImageCompiler::ImageBuilder | |
| 10 10 | 
             
              def build(shell, image, build_dir, context_helper: nil)
         | 
| 11 11 | 
             
                image.before_build_callback.call(context_helper, build_dir) if image.before_build_callback
         | 
| 12 12 |  | 
| 13 | 
            -
                 | 
| 13 | 
            +
                build_options = ["-t=#{image.registry_url}"]
         | 
| 14 | 
            +
                # use quite option for api mode ui, so it will only return built image id
         | 
| 15 | 
            +
                if KuberKit.ui_mode == :api
         | 
| 16 | 
            +
                  build_options << "-q"
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                build_result = docker_commands.build(shell, build_dir, build_options)
         | 
| 14 20 |  | 
| 15 21 | 
             
                version_tag = version_tag_builder.get_version
         | 
| 16 22 | 
             
                docker_commands.tag(shell, image.registry_url, version_tag)
         | 
| @@ -21,5 +27,7 @@ class KuberKit::ImageCompiler::ImageBuilder | |
| 21 27 | 
             
                end
         | 
| 22 28 |  | 
| 23 29 | 
             
                image.after_build_callback.call(context_helper, build_dir) if image.after_build_callback
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                build_result
         | 
| 24 32 | 
             
              end
         | 
| 25 33 | 
             
            end
         | 
| @@ -8,8 +8,9 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer: | |
| 8 8 | 
             
              STRATEGY_OPTIONS = [
         | 
| 9 9 | 
             
                :container_name,
         | 
| 10 10 | 
             
                :image_name,
         | 
| 11 | 
            -
                : | 
| 12 | 
            -
                : | 
| 11 | 
            +
                :detached,
         | 
| 12 | 
            +
                :command_name,
         | 
| 13 | 
            +
                :command_args,
         | 
| 13 14 | 
             
                :delete_if_exists
         | 
| 14 15 | 
             
              ]
         | 
| 15 16 |  | 
| @@ -21,9 +22,9 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer: | |
| 21 22 | 
             
                  raise KuberKit::Error, "Unknow options for deploy strategy: #{unknown_options}. Available options: #{STRATEGY_OPTIONS}"
         | 
| 22 23 | 
             
                end
         | 
| 23 24 |  | 
| 24 | 
            -
                container_name | 
| 25 | 
            -
                 | 
| 26 | 
            -
                 | 
| 25 | 
            +
                container_name = strategy_options.fetch(:container_name, service.uri)
         | 
| 26 | 
            +
                command_name   = strategy_options.fetch(:command_name, "bash")
         | 
| 27 | 
            +
                command_args   = strategy_options.fetch(:command_args, nil)
         | 
| 27 28 |  | 
| 28 29 | 
             
                image_name = strategy_options.fetch(:image_name, nil)
         | 
| 29 30 | 
             
                if image_name.nil?
         | 
| @@ -36,11 +37,16 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer: | |
| 36 37 | 
             
                  docker_commands.delete_container(shell, container_name)
         | 
| 37 38 | 
             
                end
         | 
| 38 39 |  | 
| 40 | 
            +
                command_args = Array(command_args)
         | 
| 41 | 
            +
                if container_name
         | 
| 42 | 
            +
                  command_args << "--name #{container_name}"
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 39 45 | 
             
                docker_commands.run(
         | 
| 40 46 | 
             
                  shell, image.remote_registry_url, 
         | 
| 41 | 
            -
                   | 
| 42 | 
            -
                   | 
| 43 | 
            -
                  detached: | 
| 47 | 
            +
                  command:    command_name,
         | 
| 48 | 
            +
                  args:       command_args, 
         | 
| 49 | 
            +
                  detached:   !!strategy_options[:detached]
         | 
| 44 50 | 
             
                )
         | 
| 45 51 | 
             
              end
         | 
| 46 52 | 
             
            end
         | 
| @@ -7,7 +7,9 @@ class KuberKit::ServiceDeployer::Strategies::DockerCompose < KuberKit::ServiceDe | |
| 7 7 |  | 
| 8 8 | 
             
              STRATEGY_OPTIONS = [
         | 
| 9 9 | 
             
                :service_name, 
         | 
| 10 | 
            -
                :command_name
         | 
| 10 | 
            +
                :command_name,
         | 
| 11 | 
            +
                :command_args,
         | 
| 12 | 
            +
                :detached
         | 
| 11 13 | 
             
              ]
         | 
| 12 14 |  | 
| 13 15 | 
             
              Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
         | 
| @@ -24,10 +26,12 @@ class KuberKit::ServiceDeployer::Strategies::DockerCompose < KuberKit::ServiceDe | |
| 24 26 |  | 
| 25 27 | 
             
                service_name = strategy_options.fetch(:service_name, service.name.to_s)
         | 
| 26 28 | 
             
                command_name = strategy_options.fetch(:command_name, "bash")
         | 
| 29 | 
            +
                command_args = strategy_options.fetch(:command_args, nil)
         | 
| 27 30 |  | 
| 28 31 | 
             
                docker_compose_commands.run(shell, config_path, 
         | 
| 29 32 | 
             
                  service:  service_name, 
         | 
| 30 33 | 
             
                  command:  command_name,
         | 
| 34 | 
            +
                  args:     command_args, 
         | 
| 31 35 | 
             
                  detached: !!strategy_options[:detached]
         | 
| 32 36 | 
             
                )
         | 
| 33 37 | 
             
              end
         | 
| @@ -39,7 +39,7 @@ class KuberKit::ServiceDeployer::Strategies::Kubernetes < KuberKit::ServiceDeplo | |
| 39 39 | 
             
                  kubectl_commands.delete_resource(shell, resource_type, resource_name, kubeconfig_path: kubeconfig_path, namespace: namespace)
         | 
| 40 40 | 
             
                end
         | 
| 41 41 |  | 
| 42 | 
            -
                kubectl_commands.apply_file(shell, config_path, kubeconfig_path: kubeconfig_path, namespace: namespace)
         | 
| 42 | 
            +
                apply_result = kubectl_commands.apply_file(shell, config_path, kubeconfig_path: kubeconfig_path, namespace: namespace)
         | 
| 43 43 |  | 
| 44 44 | 
             
                restart_enabled = strategy_options.fetch(:restart_if_exists, true)
         | 
| 45 45 | 
             
                if restart_enabled && resource_exists
         | 
| @@ -48,5 +48,7 @@ class KuberKit::ServiceDeployer::Strategies::Kubernetes < KuberKit::ServiceDeplo | |
| 48 48 | 
             
                    kubeconfig_path: kubeconfig_path, namespace: namespace
         | 
| 49 49 | 
             
                  )
         | 
| 50 50 | 
             
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                apply_result
         | 
| 51 53 | 
             
              end
         | 
| 52 54 | 
             
            end
         | 
| @@ -6,8 +6,14 @@ class KuberKit::ServiceReader::Reader | |
| 6 6 | 
             
                "preprocessing.text_preprocessor"
         | 
| 7 7 | 
             
              ]
         | 
| 8 8 |  | 
| 9 | 
            +
              AttributeNotSetError = Class.new(KuberKit::Error)
         | 
| 10 | 
            +
             | 
| 9 11 | 
             
              Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
         | 
| 10 12 | 
             
              def read(shell, service)
         | 
| 13 | 
            +
                if service.template_name.nil?
         | 
| 14 | 
            +
                  raise AttributeNotSetError, "Please set template for service using #template method"
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 11 17 | 
             
                template = template_store.get(service.template_name)
         | 
| 12 18 |  | 
| 13 19 | 
             
                context_helper = context_helper_factory.build_service_context(shell, service)
         | 
| @@ -3,7 +3,7 @@ class KuberKit::Shell::Commands::DockerCommands | |
| 3 3 | 
             
                default_args = ["--rm=true"]
         | 
| 4 4 | 
             
                args_list = (default_args + args).join(" ")
         | 
| 5 5 |  | 
| 6 | 
            -
                shell.exec!(%Q{docker build #{build_dir} #{args_list}})
         | 
| 6 | 
            +
                shell.exec!(%Q{docker image build #{build_dir} #{args_list}})
         | 
| 7 7 | 
             
              end
         | 
| 8 8 |  | 
| 9 9 | 
             
              def tag(shell, image_name, tag_name)
         | 
| @@ -14,19 +14,23 @@ class KuberKit::Shell::Commands::DockerCommands | |
| 14 14 | 
             
                shell.exec!(%Q{docker push #{tag_name}})
         | 
| 15 15 | 
             
              end
         | 
| 16 16 |  | 
| 17 | 
            -
              def run(shell, image_name,  | 
| 17 | 
            +
              def run(shell, image_name, args: nil, command: nil, detached: false, interactive: false)
         | 
| 18 18 | 
             
                command_parts = []
         | 
| 19 19 | 
             
                command_parts << "docker run"
         | 
| 20 20 | 
             
                command_parts << "-d" if detached
         | 
| 21 | 
            -
                command_parts <<  | 
| 21 | 
            +
                command_parts << Array(args).join(" ") if args
         | 
| 22 22 | 
             
                command_parts << image_name
         | 
| 23 | 
            -
                command_parts <<  | 
| 23 | 
            +
                command_parts << command if command
         | 
| 24 24 |  | 
| 25 | 
            -
                 | 
| 25 | 
            +
                if interactive
         | 
| 26 | 
            +
                  shell.interactive!(command_parts.join(" "))
         | 
| 27 | 
            +
                else
         | 
| 28 | 
            +
                  shell.exec!(command_parts.join(" "))
         | 
| 29 | 
            +
                end
         | 
| 26 30 | 
             
              end
         | 
| 27 31 |  | 
| 28 | 
            -
              def container_exists?(shell, container_name)
         | 
| 29 | 
            -
                result = get_container_id(shell, container_name)
         | 
| 32 | 
            +
              def container_exists?(shell, container_name, status: nil)
         | 
| 33 | 
            +
                result = get_container_id(shell, container_name, status: status)
         | 
| 30 34 | 
             
                result && result != ""
         | 
| 31 35 | 
             
              end
         | 
| 32 36 |  | 
| @@ -34,15 +38,16 @@ class KuberKit::Shell::Commands::DockerCommands | |
| 34 38 | 
             
                shell.exec!(%Q{docker rm -f #{container_name}})
         | 
| 35 39 | 
             
              end
         | 
| 36 40 |  | 
| 37 | 
            -
              def get_container_id(shell, container_name, only_healthy: false, status:  | 
| 41 | 
            +
              def get_container_id(shell, container_name, only_healthy: false, status: nil)
         | 
| 38 42 | 
             
                command_parts = []
         | 
| 39 43 | 
             
                command_parts << "docker ps -a -q"
         | 
| 40 44 |  | 
| 41 45 | 
             
                if only_healthy
         | 
| 42 46 | 
             
                  command_parts << "--filter=\"health=healthy\""
         | 
| 43 47 | 
             
                end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 48 | 
            +
                if status
         | 
| 49 | 
            +
                  command_parts << "--filter=\"status=#{status}\""
         | 
| 50 | 
            +
                end
         | 
| 46 51 | 
             
                command_parts << "--filter=\"name=#{container_name}\""
         | 
| 47 52 |  | 
| 48 53 | 
             
                shell.exec!(command_parts.join(" "))
         | 
| @@ -1,17 +1,16 @@ | |
| 1 1 | 
             
            class KuberKit::Shell::Commands::DockerComposeCommands
         | 
| 2 | 
            -
              def run(shell, path, service:, command | 
| 2 | 
            +
              def run(shell, path, service:, args: nil, command: nil, detached: false, interactive: false)
         | 
| 3 3 | 
             
                command_parts = [
         | 
| 4 4 | 
             
                  "docker-compose",
         | 
| 5 | 
            -
                  "run",
         | 
| 6 5 | 
             
                  "-f #{path}",
         | 
| 6 | 
            +
                  "run",
         | 
| 7 7 | 
             
                ]
         | 
| 8 8 |  | 
| 9 | 
            -
                if detached
         | 
| 10 | 
            -
                  command_parts << "-d"
         | 
| 11 | 
            -
                end
         | 
| 12 9 |  | 
| 10 | 
            +
                command_parts << "-d" if detached
         | 
| 11 | 
            +
                command_parts << Array(args).join(" ") if args
         | 
| 13 12 | 
             
                command_parts << service
         | 
| 14 | 
            -
                command_parts << command
         | 
| 13 | 
            +
                command_parts << command if command
         | 
| 15 14 |  | 
| 16 15 | 
             
                if interactive
         | 
| 17 16 | 
             
                  shell.interactive!(command_parts.join(" "))
         | 
| @@ -2,16 +2,16 @@ require 'fileutils' | |
| 2 2 |  | 
| 3 3 | 
             
            class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
         | 
| 4 4 | 
             
              include KuberKit::Import[
         | 
| 5 | 
            -
                "tools.logger",
         | 
| 6 5 | 
             
                "shell.command_counter",
         | 
| 7 6 | 
             
                "shell.rsync_commands",
         | 
| 7 | 
            +
                "ui",
         | 
| 8 8 | 
             
              ]
         | 
| 9 9 |  | 
| 10 10 | 
             
              def exec!(command, log_command: true)
         | 
| 11 11 | 
             
                command_number = command_counter.get_number.to_s.rjust(2, "0")
         | 
| 12 12 |  | 
| 13 13 | 
             
                if log_command
         | 
| 14 | 
            -
                   | 
| 14 | 
            +
                  ui.print_debug("LocalShell", "Execute: [#{command_number}]: #{command.to_s.cyan}")
         | 
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 17 | 
             
                result = nil
         | 
| @@ -20,7 +20,7 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell | |
| 20 20 | 
             
                end
         | 
| 21 21 |  | 
| 22 22 | 
             
                if result && result != "" && log_command
         | 
| 23 | 
            -
                   | 
| 23 | 
            +
                  ui.print_debug("LocalShell", "Finished [#{command_number}] with result: \n  ----\n#{result.grey}\n  ----")
         | 
| 24 24 | 
             
                end
         | 
| 25 25 |  | 
| 26 26 | 
             
                if $?.exitstatus != 0
         | 
| @@ -34,7 +34,7 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell | |
| 34 34 | 
             
                command_number = command_counter.get_number.to_s.rjust(2, "0")
         | 
| 35 35 |  | 
| 36 36 | 
             
                if log_command
         | 
| 37 | 
            -
                   | 
| 37 | 
            +
                  ui.print_debug("LocalShell", "Interactive: [#{command_number}]: #{command.to_s.cyan}")
         | 
| 38 38 | 
             
                end
         | 
| 39 39 |  | 
| 40 40 | 
             
                result = system(command)
         | 
| @@ -57,7 +57,7 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell | |
| 57 57 |  | 
| 58 58 | 
             
                File.write(file_path, content)
         | 
| 59 59 |  | 
| 60 | 
            -
                 | 
| 60 | 
            +
                ui.print_debug("LocalShell", "Created file #{file_path.to_s.cyan}\r\n  ----\r\n#{content.grey}\r\n  ----")
         | 
| 61 61 |  | 
| 62 62 | 
             
                true
         | 
| 63 63 | 
             
              end
         | 
| @@ -76,7 +76,7 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell | |
| 76 76 |  | 
| 77 77 | 
             
              def recursive_list_files(path, name: nil)
         | 
| 78 78 | 
             
                command = %Q{find -L #{path}  -type f}
         | 
| 79 | 
            -
                command += " -name #{name}" if name
         | 
| 79 | 
            +
                command += " -name '#{name}'" if name
         | 
| 80 80 | 
             
                exec!(command).split(/[\r\n]+/)
         | 
| 81 81 | 
             
              rescue => e
         | 
| 82 82 | 
             
                if e.message.include?("No such file or directory")
         | 
| @@ -2,7 +2,7 @@ require 'tempfile' | |
| 2 2 |  | 
| 3 3 | 
             
            class KuberKit::Shell::SshShell < KuberKit::Shell::LocalShell
         | 
| 4 4 | 
             
              include KuberKit::Import[
         | 
| 5 | 
            -
                " | 
| 5 | 
            +
                "ui",
         | 
| 6 6 | 
             
                "shell.command_counter",
         | 
| 7 7 | 
             
                "shell.rsync_commands",
         | 
| 8 8 | 
             
                "shell.local_shell"
         | 
| @@ -24,13 +24,13 @@ class KuberKit::Shell::SshShell < KuberKit::Shell::LocalShell | |
| 24 24 | 
             
                command_number = command_counter.get_number.to_s.rjust(2, "0")
         | 
| 25 25 |  | 
| 26 26 | 
             
                if log_command
         | 
| 27 | 
            -
                   | 
| 27 | 
            +
                  ui.print_debug("SshShell", "#{ssh_session.host.green} > Execute: [#{command_number}]: #{command.to_s.cyan}")
         | 
| 28 28 | 
             
                end
         | 
| 29 29 |  | 
| 30 30 | 
             
                result = ssh_session.exec!(command)
         | 
| 31 31 |  | 
| 32 32 | 
             
                if result && result != "" && log_command
         | 
| 33 | 
            -
                   | 
| 33 | 
            +
                  ui.print_debug("SshShell", "#{ssh_session.host.green} > Finished [#{command_number}] with result: \n#{result.grey}")
         | 
| 34 34 | 
             
                end
         | 
| 35 35 |  | 
| 36 36 | 
             
                result
         | 
| @@ -62,7 +62,7 @@ class KuberKit::Shell::SshShell < KuberKit::Shell::LocalShell | |
| 62 62 | 
             
                  sync(file.path, file_path)
         | 
| 63 63 | 
             
                end
         | 
| 64 64 |  | 
| 65 | 
            -
                 | 
| 65 | 
            +
                ui.print_debug("SshShell", "Created file #{file_path.to_s.cyan}\r\n  ----\r\n#{content.grey}\r\n  ----")
         | 
| 66 66 |  | 
| 67 67 | 
             
                true
         | 
| 68 68 | 
             
              end
         | 
| @@ -9,8 +9,12 @@ class KuberKit::Tools::LoggerFactory | |
| 9 9 | 
             
                Logger::FATAL  => String::Colors::PURPLE,
         | 
| 10 10 | 
             
              }
         | 
| 11 11 |  | 
| 12 | 
            -
               | 
| 13 | 
            -
                 | 
| 12 | 
            +
              include KuberKit::Import[
         | 
| 13 | 
            +
                "configs",
         | 
| 14 | 
            +
              ]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def create(stdout = nil, level = nil)
         | 
| 17 | 
            +
                logger = Logger.new(stdout || configs.log_file_path)
         | 
| 14 18 |  | 
| 15 19 | 
             
                logger.level = level || Logger::DEBUG
         | 
| 16 20 |  | 
| @@ -22,7 +26,7 @@ class KuberKit::Tools::LoggerFactory | |
| 22 26 | 
             
                  severity_text  = severity.to_s
         | 
| 23 27 | 
             
                  severity_text  = severity_text.colorize(severity_color) if severity_color
         | 
| 24 28 |  | 
| 25 | 
            -
                  if level == Logger:: | 
| 29 | 
            +
                  if level == Logger::DEBUG
         | 
| 26 30 | 
             
                    "#{datetime.strftime("%Y/%m/%d %H:%M:%S").grey} #{msg}\n"
         | 
| 27 31 | 
             
                  else
         | 
| 28 32 | 
             
                    "#{datetime.strftime("%Y/%m/%d %H:%M:%S").grey} #{severity_text.downcase}: #{msg}\n"
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
            class KuberKit::UI::Api < KuberKit::UI::Simple
         | 
| 3 | 
            +
              class Task < KuberKit::UI::Simple::Task
         | 
| 4 | 
            +
                def print_started
         | 
| 5 | 
            +
                  # do nothing, api formatter should only show result
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def print_finished
         | 
| 9 | 
            +
                  # do nothing, api formatter should only show result
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def create_task_group
         | 
| 14 | 
            +
                TaskGroup.new(KuberKit::UI::Api::Task)
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def create_task(title, &block)
         | 
| 18 | 
            +
                task = KuberKit::UI::Api::Task.new(title, &block)
         | 
| 19 | 
            +
                task.execute
         | 
| 20 | 
            +
                task.wait
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              def print_info(title, text)
         | 
| 24 | 
            +
                logger.debug(text)
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def print_error(title, text)
         | 
| 28 | 
            +
                logger.debug(text)
         | 
| 29 | 
            +
                print_json({error: text})
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def print_warning(title, text)
         | 
| 33 | 
            +
                logger.debug(text)
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def print_debug(title, text)
         | 
| 37 | 
            +
                logger.debug(text)
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def print_result(message, data = {})
         | 
| 41 | 
            +
                print_json({message: message}.merge(data))
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              protected
         | 
| 45 | 
            +
                def print_json(data)
         | 
| 46 | 
            +
                  puts JSON.generate(data)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            class KuberKit::UI::Debug < KuberKit::UI::Simple
         | 
| 2 | 
            +
              def print_info(title, text)
         | 
| 3 | 
            +
                print_text(text, color: String::Colors::BLUE)
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def print_error(title, text)
         | 
| 7 | 
            +
                print_text(text, color: String::Colors::RED)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def print_warning(title, text)
         | 
| 11 | 
            +
                print_text(text, color: String::Colors::YELLOW)
         | 
| 12 | 
            +
                logger.debug(text)
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              def print_debug(title, text)
         | 
| 16 | 
            +
                print_text(text, color: nil)
         | 
| 17 | 
            +
                logger.debug(text)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def print_result(message, data = {})
         | 
| 21 | 
            +
                print_debug("Result", "---------------------------")
         | 
| 22 | 
            +
                print_debug("Result", message)
         | 
| 23 | 
            +
                print_debug("Result", "---------------------------")
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              protected
         | 
| 27 | 
            +
                def print_text(text, color: nil)
         | 
| 28 | 
            +
                  colorized_message = color ? text.colorize(color) : text
         | 
| 29 | 
            +
                  puts "  #{Time.now.strftime("%H:%M:%S").grey} #{colorized_message}"
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
            end
         | 
| @@ -1,6 +1,10 @@ | |
| 1 1 | 
             
            require 'cli/ui'
         | 
| 2 2 |  | 
| 3 3 | 
             
            class KuberKit::UI::Interactive
         | 
| 4 | 
            +
              include KuberKit::Import[
         | 
| 5 | 
            +
                "tools.logger",
         | 
| 6 | 
            +
              ]
         | 
| 7 | 
            +
             | 
| 4 8 | 
             
              class TaskGroup < CLI::UI::SpinGroup
         | 
| 5 9 | 
             
              end
         | 
| 6 10 |  | 
| @@ -24,6 +28,17 @@ class KuberKit::UI::Interactive | |
| 24 28 |  | 
| 25 29 | 
             
              def print_warning(title, text)
         | 
| 26 30 | 
             
                print_in_frame(title, text, color: :yellow)
         | 
| 31 | 
            +
                logger.debug(text)
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def print_debug(title, text)
         | 
| 35 | 
            +
                logger.debug(text)
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def print_result(message, data = {})
         | 
| 39 | 
            +
                print_debug("Result", "---------------------------")
         | 
| 40 | 
            +
                print_debug("Result", message)
         | 
| 41 | 
            +
                print_debug("Result", "---------------------------")
         | 
| 27 42 | 
             
              end
         | 
| 28 43 |  | 
| 29 44 | 
             
              def prompt(text, options, &callback)
         | 
    
        data/lib/kuber_kit/ui/simple.rb
    CHANGED
    
    | @@ -1,19 +1,33 @@ | |
| 1 1 | 
             
            class KuberKit::UI::Simple
         | 
| 2 | 
            +
              include KuberKit::Import[
         | 
| 3 | 
            +
                "tools.logger",
         | 
| 4 | 
            +
              ]
         | 
| 5 | 
            +
             | 
| 2 6 | 
             
              class Task
         | 
| 3 7 | 
             
                def initialize(title, &callback)
         | 
| 4 8 | 
             
                  @title = title
         | 
| 5 9 | 
             
                  @callback = callback
         | 
| 6 10 | 
             
                end
         | 
| 7 11 |  | 
| 12 | 
            +
                def print_started
         | 
| 13 | 
            +
                  puts "- #{@title}"
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def print_finished
         | 
| 17 | 
            +
                  puts "- #{@title.grey}"
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 8 20 | 
             
                def execute
         | 
| 9 21 | 
             
                  if @thread
         | 
| 10 22 | 
             
                    raise "Already started execution of task '#{title}'"
         | 
| 11 23 | 
             
                  end
         | 
| 12 24 |  | 
| 13 25 | 
             
                  @thread = Thread.new do
         | 
| 14 | 
            -
                     | 
| 26 | 
            +
                    Thread.current.abort_on_exception = true
         | 
| 27 | 
            +
                    Thread.current.report_on_exception = false
         | 
| 28 | 
            +
                    print_started
         | 
| 15 29 | 
             
                    @callback.call(self)
         | 
| 16 | 
            -
                     | 
| 30 | 
            +
                    print_finished
         | 
| 17 31 | 
             
                  end
         | 
| 18 32 | 
             
                end
         | 
| 19 33 |  | 
| @@ -30,8 +44,12 @@ class KuberKit::UI::Simple | |
| 30 44 | 
             
              end
         | 
| 31 45 |  | 
| 32 46 | 
             
              class TaskGroup
         | 
| 47 | 
            +
                def initialize(task_class)
         | 
| 48 | 
            +
                  @task_class = task_class
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 33 51 | 
             
                def add(task_title, &task_block)
         | 
| 34 | 
            -
                  task =  | 
| 52 | 
            +
                  task = @task_class.new(task_title, &task_block)
         | 
| 35 53 | 
             
                  task.execute
         | 
| 36 54 | 
             
                  add_task(task)
         | 
| 37 55 | 
             
                end
         | 
| @@ -47,7 +65,7 @@ class KuberKit::UI::Simple | |
| 47 65 | 
             
              end
         | 
| 48 66 |  | 
| 49 67 | 
             
              def create_task_group
         | 
| 50 | 
            -
                TaskGroup.new
         | 
| 68 | 
            +
                TaskGroup.new(KuberKit::UI::Simple::Task)
         | 
| 51 69 | 
             
              end
         | 
| 52 70 |  | 
| 53 71 | 
             
              def create_task(title, &block)
         | 
| @@ -66,6 +84,17 @@ class KuberKit::UI::Simple | |
| 66 84 |  | 
| 67 85 | 
             
              def print_warning(title, text)
         | 
| 68 86 | 
             
                print_text(title, text, color: String::Colors::YELLOW)
         | 
| 87 | 
            +
                logger.debug(text)
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              def print_debug(title, text)
         | 
| 91 | 
            +
                logger.debug(text)
         | 
| 92 | 
            +
              end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              def print_result(message, data = {})
         | 
| 95 | 
            +
                print_debug("Result", "---------------------------")
         | 
| 96 | 
            +
                print_debug("Result", message)
         | 
| 97 | 
            +
                print_debug("Result", "---------------------------")
         | 
| 69 98 | 
             
              end
         | 
| 70 99 |  | 
| 71 100 | 
             
              def prompt(text, options, &callback)
         | 
| @@ -75,7 +104,7 @@ class KuberKit::UI::Simple | |
| 75 104 | 
             
                result
         | 
| 76 105 | 
             
              end
         | 
| 77 106 |  | 
| 78 | 
            -
               | 
| 107 | 
            +
              protected
         | 
| 79 108 | 
             
                def print_text(title, text, color:)
         | 
| 80 109 | 
             
                  puts "#{title.colorize(color)}\r\n #{text.colorize(color)}"
         | 
| 81 110 | 
             
                end
         | 
    
        data/lib/kuber_kit/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: kuber_kit
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Iskander Khaziev
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2021-01- | 
| 11 | 
            +
            date: 2021-01-13 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: contracts-lite
         | 
| @@ -145,6 +145,7 @@ executables: | |
| 145 145 | 
             
            extensions: []
         | 
| 146 146 | 
             
            extra_rdoc_files: []
         | 
| 147 147 | 
             
            files:
         | 
| 148 | 
            +
            - ".github/workflows/rspec.yml"
         | 
| 148 149 | 
             
            - ".gitignore"
         | 
| 149 150 | 
             
            - ".rspec"
         | 
| 150 151 | 
             
            - ".ruby-gemset"
         | 
| @@ -182,6 +183,7 @@ files: | |
| 182 183 | 
             
            - example/infrastructure/registries.rb
         | 
| 183 184 | 
             
            - example/infrastructure/templates.rb
         | 
| 184 185 | 
             
            - example/services/compose_app.rb
         | 
| 186 | 
            +
            - example/services/docker_app.rb
         | 
| 185 187 | 
             
            - example/services/env_file.rb
         | 
| 186 188 | 
             
            - example/services/ruby_app.rb
         | 
| 187 189 | 
             
            - kuber_kit.gemspec
         | 
| @@ -286,6 +288,8 @@ files: | |
| 286 288 | 
             
            - lib/kuber_kit/tools/file_presence_checker.rb
         | 
| 287 289 | 
             
            - lib/kuber_kit/tools/logger_factory.rb
         | 
| 288 290 | 
             
            - lib/kuber_kit/ui.rb
         | 
| 291 | 
            +
            - lib/kuber_kit/ui/api.rb
         | 
| 292 | 
            +
            - lib/kuber_kit/ui/debug.rb
         | 
| 289 293 | 
             
            - lib/kuber_kit/ui/interactive.rb
         | 
| 290 294 | 
             
            - lib/kuber_kit/ui/simple.rb
         | 
| 291 295 | 
             
            - lib/kuber_kit/version.rb
         |