firespring_dev_commands 2.1.26.pre.alpha.2 → 2.1.27.pre.alpha.1
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/lib/firespring_dev_commands/certificate.rb +59 -0
- data/lib/firespring_dev_commands/docker/status.rb +20 -0
- data/lib/firespring_dev_commands/docker.rb +38 -0
- data/lib/firespring_dev_commands/eol.rb +4 -13
- data/lib/firespring_dev_commands/templates/aws.rb +15 -3
- data/lib/firespring_dev_commands/templates/certificate.rb +41 -0
- data/lib/firespring_dev_commands/templates/git.rb +0 -17
- data/lib/firespring_dev_commands/version.rb +1 -1
- metadata +4 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 1f810ca7ab797bb1ec56674b67d42de056d5f88cd95a8e9c45b67d26a3570d19
         | 
| 4 | 
            +
              data.tar.gz: 487bdc8a74717f11bb48b5b81a33093fde87ddb2b44d97cdf84a0372e3b93627
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 212273f4a640214bf8001c12419f33bb6dc621dc37a29b95e75d06c5b5e4bd3f7b7231c003cd032ed1be1c2dc0667d3474fb74892a7577ddd57eca248d96ab09
         | 
| 7 | 
            +
              data.tar.gz: 480720fd9de858a1ce969644958e61238e866fef1126fb91909992eca3301275d04fd42df45c1f34a7c5126758172a4c89f7bfc0ea3c1b8e2528816de97dbfba
         | 
| @@ -0,0 +1,59 @@ | |
| 1 | 
            +
            module Dev
         | 
| 2 | 
            +
              # Class contains methods for requesting a certificate from route53.
         | 
| 3 | 
            +
              # You must have a hosted zone defined for the desired domain
         | 
| 4 | 
            +
              class Certificate
         | 
| 5 | 
            +
                attr_accessor :domains, :email
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(domains, email)
         | 
| 8 | 
            +
                  @domains = Array(domains)
         | 
| 9 | 
            +
                  @email = email
         | 
| 10 | 
            +
                  raise 'No certificate domains specified' if domains.empty?
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # Request the certificate using the route53 docker image
         | 
| 14 | 
            +
                # Certificate is stored in /etc/letsencrypt
         | 
| 15 | 
            +
                def request
         | 
| 16 | 
            +
                  puts
         | 
| 17 | 
            +
                  puts 'Getting SSL Certs For:'
         | 
| 18 | 
            +
                  puts domains.join("\n")
         | 
| 19 | 
            +
                  puts
         | 
| 20 | 
            +
                  puts 'This process can take up to 10 minutes'
         | 
| 21 | 
            +
                  puts
         | 
| 22 | 
            +
                  puts Time.now
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  # TODO: Really should use the docker api for this
         | 
| 25 | 
            +
                  cmd = %w(docker run -it --rm --name certbot)
         | 
| 26 | 
            +
                  cmd << '-e' << 'AWS_ACCESS_KEY_ID'
         | 
| 27 | 
            +
                  cmd << '-e' << 'AWS_SECRET_ACCESS_KEY'
         | 
| 28 | 
            +
                  cmd << '-e' << 'AWS_SESSION_TOKEN'
         | 
| 29 | 
            +
                  cmd << '-v' << '/etc/letsencrypt:/etc/letsencrypt'
         | 
| 30 | 
            +
                  cmd << 'certbot/dns-route53:latest'
         | 
| 31 | 
            +
                  cmd << 'certonly'
         | 
| 32 | 
            +
                  cmd << '-n'
         | 
| 33 | 
            +
                  cmd << '--agree-tos'
         | 
| 34 | 
            +
                  cmd << '--dns-route53'
         | 
| 35 | 
            +
                  cmd << '-d' << domains.join(',')
         | 
| 36 | 
            +
                  cmd << '--email' << email
         | 
| 37 | 
            +
                  cmd << '--server' << 'https://acme-v02.api.letsencrypt.org/directory'
         | 
| 38 | 
            +
                  puts cmd.join(' ')
         | 
| 39 | 
            +
                  Dev::Common.new.run_command(cmd)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                # Saves the latest version of the certificate into the given dest_dir
         | 
| 43 | 
            +
                def save(dest_dir)
         | 
| 44 | 
            +
                  raise "directory #{dest_dir} must be an existing directory" unless File.directory?(dest_dir)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  domain = domains.first.sub(/^\*\./, '')
         | 
| 47 | 
            +
                  directories = Dir.glob("/etc/letsencrypt/live/#{domain}*/")
         | 
| 48 | 
            +
                  no_suffix = directories.delete("/etc/letsencrypt/live/#{domain}/")
         | 
| 49 | 
            +
                  biggest_suffix = directories.max
         | 
