modules/mu/clouds/aws/role.rb in cloud-mu-2.1.0beta vs modules/mu/clouds/aws/role.rb in cloud-mu-3.0.0beta
- old
+ new
@@ -15,24 +15,15 @@
module MU
class Cloud
class AWS
# A user as configured in {MU::Config::BasketofKittens::roles}
class Role < MU::Cloud::Role
- @deploy = nil
- @config = nil
- attr_reader :mu_name
- attr_reader :config
- attr_reader :cloud_id
- # @param mommacat [MU::MommaCat]: A {MU::Mommacat} object containing the deploy of which this resource is/will be a member.
- # @param kitten_cfg [Hash]: The fully parsed and resolved {MU::Config} resource descriptor as defined in {MU::Config::BasketofKittens::roles}
- def initialize(mommacat: nil, kitten_cfg: nil, mu_name: nil, cloud_id: nil)
- @deploy = mommacat
- @config = MU::Config.manxify(kitten_cfg)
- @cloud_id ||= cloud_id
- @mu_name = mu_name
- @cloud_id ||= @mu_name # should be the same
+ # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like +@vpc+, for us.
+ # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat
+ def initialize(**args)
+ super
@mu_name ||= @deploy.getResourceName(@config["name"])
end
# Called automatically by {MU::Deploy#createResources}
def create
@@ -130,12 +121,21 @@
version = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy_version(
policy_arn: arn,
version_id: desc.policy.default_version_id
)
- if version.policy_version.document != URI.encode(JSON.generate(policy.values.first), /[^a-z0-9\-]/i)
- MU.log "Updating IAM policy #{policy_name}", MU::NOTICE, details: policy.values.first
+ if version.policy_version.document != URI.encode_www_form(JSON.generate(policy.values.first), /[^a-z0-9\-]/i)
+ # Special exception- we don't want to overwrite extra rules
+ # in MuSecrets policies, because our siblings might have
+ # (will have) injected those and they should stay.
+ if policy.size == 1 and policy["MuSecrets"]
+ ext = JSON.parse(URI.decode_www_form(version.policy_version.document))
+ if (ext["Statement"][0]["Resource"] & policy["MuSecrets"]["Statement"][0]["Resource"]).sort == policy["MuSecrets"]["Statement"][0]["Resource"].sort
+ next
+ end
+ end
+ MU.log "Updating IAM policy #{policy_name}", MU::NOTICE, details: policy
update_policy(arn, policy.values.first)
MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy(policy_arn: arn)
else
desc
end
@@ -269,44 +269,59 @@
def self.purgePolicy(policy_arn, credentials)
attachments = MU::Cloud::AWS.iam(credentials: credentials).list_entities_for_policy(
policy_arn: policy_arn
)
attachments.policy_users.each { |u|
- MU::Cloud::AWS.iam(credentials: credentials).detach_user_policy(
- user_name: u.user_name,
- policy_arn: policy_arn
- )
+ begin
+ MU::Cloud::AWS.iam(credentials: credentials).detach_user_policy(
+ user_name: u.user_name,
+ policy_arn: policy_arn
+ )
+ rescue ::Aws::IAM::Errors::NoSuchEntity
+ end
}
attachments.policy_groups.each { |g|
- MU::Cloud::AWS.iam(credentials: credentials).detach_group_policy(
- group_name: g.group_name,
- policy_arn: policy_arn
- )
+ begin
+ MU::Cloud::AWS.iam(credentials: credentials).detach_group_policy(
+ group_name: g.group_name,
+ policy_arn: policy_arn
+ )
+ rescue ::Aws::IAM::Errors::NoSuchEntity
+ end
}
attachments.policy_roles.each { |r|
- MU::Cloud::AWS.iam(credentials: credentials).detach_role_policy(
- role_name: r.role_name,
- policy_arn: policy_arn
- )
+ begin
+ MU::Cloud::AWS.iam(credentials: credentials).detach_role_policy(
+ role_name: r.role_name,
+ policy_arn: policy_arn
+ )
+ rescue ::Aws::IAM::Errors::NoSuchEntity
+ end
}
versions = MU::Cloud::AWS.iam(credentials: credentials).list_policy_versions(
policy_arn: policy_arn,
).versions
versions.each { |v|
next if v.is_default_version
- MU::Cloud::AWS.iam(credentials: credentials).delete_policy_version(
- policy_arn: policy_arn,
- version_id: v.version_id
- )
+ begin
+ MU::Cloud::AWS.iam(credentials: credentials).delete_policy_version(
+ policy_arn: policy_arn,
+ version_id: v.version_id
+ )
+ rescue ::Aws::IAM::Errors::NoSuchEntity
+ end
}
# Delete the policy, unless it's one of the global canned ones owned
# by AWS
if !policy_arn.match(/^arn:aws:iam::aws:/)
- MU::Cloud::AWS.iam(credentials: credentials).delete_policy(
- policy_arn: policy_arn
- )
+ begin
+ MU::Cloud::AWS.iam(credentials: credentials).delete_policy(
+ policy_arn: policy_arn
+ )
+ rescue ::Aws::IAM::Errors::NoSuchEntity
+ end
end
end
# Does this resource type exist as a global (cloud-wide) artifact, or
# is it localized to a region/zone?
@@ -338,15 +353,29 @@
purgePolicy(policy.arn, credentials)
end
}
end
+ deleteme = []
resp = MU::Cloud::AWS.iam(credentials: credentials).list_roles(
path_prefix: "/"+MU.deploy_id+"/"
)
- if resp and resp.roles
- resp.roles.each { |r|
+ deleteme.concat(resp.roles) if resp and resp.roles
+ if flags and flags["known"]
+ resp = MU::Cloud::AWS.iam(credentials: credentials).list_roles(
+ max_items: 1000
+ )
+ if resp and resp.roles
+ resp.roles.each { |r|
+ deleteme << r if flags["known"].include?(r.role_name)
+ }
+ end
+ deleteme.uniq!
+ end
+
+ if deleteme.size > 0
+ deleteme.each { |r|
MU.log "Deleting IAM role #{r.role_name}"
if !noop
# purgePolicy won't touch roles we don't own, so gently detach
# those first
detachables = MU::Cloud::AWS.iam(credentials: credentials).list_attached_role_policies(
@@ -442,11 +471,11 @@
if entitytype == "user"
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_user_policies(
path_prefix: "/"+@deploy.deploy_id+"/",
user_name: entityname
)
- if !resp or !resp.attached_policies.map { |p| p.policy_name }.include?(p.policy_name)
+ if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
MU.log "Attaching IAM policy #{p.policy_name} to user #{entityname}", MU::NOTICE
MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_user_policy(
policy_arn: p.arn,
user_name: entityname
)
@@ -454,11 +483,11 @@
elsif entitytype == "group"
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_group_policies(
path_prefix: "/"+@deploy.deploy_id+"/",
group_name: entityname
)
- if !resp or !resp.attached_policies.map { |p| p.policy_name }.include?(p.policy_name)
+ if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
MU.log "Attaching policy #{p.policy_name} to group #{entityname}", MU::NOTICE
MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_group_policy(
policy_arn: p.arn,
group_name: entityname
)
@@ -466,10 +495,10 @@
elsif entitytype == "role"
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_role_policies(
role_name: entityname
)
- if !resp or !resp.attached_policies.map { |p| p.policy_name }.include?(p.policy_name)
+ if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
MU.log "Attaching policy #{p.policy_name} to role #{entityname}", MU::NOTICE
MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_role_policy(
policy_arn: p.arn,
role_name: entityname
)