lucid-cumulus 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +3 -0
- data/.travis.yml +11 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +202 -0
- data/README.md +41 -0
- data/autocomplete +137 -0
- data/bin/cumulus +658 -0
- data/cumulus +2 -0
- data/lib/autoscaling/AutoScaling.rb +40 -0
- data/lib/autoscaling/loader/Loader.rb +56 -0
- data/lib/autoscaling/manager/Manager.rb +360 -0
- data/lib/autoscaling/models/AlarmConfig.rb +165 -0
- data/lib/autoscaling/models/AlarmDiff.rb +172 -0
- data/lib/autoscaling/models/AutoScalingDiff.rb +178 -0
- data/lib/autoscaling/models/GroupConfig.rb +330 -0
- data/lib/autoscaling/models/PolicyConfig.rb +135 -0
- data/lib/autoscaling/models/PolicyDiff.rb +73 -0
- data/lib/autoscaling/models/ScheduledActionDiff.rb +53 -0
- data/lib/autoscaling/models/ScheduledConfig.rb +96 -0
- data/lib/aws_extensions/ec2/DhcpOptions.rb +41 -0
- data/lib/aws_extensions/ec2/Instance.rb +29 -0
- data/lib/aws_extensions/ec2/NetworkAcl.rb +25 -0
- data/lib/aws_extensions/ec2/NetworkInterface.rb +14 -0
- data/lib/aws_extensions/ec2/RouteTable.rb +26 -0
- data/lib/aws_extensions/ec2/SecurityGroup.rb +16 -0
- data/lib/aws_extensions/ec2/Subnet.rb +28 -0
- data/lib/aws_extensions/ec2/Volume.rb +24 -0
- data/lib/aws_extensions/ec2/Vpc.rb +14 -0
- data/lib/aws_extensions/ec2/VpcEndpoint.rb +11 -0
- data/lib/aws_extensions/elb/BackendServerDescription.rb +12 -0
- data/lib/aws_extensions/elb/PolicyDescription.rb +14 -0
- data/lib/aws_extensions/kinesis/StreamDescription.rb +12 -0
- data/lib/aws_extensions/route53/AliasTarget.rb +21 -0
- data/lib/aws_extensions/s3/Bucket.rb +33 -0
- data/lib/aws_extensions/s3/BucketAcl.rb +28 -0
- data/lib/aws_extensions/s3/BucketCors.rb +17 -0
- data/lib/aws_extensions/s3/BucketLifecycle.rb +21 -0
- data/lib/aws_extensions/s3/BucketLogging.rb +18 -0
- data/lib/aws_extensions/s3/BucketNotification.rb +23 -0
- data/lib/aws_extensions/s3/BucketPolicy.rb +18 -0
- data/lib/aws_extensions/s3/BucketTagging.rb +15 -0
- data/lib/aws_extensions/s3/BucketVersioning.rb +14 -0
- data/lib/aws_extensions/s3/BucketWebsite.rb +49 -0
- data/lib/aws_extensions/s3/CORSRule.rb +27 -0
- data/lib/aws_extensions/s3/ReplicationConfiguration.rb +22 -0
- data/lib/cloudfront/CloudFront.rb +83 -0
- data/lib/cloudfront/loader/Loader.rb +31 -0
- data/lib/cloudfront/manager/Manager.rb +183 -0
- data/lib/cloudfront/models/CacheBehaviorConfig.rb +237 -0
- data/lib/cloudfront/models/CacheBehaviorDiff.rb +211 -0
- data/lib/cloudfront/models/CustomOriginConfig.rb +51 -0
- data/lib/cloudfront/models/CustomOriginDiff.rb +74 -0
- data/lib/cloudfront/models/DistributionConfig.rb +183 -0
- data/lib/cloudfront/models/DistributionDiff.rb +131 -0
- data/lib/cloudfront/models/InvalidationConfig.rb +37 -0
- data/lib/cloudfront/models/OriginConfig.rb +144 -0
- data/lib/cloudfront/models/OriginDiff.rb +86 -0
- data/lib/cloudfront/models/OriginSslProtocols.rb +28 -0
- data/lib/cloudfront/models/OriginSslProtocolsDiff.rb +39 -0
- data/lib/common/BaseLoader.rb +80 -0
- data/lib/common/manager/Manager.rb +148 -0
- data/lib/common/models/Diff.rb +114 -0
- data/lib/common/models/ListChange.rb +21 -0
- data/lib/common/models/TagsDiff.rb +55 -0
- data/lib/common/models/UTCTimeSource.rb +17 -0
- data/lib/conf/Configuration.rb +365 -0
- data/lib/ec2/EC2.rb +503 -0
- data/lib/ec2/IPProtocolMapping.rb +165 -0
- data/lib/ec2/loaders/EbsLoader.rb +19 -0
- data/lib/ec2/loaders/InstanceLoader.rb +32 -0
- data/lib/ec2/managers/EbsManager.rb +176 -0
- data/lib/ec2/managers/InstanceManager.rb +509 -0
- data/lib/ec2/models/EbsGroupConfig.rb +133 -0
- data/lib/ec2/models/EbsGroupDiff.rb +48 -0
- data/lib/ec2/models/InstanceConfig.rb +202 -0
- data/lib/ec2/models/InstanceDiff.rb +95 -0
- data/lib/elb/ELB.rb +148 -0
- data/lib/elb/loader/Loader.rb +65 -0
- data/lib/elb/manager/Manager.rb +581 -0
- data/lib/elb/models/AccessLogConfig.rb +82 -0
- data/lib/elb/models/AccessLogDiff.rb +47 -0
- data/lib/elb/models/HealthCheckConfig.rb +91 -0
- data/lib/elb/models/HealthCheckDiff.rb +50 -0
- data/lib/elb/models/ListenerConfig.rb +99 -0
- data/lib/elb/models/ListenerDiff.rb +91 -0
- data/lib/elb/models/LoadBalancerConfig.rb +239 -0
- data/lib/elb/models/LoadBalancerDiff.rb +265 -0
- data/lib/iam/IAM.rb +36 -0
- data/lib/iam/loader/Loader.rb +117 -0
- data/lib/iam/manager/IamGroups.rb +98 -0
- data/lib/iam/manager/IamResource.rb +288 -0
- data/lib/iam/manager/IamRoles.rb +112 -0
- data/lib/iam/manager/IamUsers.rb +54 -0
- data/lib/iam/manager/Manager.rb +29 -0
- data/lib/iam/migration/AssumeRoleUnifier.rb +34 -0
- data/lib/iam/migration/PolicyUnifier.rb +90 -0
- data/lib/iam/models/GroupConfig.rb +40 -0
- data/lib/iam/models/IamDiff.rb +132 -0
- data/lib/iam/models/PolicyConfig.rb +67 -0
- data/lib/iam/models/ResourceWithPolicy.rb +208 -0
- data/lib/iam/models/RoleConfig.rb +53 -0
- data/lib/iam/models/StatementConfig.rb +35 -0
- data/lib/iam/models/UserConfig.rb +21 -0
- data/lib/kinesis/Kinesis.rb +94 -0
- data/lib/kinesis/loader/Loader.rb +19 -0
- data/lib/kinesis/manager/Manager.rb +206 -0
- data/lib/kinesis/models/StreamConfig.rb +75 -0
- data/lib/kinesis/models/StreamDiff.rb +58 -0
- data/lib/lambda/Lambda.rb +41 -0
- data/lib/route53/loader/Loader.rb +32 -0
- data/lib/route53/manager/Manager.rb +241 -0
- data/lib/route53/models/AliasTarget.rb +86 -0
- data/lib/route53/models/RecordConfig.rb +178 -0
- data/lib/route53/models/RecordDiff.rb +140 -0
- data/lib/route53/models/Vpc.rb +24 -0
- data/lib/route53/models/ZoneConfig.rb +156 -0
- data/lib/route53/models/ZoneDiff.rb +118 -0
- data/lib/s3/S3.rb +89 -0
- data/lib/s3/loader/Loader.rb +66 -0
- data/lib/s3/manager/Manager.rb +296 -0
- data/lib/s3/models/BucketConfig.rb +321 -0
- data/lib/s3/models/BucketDiff.rb +167 -0
- data/lib/s3/models/GrantConfig.rb +189 -0
- data/lib/s3/models/GrantDiff.rb +50 -0
- data/lib/s3/models/LifecycleConfig.rb +142 -0
- data/lib/s3/models/LifecycleDiff.rb +46 -0
- data/lib/s3/models/LoggingConfig.rb +81 -0
- data/lib/s3/models/NotificationConfig.rb +157 -0
- data/lib/s3/models/NotificationDiff.rb +62 -0
- data/lib/s3/models/ReplicationConfig.rb +133 -0
- data/lib/s3/models/ReplicationDiff.rb +60 -0
- data/lib/s3/models/WebsiteConfig.rb +107 -0
- data/lib/security/SecurityGroups.rb +39 -0
- data/lib/security/loader/Loader.rb +94 -0
- data/lib/security/manager/Manager.rb +246 -0
- data/lib/security/models/RuleConfig.rb +161 -0
- data/lib/security/models/RuleDiff.rb +72 -0
- data/lib/security/models/RuleMigration.rb +127 -0
- data/lib/security/models/SecurityGroupConfig.rb +172 -0
- data/lib/security/models/SecurityGroupDiff.rb +112 -0
- data/lib/sns/SNS.rb +40 -0
- data/lib/sqs/SQS.rb +62 -0
- data/lib/sqs/loader/Loader.rb +34 -0
- data/lib/sqs/manager/Manager.rb +128 -0
- data/lib/sqs/models/DeadLetterConfig.rb +70 -0
- data/lib/sqs/models/DeadLetterDiff.rb +35 -0
- data/lib/sqs/models/QueueConfig.rb +115 -0
- data/lib/sqs/models/QueueDiff.rb +89 -0
- data/lib/util/Colors.rb +111 -0
- data/lib/util/StatusCodes.rb +51 -0
- data/lib/vpc/loader/Loader.rb +73 -0
- data/lib/vpc/manager/Manager.rb +954 -0
- data/lib/vpc/models/AclEntryConfig.rb +150 -0
- data/lib/vpc/models/AclEntryDiff.rb +54 -0
- data/lib/vpc/models/DhcpConfig.rb +100 -0
- data/lib/vpc/models/DhcpDiff.rb +90 -0
- data/lib/vpc/models/EndpointConfig.rb +76 -0
- data/lib/vpc/models/EndpointDiff.rb +69 -0
- data/lib/vpc/models/NetworkAclConfig.rb +87 -0
- data/lib/vpc/models/NetworkAclDiff.rb +116 -0
- data/lib/vpc/models/RouteConfig.rb +82 -0
- data/lib/vpc/models/RouteDiff.rb +50 -0
- data/lib/vpc/models/RouteTableConfig.rb +92 -0
- data/lib/vpc/models/RouteTableDiff.rb +101 -0
- data/lib/vpc/models/SubnetConfig.rb +113 -0
- data/lib/vpc/models/SubnetDiff.rb +78 -0
- data/lib/vpc/models/VpcConfig.rb +173 -0
- data/lib/vpc/models/VpcDiff.rb +315 -0
- data/lucid-cumulus.gemspec +20 -0
- data/rakefile.rb +8 -0
- metadata +245 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
require "iam/loader/Loader"
|
2
|
+
require "iam/manager/IamResource"
|
3
|
+
require "iam/migration/AssumeRoleUnifier"
|
4
|
+
require "iam/models/IamDiff"
|
5
|
+
require "iam/models/RoleConfig"
|
6
|
+
require "util/Colors"
|
7
|
+
|
8
|
+
require "aws-sdk"
|
9
|
+
|
10
|
+
module Cumulus
|
11
|
+
module IAM
|
12
|
+
# Public: Manager class for IAM Roles.
|
13
|
+
class IamRoles < IamResource
|
14
|
+
|
15
|
+
def initialize(iam)
|
16
|
+
super(iam)
|
17
|
+
@type = "role"
|
18
|
+
@migration_dir = "roles"
|
19
|
+
end
|
20
|
+
|
21
|
+
def local_resources
|
22
|
+
local = {}
|
23
|
+
Loader.roles.each do |role|
|
24
|
+
local[role.name] = role
|
25
|
+
end
|
26
|
+
local
|
27
|
+
end
|
28
|
+
|
29
|
+
def one_local(name)
|
30
|
+
Loader.role(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def aws_resources
|
34
|
+
@aws_roles ||= init_aws_roles
|
35
|
+
end
|
36
|
+
|
37
|
+
# Internal: Load all the roles from AWS
|
38
|
+
#
|
39
|
+
# Returns the Array of AWS roles
|
40
|
+
def init_aws_roles
|
41
|
+
@iam.list_roles().roles.map do |role|
|
42
|
+
Aws::IAM::Role.new(role.role_name, { :client => @iam })
|
43
|
+
end
|
44
|
+
end
|
45
|
+
private :init_aws_roles
|
46
|
+
|
47
|
+
def create(difference)
|
48
|
+
# create the role
|
49
|
+
@iam.create_role({
|
50
|
+
:role_name => difference.local.name,
|
51
|
+
:assume_role_policy_document => difference.local.policy_document
|
52
|
+
})
|
53
|
+
role = Aws::IAM::Role.new(difference.local.name, { :client => @iam })
|
54
|
+
|
55
|
+
# try to create the instance profile, but if it already exists, just warn
|
56
|
+
# the user
|
57
|
+
begin
|
58
|
+
@iam.create_instance_profile({
|
59
|
+
:instance_profile_name => difference.local.name
|
60
|
+
})
|
61
|
+
rescue Aws::IAM::Errors::EntityAlreadyExists
|
62
|
+
Colors.red("Instance profile already exists")
|
63
|
+
end
|
64
|
+
|
65
|
+
# assign the role to the instance profile
|
66
|
+
instance_profile = Aws::IAM::InstanceProfile.new(difference.local.name, { :client => @iam })
|
67
|
+
instance_profile.add_role({
|
68
|
+
:role_name => difference.local.name
|
69
|
+
})
|
70
|
+
role
|
71
|
+
end
|
72
|
+
|
73
|
+
def update(resource, diffs)
|
74
|
+
super(resource, diffs)
|
75
|
+
|
76
|
+
diffs.each do |diff|
|
77
|
+
if diff.type == IamChange::POLICY_DOC
|
78
|
+
puts Colors.blue("updating assume role policy document...")
|
79
|
+
resource.assume_role_policy.update({
|
80
|
+
policy_document: diff.local.policy_document
|
81
|
+
})
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def empty_config
|
87
|
+
RoleConfig.new
|
88
|
+
end
|
89
|
+
|
90
|
+
def migrate_additional(configs_to_aws)
|
91
|
+
policy_document_dir = "#{@migration_root}/#{@migration_dir}/policy-documents"
|
92
|
+
|
93
|
+
if !Dir.exists?(policy_document_dir)
|
94
|
+
Dir.mkdir(policy_document_dir)
|
95
|
+
end
|
96
|
+
|
97
|
+
unifier = AssumeRoleUnifier.new(
|
98
|
+
policy_document_dir,
|
99
|
+
&Proc.new { |c, v| c.policy_document = v }
|
100
|
+
)
|
101
|
+
configs_to_aws.map do |config, resource|
|
102
|
+
unifier.unify(
|
103
|
+
config,
|
104
|
+
URI.unescape(resource.assume_role_policy_document),
|
105
|
+
config.name
|
106
|
+
)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "iam/loader/Loader"
|
2
|
+
require "iam/manager/IamResource"
|
3
|
+
require "iam/models/UserConfig"
|
4
|
+
|
5
|
+
require "aws-sdk"
|
6
|
+
|
7
|
+
module Cumulus
|
8
|
+
module IAM
|
9
|
+
# Public: Manager class for IAM Users
|
10
|
+
class IamUsers < IamResource
|
11
|
+
|
12
|
+
def initialize(iam)
|
13
|
+
super(iam)
|
14
|
+
@type = "user"
|
15
|
+
@migration_dir = "users"
|
16
|
+
end
|
17
|
+
|
18
|
+
def local_resources
|
19
|
+
local = {}
|
20
|
+
Loader.users.each do |user|
|
21
|
+
local[user.name] = user
|
22
|
+
end
|
23
|
+
local
|
24
|
+
end
|
25
|
+
|
26
|
+
def one_local(name)
|
27
|
+
Loader.user(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def aws_resources
|
31
|
+
@aws_users ||= init_aws_users
|
32
|
+
end
|
33
|
+
|
34
|
+
def init_aws_users
|
35
|
+
@iam.list_users().users.map do |user|
|
36
|
+
Aws::IAM::User.new(user.user_name, { :client => @iam })
|
37
|
+
end
|
38
|
+
end
|
39
|
+
private :init_aws_users
|
40
|
+
|
41
|
+
def create(difference)
|
42
|
+
@iam.create_user({
|
43
|
+
:user_name => difference.local.name
|
44
|
+
})
|
45
|
+
Aws::IAM::User.new(difference.local.name, { :client => @iam })
|
46
|
+
end
|
47
|
+
|
48
|
+
def empty_config
|
49
|
+
UserConfig.new
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "conf/Configuration"
|
2
|
+
require "iam/manager/IamGroups"
|
3
|
+
require "iam/manager/IamRoles"
|
4
|
+
require "iam/manager/IamUsers"
|
5
|
+
|
6
|
+
require "aws-sdk"
|
7
|
+
|
8
|
+
module Cumulus
|
9
|
+
module IAM
|
10
|
+
|
11
|
+
# Public: The main class for the IAM management module.
|
12
|
+
class Manager
|
13
|
+
|
14
|
+
attr_reader :groups
|
15
|
+
attr_reader :roles
|
16
|
+
attr_reader :users
|
17
|
+
|
18
|
+
# Public: Constructor
|
19
|
+
def initialize
|
20
|
+
iam = Aws::IAM::Client.new(Configuration.instance.client)
|
21
|
+
|
22
|
+
@groups = IamGroups.new(iam)
|
23
|
+
@roles = IamRoles.new(iam)
|
24
|
+
@users = IamUsers.new(iam)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Cumulus
|
2
|
+
module IAM
|
3
|
+
# Public: A class that keeps track of strings, writing them to file and unifying
|
4
|
+
# them if they are identical. Specifically, this is use for the assume role
|
5
|
+
# document on roles
|
6
|
+
class AssumeRoleUnifier
|
7
|
+
# Public: Constructor.
|
8
|
+
#
|
9
|
+
# dir - the directory to write assets to
|
10
|
+
# save - a function that will save a value to a config. Takes the value and
|
11
|
+
# the config as paramters.
|
12
|
+
def initialize(dir, &save)
|
13
|
+
@dir = dir
|
14
|
+
@strings = {}
|
15
|
+
@save = save
|
16
|
+
end
|
17
|
+
|
18
|
+
# Public: Unify a string with any previous instances of the string
|
19
|
+
#
|
20
|
+
# config - the config object that the string should belong to
|
21
|
+
# s - the string to unify
|
22
|
+
# name - the name of the file this string should be saved to if needed
|
23
|
+
def unify(config, s, name)
|
24
|
+
if !@strings.has_key?(s)
|
25
|
+
File.open("#{@dir}/#{name}", 'w') { |f| f.write(s) }
|
26
|
+
@strings[s] = name
|
27
|
+
@save.call(config, name)
|
28
|
+
else
|
29
|
+
@save.call(config, @strings[s])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Cumulus
|
2
|
+
module IAM
|
3
|
+
# Public: A class that keeps track of policy statements, determining when to put
|
4
|
+
# a policy into the inline definition of the resource, or to create a static
|
5
|
+
# policy that can apply to multiple resources. It does this by keeping track of
|
6
|
+
# policies that it's seen before, and putting everything into inlines. When it
|
7
|
+
# sees something for the second time, it will remove the policy from the first
|
8
|
+
# resource's inlines, and creates a static policy definition.
|
9
|
+
class PolicyUnifier
|
10
|
+
|
11
|
+
# the following inner classes are used to keep track of whether we've seen
|
12
|
+
# a policy before. `SingleInstance` and `MultipleInstances` both extend
|
13
|
+
# `Instance`, as both of them have a `name` attribute.
|
14
|
+
class Instance
|
15
|
+
attr_reader :name
|
16
|
+
def initialize(name)
|
17
|
+
@name = name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class SingleInstance < Instance
|
22
|
+
attr_reader :config
|
23
|
+
def initialize(config, name)
|
24
|
+
super(name)
|
25
|
+
@config = config
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class MultipleInstances < Instance
|
30
|
+
end
|
31
|
+
|
32
|
+
# Public: Constructor
|
33
|
+
#
|
34
|
+
# dir - the directory to write static policies to
|
35
|
+
def initialize(dir)
|
36
|
+
@dir = dir
|
37
|
+
@policies = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Public: Unify a particular policy for a configuration object. If `policy`
|
41
|
+
# has not been encountered before, it will be put into the config's inlines,
|
42
|
+
# but if it has, it will be written to static and added to the static array
|
43
|
+
# of the configuration. Will also go back and fix the inlines for the first
|
44
|
+
# time `policy` was encountered.
|
45
|
+
#
|
46
|
+
# config - the config object to change
|
47
|
+
# policy - the policy to unify
|
48
|
+
# name - the name of the file to write, if needed
|
49
|
+
def unify(config, policy, name)
|
50
|
+
# if we haven't seen the policy before, add it to the inlines
|
51
|
+
if !@policies.has_key?(policy)
|
52
|
+
@policies[policy] = SingleInstance.new(config, name)
|
53
|
+
config.inlines << policy
|
54
|
+
else
|
55
|
+
case @policies[policy]
|
56
|
+
# if we've only seen the policy once before, write it to file and fix the
|
57
|
+
# previous configuration that had the policy
|
58
|
+
when SingleInstance
|
59
|
+
single = @policies[policy]
|
60
|
+
|
61
|
+
# write to file, checking for naming conflicts
|
62
|
+
file = "#{@dir}/#{single.name}"
|
63
|
+
contents = JSON.pretty_generate(policy)
|
64
|
+
if File.exists?(file)
|
65
|
+
original_contents = File.read(file)
|
66
|
+
if original_contents != contents
|
67
|
+
file = "#{file}-#{single.config.name}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
File.open(file, 'w') { |f| f.write(contents) }
|
71
|
+
file = file[(file.rindex("/") + 1)..-1]
|
72
|
+
|
73
|
+
# update the config objects
|
74
|
+
single.config.inlines.delete(policy)
|
75
|
+
single.config.statics << file
|
76
|
+
config.statics << file
|
77
|
+
@policies[policy] = MultipleInstances.new(file)
|
78
|
+
|
79
|
+
# if the policy has already been written to file, we just use the static
|
80
|
+
# in the configuration
|
81
|
+
when MultipleInstances
|
82
|
+
multiple = @policies[policy]
|
83
|
+
config.statics << multiple.name
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "iam/models/IamDiff"
|
2
|
+
require "iam/models/ResourceWithPolicy"
|
3
|
+
require "util/Colors"
|
4
|
+
|
5
|
+
module Cumulus
|
6
|
+
module IAM
|
7
|
+
# Public: Represents a config file for a group
|
8
|
+
class GroupConfig < ResourceWithPolicy
|
9
|
+
|
10
|
+
attr_accessor :users
|
11
|
+
|
12
|
+
# Public: Constructor
|
13
|
+
#
|
14
|
+
# name - the name of the group
|
15
|
+
# json - the Hash containing the JSON configuration for this GroupConfig, if
|
16
|
+
# nil, this will be an "empty GroupConfig"
|
17
|
+
def initialize(name = nil, json = nil)
|
18
|
+
super(name, json)
|
19
|
+
@type = "group"
|
20
|
+
@users = json["users"] unless json.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
# override diff to check for changes in users
|
24
|
+
def diff(aws_resource)
|
25
|
+
differences = super(aws_resource)
|
26
|
+
|
27
|
+
aws_users = aws_resource.users.map { |user| user.name }
|
28
|
+
new_users = @users.select { |local| !aws_users.include?(local) }
|
29
|
+
unmanaged = aws_users.select { |aws| !@users.include?(aws) }
|
30
|
+
|
31
|
+
if !unmanaged.empty? or !new_users.empty?
|
32
|
+
differences << IamDiff.users(new_users, unmanaged)
|
33
|
+
end
|
34
|
+
|
35
|
+
differences
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require "common/models/Diff"
|
2
|
+
require "util/Colors"
|
3
|
+
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module Cumulus
|
7
|
+
module IAM
|
8
|
+
# Public: The types of changes that can be made to IAM resources
|
9
|
+
module IamChange
|
10
|
+
include Common::DiffChange
|
11
|
+
|
12
|
+
ADDED_POLICY = Common::DiffChange::next_change_id
|
13
|
+
ATTACHED = Common::DiffChange::next_change_id
|
14
|
+
POLICY = Common::DiffChange::next_change_id
|
15
|
+
POLICY_DOC = Common::DiffChange::next_change_id
|
16
|
+
UNMANAGED_POLICY = Common::DiffChange::next_change_id
|
17
|
+
USER = Common::DiffChange::next_change_id
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: Represents a single difference between local configuration and AWS
|
21
|
+
# configuration of an IAM resource
|
22
|
+
class IamDiff < Common::Diff
|
23
|
+
include IamChange
|
24
|
+
|
25
|
+
attr_accessor :added_users
|
26
|
+
attr_accessor :attached
|
27
|
+
attr_accessor :policy_name
|
28
|
+
attr_accessor :removed_users
|
29
|
+
attr_accessor :detached
|
30
|
+
|
31
|
+
# Public: Create an IamDiff that represents an unmanaged policy
|
32
|
+
#
|
33
|
+
# policy_name - the name of the policy that is unmanaged
|
34
|
+
#
|
35
|
+
# Returns an IamDiff representing the changes
|
36
|
+
def self.unmanaged_policy(policy_name)
|
37
|
+
diff = IamDiff.new(UNMANAGED_POLICY)
|
38
|
+
diff.policy_name = policy_name
|
39
|
+
diff
|
40
|
+
end
|
41
|
+
|
42
|
+
# Public: Create an IamDiff that represents an added policy
|
43
|
+
#
|
44
|
+
# policy_name - the name of the policy that is added
|
45
|
+
# config - the configuration for the policy
|
46
|
+
#
|
47
|
+
# Returns an IamDiff representing the changes
|
48
|
+
def self.added_policy(policy_name, config)
|
49
|
+
diff = IamDiff.new(ADDED_POLICY, nil, config)
|
50
|
+
diff.policy_name = policy_name
|
51
|
+
diff
|
52
|
+
end
|
53
|
+
|
54
|
+
# Public: Create an IamDiff to represent the changes in users for an IAM group
|
55
|
+
#
|
56
|
+
# added - the added users
|
57
|
+
# removed - the removed users
|
58
|
+
#
|
59
|
+
# Returns an IamDiff representing those changes
|
60
|
+
def self.users(added, removed)
|
61
|
+
diff = IamDiff.new(USER)
|
62
|
+
diff.added_users = added
|
63
|
+
diff.removed_users = removed
|
64
|
+
diff
|
65
|
+
end
|
66
|
+
|
67
|
+
# Public: Create an IamDiff to represent changes in attached policies
|
68
|
+
#
|
69
|
+
# added - the added attached policies
|
70
|
+
# removed - the removed attached policies
|
71
|
+
#
|
72
|
+
# Returns an IamDiff representing those changes
|
73
|
+
def self.attached(added, removed)
|
74
|
+
diff = IamDiff.new(ATTACHED)
|
75
|
+
diff.attached = added
|
76
|
+
diff.detached = removed
|
77
|
+
diff
|
78
|
+
end
|
79
|
+
|
80
|
+
def diff_string
|
81
|
+
case @type
|
82
|
+
when ADDED_POLICY
|
83
|
+
Colors.added("Policy #{@policy_name} will be created.")
|
84
|
+
when ATTACHED
|
85
|
+
lines = ["Attached policies:"]
|
86
|
+
lines << @attached.map { |arn| Colors.added("\t#{arn}") }
|
87
|
+
lines << @detached.map { |arn| Colors.removed("\t#{arn}") }
|
88
|
+
lines.flatten.join("\n")
|
89
|
+
when POLICY
|
90
|
+
lines = ["Policy differences:"]
|
91
|
+
locals = @local.as_hash["Statement"]
|
92
|
+
|
93
|
+
@aws.each do |aws|
|
94
|
+
if !locals.include?(aws)
|
95
|
+
lines << "\tAWS:\t#{Colors.aws_changes(aws.to_json)}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
locals.each do |local|
|
100
|
+
if !@aws.include?(local)
|
101
|
+
lines << "\tLocal:\t#{Colors.local_changes(local.to_json)}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
lines.join("\n")
|
106
|
+
when POLICY_DOC
|
107
|
+
aws = JSON.parse(URI.unescape(@aws.assume_role_policy_document)).to_s
|
108
|
+
[
|
109
|
+
"Assume role policy document:",
|
110
|
+
Colors.aws_changes("\tAWS -\t#{aws}"),
|
111
|
+
Colors.local_changes("\tLocal -\t#{@local.one_line_policy_document}")
|
112
|
+
].join("\n")
|
113
|
+
when UNMANAGED_POLICY
|
114
|
+
Colors.unmanaged("Policy #{@policy_name} is not managed by Cumulus")
|
115
|
+
when USER
|
116
|
+
lines = ["User differences:"]
|
117
|
+
lines << @added_users.map { |u| Colors.added("\t#{u}") }
|
118
|
+
lines << @removed_users.map { |u| Colors.removed("\t#{u}") }
|
119
|
+
lines.flatten.join("\n")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def asset_type
|
124
|
+
"IAM resource"
|
125
|
+
end
|
126
|
+
|
127
|
+
def aws_name
|
128
|
+
@aws.name
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|