Skip to content

Commit

Permalink
Merge pull request #36 from limitusus/feature/role-max-session-duration
Browse files Browse the repository at this point in the history
Role MaxSessionDuration support
  • Loading branch information
limitusus committed Apr 2, 2018
2 parents 0bf2004 + c98769a commit 7c4f5bc
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 2 deletions.
14 changes: 13 additions & 1 deletion lib/miam/client.rb
Expand Up @@ -255,12 +255,24 @@ def walk_role(role_name, expected_attrs, actual_attrs)
log(:warn, "Role `#{role_name}`: 'path' cannot be updated", :color => :yellow)
end

updated = walk_assume_role_policy(role_name, expected_attrs[:assume_role_policy_document], actual_attrs[:assume_role_policy_document])
updated = walk_role_settings(role_name, {max_session_duration: expected_attrs[:max_session_duration]}, {max_session_duration: actual_attrs[:max_session_duration]})
updated = walk_assume_role_policy(role_name, expected_attrs[:assume_role_policy_document], actual_attrs[:assume_role_policy_document]) || updated
updated = walk_role_instance_profiles(role_name, expected_attrs[:instance_profiles], actual_attrs[:instance_profiles]) || updated
updated = walk_attached_managed_policies(:role, role_name, expected_attrs[:attached_managed_policies], actual_attrs[:attached_managed_policies]) || updated
walk_policies(:role, role_name, expected_attrs[:policies], actual_attrs[:policies]) || updated
end

def walk_role_settings(role_name, expected_settings, actual_settings)
updated = false

if expected_settings != actual_settings
@driver.update_role_settings(role_name, expected_settings, actual_settings)
updated = true
end

updated
end

def walk_assume_role_policy(role_name, expected_assume_role_policy, actual_assume_role_policy)
updated = false
expected_assume_role_policy.sort_array!
Expand Down
10 changes: 10 additions & 0 deletions lib/miam/driver.rb
Expand Up @@ -178,6 +178,7 @@ def create_role(role_name, attrs)
params = {
:role_name => role_name,
:assume_role_policy_document => encode_document(assume_role_policy_document),
:max_session_duration => attrs.fetch(:max_session_duration)
}

params[:path] = attrs[:path] if attrs[:path]
Expand All @@ -189,6 +190,7 @@ def create_role(role_name, attrs)
:assume_role_policy_document => assume_role_policy_document,
:policies => {},
:attached_managed_policies => [],
:max_session_duration => attrs.fetch(:max_session_duration),
}

new_role_attrs[:path] = attrs[:path] if attrs[:path]
Expand Down Expand Up @@ -237,6 +239,14 @@ def remove_role_from_instance_profiles(role_name, instance_profile_names)
end
end

def update_role_settings(role_name, new_settings, old_settings)
log(:info, "Update Role `#{role_name}` > Settings", :color => :green)
log(:info, Miam::Utils.diff(old_settings, new_settings, :color => @options[:color]), :color => false)
unless_dry_run do
@iam.update_role(new_settings.merge(role_name: role_name))
end
end

def update_assume_role_policy(role_name, policy_document, old_policy_document)
log(:info, "Update Role `#{role_name}` > AssumeRolePolicy", :color => :green)
log(:info, Miam::Utils.diff(old_policy_document, policy_document, :color => @options[:color]), :color => false)
Expand Down
6 changes: 5 additions & 1 deletion lib/miam/dsl/context/role.rb
Expand Up @@ -4,7 +4,7 @@ class Miam::DSL::Context::Role
def initialize(context, name, &block)
@role_name = name
@context = context.merge(:role_name => name)
@result = {:instance_profiles => [], :policies => {}, :attached_managed_policies => []}
@result = {:instance_profiles => [], :max_session_duration => 3600, :policies => {}, :attached_managed_policies => []}
instance_eval(&block)
end

Expand All @@ -22,6 +22,10 @@ def instance_profiles(*profiles)
@result[:instance_profiles].concat(profiles.map(&:to_s))
end

def max_session_duration(duration)
@result[:max_session_duration] = duration
end

