Class: Cumulus::IAM::IamResource

Inherits:
Object
  • Object
show all
Defined in:
lib/iam/manager/IamResource.rb

Overview

Internal: Represents the manager of a type of IamResource. Base class for groups, roles, and users.

Direct Known Subclasses

IamGroups, IamRoles, IamUsers

Constant Summary collapse

@@diff =
Proc.new do |name, diffs|
  if diffs.size > 0
     if diffs.reject(&:info_only).size > 0
      StatusCodes::set_status(StatusCodes::DIFFS)
    end
     if diffs.size == 1 and (diffs[0].type == Common::DiffChange::ADD or
      diffs[0].type == Common::DiffChange::UNMANAGED)
      puts diffs[0]
    else
      puts "#{name} has the following changes:"
      diffs.each do |diff|
        diff_string = diff.to_s.lines.map { |s| "\t#{s}" }.join
        puts diff_string
      end
    end
  end
end

Instance Method Summary collapse

Constructor Details

#initialize(iam) ⇒ IamResource

Public: Constructor

iam - the IAM client to use



92
93
94
95
# File 'lib/iam/manager/IamResource.rb', line 92

def initialize(iam)
  @iam = iam
  @migration_root = "generated"
end

Instance Method Details

#aws_resourcesObject

Public: Get resources from AWS

Returns an array of resources from AWS



56
57
58
# File 'lib/iam/manager/IamResource.rb', line 56

def aws_resources
  nil
end

#create(difference) ⇒ Object

Public: Create a resource in AWS

difference - the Diff object that contains the local differences

Returns the created resource



65
66
67
# File 'lib/iam/manager/IamResource.rb', line 65

def create(difference)
  nil
end

#diffObject

Public: Print out the diff between the local configuration and the IAMS in AWS



99
100
101
# File 'lib/iam/manager/IamResource.rb', line 99

def diff
  each_difference(local_resources, true, &@@diff)
end

#diff_one(name) ⇒ Object

Public: Print out the diff between local configuration and AWS for one resource

name - the name of the resource to diff



107
108
109
# File 'lib/iam/manager/IamResource.rb', line 107

def diff_one(name)
  each_difference({ name => one_local(name) }, false, &@@diff)
end

#empty_configObject

Public: Create an empty config object

Returns the created config object



72
73
74
# File 'lib/iam/manager/IamResource.rb', line 72

def empty_config
  nil
end

#listObject

Public: Print out a list of resources defined by local configuration.



112
113
114
# File 'lib/iam/manager/IamResource.rb', line 112

def list
  puts local_resources.map { |name, resource| name }.join(" ")
end

#local_resourcesObject

Methods to be overridden

Public: Get the local resources

Returns an array of resources



40
41
42
# File 'lib/iam/manager/IamResource.rb', line 40

def local_resources
  nil
end

#migrateObject

Public: Migrate AWS IAMs to Cumulus configuration.



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/iam/manager/IamResource.rb', line 131

def migrate
  assets = "#{@migration_root}/#{@migration_dir}"
  policies_dir = "#{@migration_root}/policies"
  statics_dir = "#{policies_dir}/static"

  if !Dir.exists?(@migration_root)
    Dir.mkdir(@migration_root)
  end
  if !Dir.exists?(assets)
    Dir.mkdir(assets)
  end
  if !Dir.exists?(policies_dir)
    Dir.mkdir(policies_dir)
  end
  if !Dir.exists?(statics_dir)
    Dir.mkdir(statics_dir)
  end

  # generate the configuration objects. This MUST be done separate from
  # writing to file, because the unifier will change the configuration objects
  # as it finds ways to unify configured attributes.
  policy_unifier = PolicyUnifier.new(statics_dir)
  configs = aws_resources.map do |resource|
    puts "Processing #{@type} #{resource.name}..."
    config = empty_config
    config.name = resource.name

    config.attached_policies = resource.attached_policies.map { |p| p.arn }

    resource.policies.each do |policy|
      statements = JSON.parse(URI.decode(policy.policy_document))["Statement"]
      statements.each { |statement| statement.delete("Sid") }
      policy_unifier.unify(config, statements, policy.name)
    end

    [config, resource]
  end

  migrate_additional(configs)
  configs = configs.map { |config, resource| config }

  # write the configuration to file
  puts "Writing configuration to file..."
  configs.each do |config|
    File.open("#{assets}/#{config.name}.json", 'w') { |f| f.write(config.json) }
  end

  puts "Done."
end

#migrate_additional(configs_to_aws) ⇒ Object

Public: When migrating, provide a config with any resource type specific data.

configs_to_aws - an array of arrays where each inner array’s first element

is the configuration generated so far, and the second
element is the corresponding aws resource


82
83
# File 'lib/iam/manager/IamResource.rb', line 82

def migrate_additional(configs_to_aws)
end

#one_local(name) ⇒ Object

Public: Get one local resource

name - the name of the resource to load

Returns one local resource



49
50
51
# File 'lib/iam/manager/IamResource.rb', line 49

def one_local(name)
  nil
end

#syncObject

Public: Sync the local configuration with the configuration in AWS. Will not delete resources that are not locally configured; also will not remove inline policies that are not locally configured.



119
120
121
# File 'lib/iam/manager/IamResource.rb', line 119

def sync
  each_difference(local_resources, true) { |name, diffs| sync_difference(name, diffs) }
end

#sync_one(name) ⇒ Object

Public: Sync the local configuration for one resource with AWS

name - the name of the resource to sync



126
127
128
# File 'lib/iam/manager/IamResource.rb', line 126

def sync_one(name)
  each_difference({ name => one_local(name) }, false) { |name, diffs| sync_difference(name, diffs) }
end

#update(resource, diffs) ⇒ Object

Public: Update a resource in AWS

resource - the resource to update diffs - the diff objects to be used when updating the resource



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/iam/manager/IamResource.rb', line 185

def update(resource, diffs)
  if diffs.size == 1 and diffs[0].type == Common::DiffChange::ADD
    if !diffs[0].local.policy.empty?
      update_policy(resource, diffs[0].local.generated_policy_name, diffs[0].local.policy)
    end
    if !diffs[0].local.attached_policies.empty?
      update_attached(resource, diffs[0].local.attached_policies, [])
    end
  else
    diffs.each do |diff|
      case diff.type
      when IamChange::POLICY
        update_policy(resource, diff.policy_name, diff.local)
      when IamChange::ATTACHED
        update_attached(resource, diff.attached, diff.detached)
      when IamChange::ADDED_POLICY
        update_policy(resource, diff.policy_name, diff.local)
      when IamChange::UNMANAGED_POLICY
        puts Colors.unmanaged("\t#{diff.policy_name} is not managed by Cumulus")
      end
    end
  end
end