| 50 | 
            +
                  source_dir = biggest_suffix || no_suffix
         | 
| 51 | 
            +
                  raise "unable to determine certificate directory for #{domain}" unless source_dir
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  FileUtils.cp("#{source_dir}privkey.pem", dest_dir, verbose: true)
         | 
| 54 | 
            +
                  FileUtils.cp("#{source_dir}cert.pem", dest_dir, verbose: true)
         | 
| 55 | 
            +
                  FileUtils.cp("#{source_dir}chain.pem", dest_dir, verbose: true)
         | 
| 56 | 
            +
                  FileUtils.cp("#{source_dir}fullchain.pem", dest_dir, verbose: true)
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
            end
         | 
| @@ -33,6 +33,26 @@ module Dev | |
| 33 33 | 
             
                    EXITED,
         | 
| 34 34 | 
             
                    DEAD
         | 
| 35 35 | 
             
                  ].freeze
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  # TODO: Can we use 'curses' here and overwrite the correct line?
         | 
| 38 | 
            +
                  def response_callback(response)
         | 
| 39 | 
            +
                    response.split("\n").each do |line|
         | 
| 40 | 
            +
                      data = JSON.parse(line)
         | 
| 41 | 
            +
                      if data.include?('status')
         | 
| 42 | 
            +
                        if data['id']
         | 
| 43 | 
            +
                          LOG.info "#{data['id']}: #{data['status']}"
         | 
| 44 | 
            +
                        else
         | 
| 45 | 
            +
                          LOG.info (data['status']).to_s
         | 
| 46 | 
            +
                        end
         | 
| 47 | 
            +
                      elsif data.include?('errorDetail')
         | 
| 48 | 
            +
                        raise data['errorDetail']['message']
         | 
| 49 | 
            +
                      elsif data.include?('aux')
         | 
| 50 | 
            +
                        next
         | 
| 51 | 
            +
                      else
         | 
| 52 | 
            +
                        raise "Unrecognized message from docker: #{data}"
         | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                  end
         | 
| 36 56 | 
             
                end
         | 
| 37 57 | 
             
              end
         | 
| 38 58 | 
             
            end
         | 
| @@ -117,6 +117,44 @@ module Dev | |
| 117 117 | 
             
                  format('%.1f %s', size.to_f / (1024**exp), units[exp])
         | 
| 118 118 | 
             
                end
         | 
| 119 119 |  | 
| 120 | 
            +
                # Push the local version of the docker image to the defined remote repository
         | 
| 121 | 
            +
                def push_image(image, name, tag = nil)
         | 
| 122 | 
            +
                  unless tag
         | 
| 123 | 
            +
                    if name.include?(':')
         | 
| 124 | 
            +
                      name, tag = name.split(':')
         | 
| 125 | 
            +
                    else
         | 
| 126 | 
            +
                      tag = 'latest'
         | 
| 127 | 
            +
                    end
         | 
| 128 | 
            +
                  end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                  puts "Pushing to #{name}:#{tag}"
         | 
| 131 | 
            +
                  image.push(::Docker.creds, repo_tag: "#{name}:#{tag}") { |response| Dev::Docker::Status.new.response_callback(response) }
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                # Push the remote version of the docker image from the defined remote repository
         | 
| 135 | 
            +
                def pull_image(name, tag = nil)
         | 
| 136 | 
            +
                  unless tag
         | 
| 137 | 
            +
                    if name.include?(':')
         | 
| 138 | 
            +
                      name, tag = name.split(':')
         | 
| 139 | 
            +
                    else
         | 
| 140 | 
            +
                      tag = 'latest'
         | 
| 141 | 
            +
                    end
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                  puts "\nPulling #{name}:#{tag}"
         | 
| 145 | 
            +
                  opts = {
         | 
| 146 | 
            +
                    fromImage: "#{name}:#{tag}",
         | 
| 147 | 
            +
                    platform: Dev::Common::Platform.new.architecture
         | 
| 148 | 
            +
                  }
         | 
| 149 | 
            +
                  ::Docker::Image.create(**opts) { |response| Dev::Docker::Status.new.response_callback(response) }
         | 
| 150 | 
            +
                end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                # Remove the local version of the given docker image
         | 
| 153 | 
            +
                def untag_image(image, name, tag)
         | 
| 154 | 
            +
                  puts "Untagging #{name}:#{tag}"
         | 
| 155 | 
            +
                  image.remove(name: "#{name}:#{tag}")
         | 
| 156 | 
            +
                end
         | 
| 157 | 
            +
             | 
| 120 158 | 
             
                # Remove docker images with the "force" option set to true
         | 
| 121 159 | 
             
                # This will remove the images even if they are currently in use and cause unintended side effects.
         | 
