Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ORCH-11235 | Port upstream kms tagging changes to 2.0.0.beta6 #303

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/moonshot/commands/create.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# frozen_string_literal: true

require_relative 'parameter_arguments'
require_relative 'tag_arguments'
require_relative 'show_all_events_option'
require_relative 'parent_stack_option'

module Moonshot
module Commands
class Create < Moonshot::Command
include ParameterArguments
include TagArguments
include ShowAllEventsOption
include ParentStackOption

Expand All @@ -21,6 +29,10 @@ def parser
parser.on('--version VERSION_NAME', 'Version for initial deployment. If unset, a new development build is created from the local directory') do |v| # rubocop:disable LineLength
@version = v
end

parser.on('--template-file=FILE', 'Override the path to the CloudFormation template.') do |v|
Moonshot.config.template_file = v
end
end

def execute
Expand Down
18 changes: 18 additions & 0 deletions lib/moonshot/commands/tag_arguments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Moonshot
module Commands
module TagArguments
def parser
parser = super

parser.on('--tag KEY=VALUE', '-TKEY=VALUE', 'Specify Stack Tag on the command line') do |v|
data = v.split('=', 2)
unless data.size == 2
raise "Invalid tag format '#{v}', expected KEY=VALUE (e.g. MyStackTag=12)"
end

Moonshot.config.extra_tags << { key: data[0], value: data[1] }
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/moonshot/commands/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Moonshot
module Commands
class Update < Moonshot::Command
include ParameterArguments
include TagArguments
include ShowAllEventsOption
include ParentStackOption

Expand Down
2 changes: 2 additions & 0 deletions lib/moonshot/controller_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class ControllerConfig
attr_accessor :ssh_config
attr_accessor :ssh_instance
attr_accessor :template_s3_bucket
attr_accessor :extra_tags

def initialize
@default_parameter_source = AskUserSource.new
Expand All @@ -42,6 +43,7 @@ def initialize
@project_root = Dir.pwd
@show_all_stack_events = false
@ssh_config = SSHConfig.new
@extra_tags = []

@dev_build_name_proc = lambda do |c|
['dev', c.app_name, c.environment_name, Time.now.to_i].join('/')
Expand Down
36 changes: 24 additions & 12 deletions lib/moonshot/stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,30 @@ class Stack # rubocop:disable ClassLength
attr_reader :app_name
attr_reader :name

class << self
def generate_name(config)
[config.app_name, config.environment_name].join('-')
end

def make_tags(config)
default_tags = [
{ key: 'moonshot_application', value: config.app_name },
{ key: 'moonshot_environment', value: config.environment_name },
]
name = generate_name(config)

if config.additional_tag
default_tags << { key: config.additional_tag, value: name }
end

default_tags + config.extra_tags
end
end

def initialize(config)
@config = config
@ilog = config.interactive_logger
@name = [@config.app_name, @config.environment_name].join('-')
@name = self.class.generate_name(@config)

yield @config if block_given?
end
Expand Down Expand Up @@ -225,7 +245,8 @@ def new_change_set
description: "Moonshot update command for application '#{Moonshot.config.app_name}'",
stack_name: @name,
capabilities: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM),
parameters: @config.parameters.values.map(&:to_cf)
parameters: @config.parameters.values.map(&:to_cf),
tags: make_tags
}
if @config.template_s3_bucket
parameters[:template_url] = upload_template_to_s3
Expand Down Expand Up @@ -284,16 +305,7 @@ def wait_for_stack_state(wait_target, past_tense_verb)
end

def make_tags
default_tags = [
{ key: 'moonshot_application', value: @config.app_name },
{ key: 'moonshot_environment', value: @config.environment_name }
]

if @config.additional_tag
default_tags << { key: @config.additional_tag, value: @name }
end

default_tags
self.class.make_tags(@config)
end