def assume_role_policy_document
if @result[:assume_role_policy_document]
raise "Role `#{@role_name}` > AssumeRolePolicyDocument: already defined"
Expand Down
8 changes: 8 additions & 0 deletions lib/miam/dsl/converter.rb
Expand Up @@ -95,6 +95,8 @@ def output_role(role_name, attrs)
role #{role_name.inspect}, #{Miam::Utils.unbrace(role_options.inspect)} do
#{output_role_instance_profiles(attrs[:instance_profiles])}
#{output_role_max_session_duration(attrs[:max_session_duration])}
#{output_assume_role_policy_document(attrs[:assume_role_policy_document])}
#{output_policies(attrs[:policies])}
Expand Down Expand Up @@ -122,6 +124,12 @@ def output_instance_profiles(instance_profiles)
}.select {|i| i }.join("\n")
end

def output_role_max_session_duration(max_session_duration)
<<-EOS.strip
max_session_duration #{max_session_duration}
EOS
end

def output_assume_role_policy_document(assume_role_policy_document)
assume_role_policy_document = assume_role_policy_document.pretty_inspect
assume_role_policy_document.gsub!("\n", "\n ").strip!
Expand Down
3 changes: 3 additions & 0 deletions lib/miam/exporter.rb
Expand Up @@ -144,6 +144,8 @@ def export_roles(roles, instance_profile_roles)
instance_profiles = role.instance_profile_list.map {|i| i.instance_profile_name }
policies = export_role_policies(role)
attached_managed_policies = role.attached_managed_policies.map(&:policy_arn)
role_data = @iam.get_role(role_name: role_name).role
max_session_duration = role_data.max_session_duration

@mutex.synchronize do
instance_profiles.each do |instance_profile_name|
Expand All @@ -159,6 +161,7 @@ def export_roles(roles, instance_profile_roles)
:instance_profiles => instance_profiles,
:policies => policies,
:attached_managed_policies => attached_managed_policies,
:max_session_duration => max_session_duration,
}

progress
Expand Down
86 changes: 86 additions & 0 deletions spec/miam/update_spec.rb
Expand Up @@ -122,6 +122,7 @@
"Principal"=>{"Service"=>"ec2.amazonaws.com"},
"Action"=>"sts:AssumeRole"}]},
:instance_profiles=>["my-instance-profile"],
:max_session_duration=>3600,
:attached_managed_policies=>[],
:policies=>
{"role-policy"=>
Expand Down Expand Up @@ -888,4 +889,89 @@
expect(export).to eq expected
end
end

context 'when update role max_session_duration' do
let(:update_instance_profiles_dsl) do
<<-RUBY
user "bob", :path=>"/developer/" do
login_profile :password_reset_required=>true
groups(
"Admin",
"SES"
)
policy "S3" do
{"Statement"=>
[{"Action"=>
["s3:Get*",
"s3:List*"],
"Effect"=>"Allow",
"Resource"=>"*"}]}
end
end
user "mary", :path=>"/staff/" do
policy "S3" do
{"Statement"=>
[{"Action"=>
["s3:Get*",
"s3:List*"],
"Effect"=>"Allow",
"Resource"=>"*"}]}
end
end
group "Admin", :path=>"/admin/" do
policy "Admin" do
{"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
end
end
group "SES", :path=>"/ses/" do
policy "ses-policy" do
{"Statement"=>
[{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
end
end
role "my-role", :path=>"/any/" do
instance_profiles(
"my-instance-profile"
)
max_session_policy 43200
assume_role_policy_document do
{"Version"=>"2012-10-17",
"Statement"=>
[{"Sid"=>"",
"Effect"=>"Allow",
"Principal"=>{"Service"=>"ec2.amazonaws.com"},
"Action"=>"sts:AssumeRole"}]}
end
policy "role-policy" do
{"Statement"=>
[{"Action"=>
["s3:Get*",
"s3:List*"],
"Effect"=>"Allow",
"Resource"=>"*"}]}
end
end
instance_profile "my-instance-profile", :path=>"/profile/"
RUBY
end

subject { client }

it do
updated = apply(subject) { update_instance_profiles_dsl }
expect(updated).to be_truthy
expected[:roles]["my-role"][:max_session_duration] = 43200
expect(export).to eq expected
end
end
end

0 comments on commit 7c4f5bc

Please sign in to comment.