| 122 160 | 
             
                def force_remove_images(name_and_tag)
         | 
| @@ -5,9 +5,8 @@ module Dev | |
| 5 5 | 
             
                END_OF_LIFE_API_URL = 'https://endoflife.date/api'.freeze
         | 
| 6 6 |  | 
| 7 7 | 
             
                # Config object for setting top level git config options
         | 
| 8 | 
            -
                Config = Struct.new(: | 
| 8 | 
            +
                Config = Struct.new(:product_versions, :manual_dates) do
         | 
| 9 9 | 
             
                  def initialize
         | 
| 10 | 
            -
                    self.check_aws_resources = false
         | 
| 11 10 | 
             
                    self.product_versions = []
         | 
| 12 11 | 
             
                    self.manual_dates = {}
         | 
| 13 12 | 
             
                  end
         | 
| @@ -27,10 +26,9 @@ module Dev | |
| 27 26 | 
             
                  alias_method :configure, :config
         | 
| 28 27 | 
             
                end
         | 
| 29 28 |  | 
| 30 | 
            -
                attr_accessor :url, :products, : | 
| 29 | 
            +
                attr_accessor :url, :products, :product_versions
         | 
| 31 30 |  | 
| 32 | 
            -
                def initialize( | 
| 33 | 
            -
                  @check_aws_resources = check_aws_resources
         | 
| 31 | 
            +
                def initialize(product_versions: self.class.config.product_versions)
         | 
| 34 32 | 
             
                  @product_versions = Array(product_versions)
         | 
| 35 33 | 
             
                  raise 'product version must be of type Dev::EndOfLife::ProductVersions' unless @product_versions.all?(Dev::EndOfLife::ProductVersion)
         | 
| 36 34 | 
             
                end
         | 
| @@ -52,14 +50,7 @@ module Dev | |
| 52 50 | 
             
                # Raises an error if any products are EOL
         | 
| 53 51 | 
             
                def check
         | 
| 54 52 | 
             
                  puts
         | 
| 55 | 
            -
                   | 
| 56 | 
            -
                  if check_aws_resources
         | 
| 57 | 
            -
                    account_id = Dev::Aws::Profile.new.current
         | 
| 58 | 
            -
                    account_name = Dev::Aws::Account.new.name_by_account(account_id)
         | 
| 59 | 
            -
                    LOG.info "  Current AWS Account is #{account_name} (#{account_id})\n".light_yellow
         | 
| 60 | 
            -
                    checks_to_perform.concat(Dev::EndOfLife::Aws.new.default_products)
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
                  checks_to_perform.sort_by(&:name).each(&:print_status)
         | 
| 53 | 
            +
                  product_versions.sort_by(&:name).each(&:print_status)
         | 
| 63 54 | 
             
                  puts
         | 
| 64 55 | 
             
                  raise 'found EOL versions' if product_versions.any?(&:eol)
         | 
| 65 56 | 
             
                end
         | 
| @@ -94,11 +94,23 @@ module Dev | |
| 94 94 | 
             
                  end
         | 
| 95 95 | 
             
                  # rubocop:enable Metrics/MethodLength
         | 
| 96 96 |  | 
| 97 | 
            -
                  #  | 
| 97 | 
            +
                  # Create the rake task for the eol method
         | 
| 98 98 | 
             
                  def create_eol_task!
         | 
| 99 | 
            -
                     | 
| 99 | 
            +
                    # Have to set a local variable to be accessible inside of the instance_eval block
         | 
| 100 | 
            +
                    exclude = @exclude
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                    DEV_COMMANDS_TOP_LEVEL.instance_eval do
         | 
| 103 | 
            +
                      return if exclude.include?(:eol)
         | 
| 100 104 |  | 
| 101 | 
            -
             | 
| 105 | 
            +
                      desc 'Compares the current date to the EOL date for supported resources'
         | 
| 106 | 
            +
                      task eol: %w(init ensure_aws_credentials) do
         | 
| 107 | 
            +
                        account_id = Dev::Aws::Profile.new.current
         | 
| 108 | 
            +
                        account_name = Dev::Aws::Account.new.name_by_account(account_id)
         | 
| 109 | 
            +
                        LOG.info "  Current AWS Account is #{account_name} (#{account_id})".light_yellow
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                        Dev::EndOfLife.new(product_versions: Dev::EndOfLife::Aws.new.default_products).check
         | 
| 112 | 
            +
                      end
         | 
| 113 | 
            +
                    end
         | 
| 102 114 | 
             
                  end
         | 
| 103 115 | 
             
                end
         | 
| 104 116 | 
             
              end
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require_relative 'base_interface'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Dev
         | 
| 4 | 
            +
              module Template
         | 
| 5 | 
            +
                # Class contains rake templates for managing configured certificates
         | 
| 6 | 
            +
                class Certificate < Dev::Template::BaseInterface
         | 
| 7 | 
            +
                  attr_reader :names, :email, :paths
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def initialize(names, email:, paths:, exclude: [])
         | 
| 10 | 
            +
                    @names = names
         | 
| 11 | 
            +
                    @email = email
         | 
| 12 | 
            +
                    @paths = Array(paths)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    super(exclude:)
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # Create the rake task for the generate method
         | 
| 18 | 
            +
                  def create_generate_task!
         | 
| 19 | 
            +
                    # Have to set a local variable to be accessible inside of the instance_eval block
         | 
| 20 | 
            +
                    names = @names
         | 
| 21 | 
            +
                    email = @email
         | 
| 22 | 
            +
                    paths = @paths
         | 
| 23 | 
            +
                    exclude = @exclude
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    DEV_COMMANDS_TOP_LEVEL.instance_eval do
         | 
| 26 | 
            +
                      return if exclude.include?(:generate)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      namespace :certificate do
         | 
| 29 | 
            +
                        desc 'Requests a new certificate for the configured domain using the route53 validation and deposits it in the configured paths'
         | 
| 30 | 
            +
                        task generate: %w(init_docker ensure_aws_credentials) do
         | 
| 31 | 
            +
                          Dev::Docker.new.pull_image('certbot/dns-route53', 'latest')
         | 
| 32 | 
            +
                          c = Dev::Certificate.new(names, email)
         | 
| 33 | 
            +
                          c.request
         | 
| 34 | 
            +
                          paths.each { |path| c.save(path) }
         | 
| 35 | 
            +
                        end
         | 
| 36 | 
            +
                      end
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| @@ -4,23 +4,6 @@ module Dev | |
| 4 4 | 
             
              module Template
         | 
| 5 5 | 
             
                # Class contains rake templates for managing your git project
         | 
| 6 6 | 
             
                class Git < Dev::Template::BaseInterface
         | 
| 7 | 
            -
                  # Create the rake task for cloning all defined repos
         | 
| 8 | 
            -
                  def create_clone_task!
         | 
| 9 | 
            -
                    # Have to set a local variable to be accessible inside of the instance_eval block
         | 
| 10 | 
            -
                    exclude = @exclude
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                    DEV_COMMANDS_TOP_LEVEL.instance_eval do
         | 
| 13 | 
            -
                      namespace :git do
         | 
| 14 | 
            -
                        return if exclude.include?(:clone)
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                        desc 'Make sure all repos are cloned'
         | 
| 17 | 
            -
                        task :clone do
         | 
| 18 | 
            -
                          Dev::Git.new.clone_repos
         | 
| 19 | 
            -
                        end
         | 
| 20 | 
            -
                      end
         | 
| 21 | 
            -
                    end
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 7 | 
             
                  # Create the rake task for the git checkout method
         | 
| 25 8 | 
             
                  def create_checkout_task!
         | 
| 26 9 | 
             
                    # Have to set a local variable to be accessible inside of the instance_eval block
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: firespring_dev_commands
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.1. | 
| 4 | 
            +
              version: 2.1.27.pre.alpha.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Firespring
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024-02- | 
| 11 | 
            +
            date: 2024-02-19 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -332,6 +332,7 @@ files: | |
| 332 332 | 
             
            - lib/firespring_dev_commands/bloom_growth/seat.rb
         | 
| 333 333 | 
             
            - lib/firespring_dev_commands/bloom_growth/user.rb
         | 
| 334 334 | 
             
            - lib/firespring_dev_commands/boolean.rb
         | 
| 335 | 
            +
            - lib/firespring_dev_commands/certificate.rb
         | 
| 335 336 | 
             
            - lib/firespring_dev_commands/common.rb
         | 
| 336 337 | 
             
            - lib/firespring_dev_commands/coverage/base.rb
         | 
| 337 338 | 
             
            - lib/firespring_dev_commands/coverage/cobertura.rb
         | 
| @@ -383,6 +384,7 @@ files: | |
| 383 384 | 
             
            - lib/firespring_dev_commands/target_process/user_story_history.rb
         | 
| 384 385 | 
             
            - lib/firespring_dev_commands/templates/aws.rb
         | 
| 385 386 | 
             
            - lib/firespring_dev_commands/templates/base_interface.rb
         | 
| 387 | 
            +
            - lib/firespring_dev_commands/templates/certificate.rb
         | 
| 386 388 | 
             
            - lib/firespring_dev_commands/templates/ci.rb
         | 
| 387 389 | 
             
            - lib/firespring_dev_commands/templates/config.rb
         | 
| 388 390 | 
             
            - lib/firespring_dev_commands/templates/docker/application.rb
         |