def format_event(event)
Expand Down
4 changes: 3 additions & 1 deletion lib/plugins/encrypted_parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ def find_or_create_kms_key
Moonshot.config.parameters[@kms_key_parameter_name].set(key_arn)
s.success "Created a new KMS Key for #{@kms_key_parameter_name.blue}!"
else
key_arn = KmsKey.new(Moonshot.config.parameters[@kms_key_parameter_name].value).arn
kms=KmsKey.new(Moonshot.config.parameters[@kms_key_parameter_name].value)
key_arn = kms.arn
kms.update
s.success "Using existing KMS Key for #{@kms_key_parameter_name.blue}!"
end
end
Expand Down
29 changes: 24 additions & 5 deletions lib/plugins/encrypted_parameters/kms_key.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
# frozen_string_literal: true
require_relative '../../moonshot/stack.rb'

module Moonshot
module Plugins
class EncryptedParameters
# Class that manages KMS keys in AWS.
class KmsKey
attr_reader :arn
class << self
def create
standard_tags = stack_tags
resp = Aws::KMS::Client.new.create_key({
tags: standard_tags, # An array of tags.
})
arn = resp.key_metadata.arn
new(arn)
end

def stack_tags
tags = Moonshot::Stack.make_tags(Moonshot.config)
tags.map { |tag| { tag_key: tag[:key], tag_value: tag[:value] } }
end
end

def initialize(arn)
@arn = arn
@kms_client = Aws::KMS::Client.new
end

def self.create
resp = Aws::KMS::Client.new.create_key
arn = resp.key_metadata.arn

new(arn)
def update
standard_tags = self.class.stack_tags
@kms_client.tag_resource({
key_id: @arn, # arn of the CMK being tagged
tags: standard_tags, # An array of tags.
})
end

def delete
Expand Down
16 changes: 16 additions & 0 deletions spec/moonshot/commands/create_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@
end
end

extra_tags = {
%w(-T Key=Value -T OtherKey=OtherValue) =>
[{ key: 'Key', value: 'Value' }, { key: 'OtherKey', value: 'OtherValue' }],
%w(-TKey=ValueWith=Equals) => [{ key: 'Key', value: 'ValueWith=Equals' }],
%w(--tag Key=Value --tag OtherKey=OtherValue) =>
[{ key: 'Key', value: 'Value' }, { key: 'OtherKey', value: 'OtherValue' }]
}

extra_tags.each do |input, expected|
it "Should process #{input} correctly" do
op = subject.parser
op.parse(input)
expect(Moonshot.config.extra_tags).to match(expected)
end
end

it 'should handle version and deploy correctly' do
op = subject.parser
op.parse(%w(--version 1.2.3 --no-deploy -P Key=Value))
Expand Down
16 changes: 16 additions & 0 deletions spec/moonshot/commands/update_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,20 @@
expect(Moonshot.config.parameter_overrides).to match(expected)
end
end

extra_tags = {
%w(-T Key=Value -T OtherKey=OtherValue) =>
[{ key: 'Key', value: 'Value' }, { key: 'OtherKey', value: 'OtherValue' }],
%w(-TKey=ValueWith=Equals) => [{ key: 'Key', value: 'ValueWith=Equals' }],
%w(--tag Key=Value --tag OtherKey=OtherValue) =>
[{ key: 'Key', value: 'Value' }, { key: 'OtherKey', value: 'OtherValue' }]
}

extra_tags.each do |input, expected|
it "Should process #{input} correctly" do
op = subject.parser
op.parse(input)
expect(Moonshot.config.extra_tags).to match(expected)
end
end
end
25 changes: 25 additions & 0 deletions spec/moonshot/stack_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,31 @@
subject.create
end
end

context 'when has extra tags' do
let(:expected_create_stack_options) do
{
tags: [
{ key: 'moonshot_application', value: 'rspec-app' },
{ key: 'moonshot_environment', value: 'staging' },
{ key: 'tag1', value: 'A' },
{ key: 'tag2', value: 'B' }
]
}
end

before do
config.extra_tags << { key: 'tag1', value: 'A' }
config.extra_tags << { key: 'tag2', value: 'B' }
end

it 'should call CreateStack, then wait for completion' do
expect(s3_client).not_to receive(:put_object)
expect(cf_client).to receive(:create_stack)
.with(hash_including(expected_create_stack_options))
subject.create
end
end
end
end

Expand Down