class Cumulus::SecurityGroups::Manager
Public Class Methods
Cumulus::Common::Manager::new
# File lib/security/manager/Manager.rb, line 15 def initialize super() @ec2 = Aws::EC2::Client.new(Configuration.instance.client) end
Public Instance Methods
# File lib/security/manager/Manager.rb, line 80 def added_diff(local) SecurityGroupDiff.added(local) end
Hash the aws security groups using the vpc and security group name
# File lib/security/manager/Manager.rb, line 72 def aws_resources @aws_resources ||= Hash[SecurityGroups::security_groups.map { |sg| [sg.vpc_group_name, sg] }] end
# File lib/security/manager/Manager.rb, line 88 def create(local) result = @ec2.create_security_group({ group_name: local.name.split("/").last, description: local.description, vpc_id: local.vpc_id, }) security_group_id = result.group_id update_tags(security_group_id, local.tags, {}) update_inbound(local.vpc_id, security_group_id, local.inbound, []) allow_all_rule = RuleConfig.allow_all allow_all_outbound = Configuration.instance.security.outbound_default_all_allowed or local.outbound.find { |g| g.hash == allow_all_rule.hash } outbound_remove = if allow_all_outbound [] else [allow_all_rule] end outbound_add = local.outbound.reject { |g| g.hash == allow_all_rule.hash } update_outbound(local.vpc_id, security_group_id, outbound_add, outbound_remove) end
# File lib/security/manager/Manager.rb, line 84 def diff_resource(local, aws) local.diff(aws) end
# File lib/security/manager/Manager.rb, line 67 def local_resources @local_resources ||= Hash[Loader.groups.map { |local| [local.name, local] }] end
Public: Migrate AWS Security Groups to Cumulus
configuration.
# File lib/security/manager/Manager.rb, line 21 def migrate groups_dir = "#{@migration_root}/security-groups" if !Dir.exists?(@migration_root) Dir.mkdir(@migration_root) end if !Dir.exists?(groups_dir) Dir.mkdir(groups_dir) end # Make the directories needed for resources that require it aws_resources.map do |name, _| parts = name.partition("/") if parts.length > 1 "#{groups_dir}/#{parts.first}" end end.uniq.compact.each do |dir| if !Dir.exists?(dir) Dir.mkdir(dir) end end aws_resources.each_value do |resource| puts "Processing #{resource.vpc_group_name}..." config = SecurityGroupConfig.new(resource.vpc_group_name, resource.vpc_id) config.populate!(resource) puts "Writing #{resource.vpc_group_name} configuration to file..." File.open("#{groups_dir}/#{config.name}.json", "w") { |f| f.write(config.pretty_json) } end File.open("#{@migration_root}/subnets.json", "w") do |f| f.write(JSON.pretty_generate({ "all" => ["0.0.0.0/0"] })) end puts Colors.blue("IP addresses for inbound and outbound rules have been left as is in each individual security group, except in the case of 0.0.0.0/0.") puts Colors.blue("0.0.0.0/0 has been renamed to 'all' and is referenced as such in security group definitions.") puts Colors.blue("See subnets.json to see the definition of the 'all' subnet group.") end
# File lib/security/manager/Manager.rb, line 63 def resource_name "Security Group" end
# File lib/security/manager/Manager.rb, line 76 def unmanaged_diff(aws) SecurityGroupDiff.unmanaged(aws) end
# File lib/security/manager/Manager.rb, line 113 def update(local, diffs) diffs_by_type = diffs.group_by(&:type) if diffs_by_type.include?(SecurityGroupChange::DESCRIPTION) puts "\tUnfortunately, AWS's SDK does not allow updating the description." else diffs.each do |diff| case diff.type when SecurityGroupChange::TAGS update_tags(diff.aws.group_id, diff.tags_to_add, diff.tags_to_remove) when SecurityGroupChange::INBOUND update_inbound(local.vpc_id, diff.aws.group_id, diff.added_inbounds, diff.removed_inbounds) when SecurityGroupChange::OUTBOUND update_outbound(local.vpc_id, diff.aws.group_id, diff.added_outbounds, diff.removed_outbounds) end end end end
Private Instance Methods
Internal: Update the inbound rules associated with a security group.
vpc_id - - the id of the vpc the security groups are in security_group_id - the id of the security group add - the inbound rules to associate with the security group remove - the inbound rules to dissociate from the security group
# File lib/security/manager/Manager.rb, line 162 def update_inbound(vpc_id, security_group_id, add, remove) update_rules( vpc_id, security_group_id, add, remove, { :type => "inbound", :add_action => @ec2.method(:authorize_security_group_ingress), :remove_action => @ec2.method(:revoke_security_group_ingress) } ) end
Internal: Update the outbound rules associated with a security group.
vpc_id - - the id of the vpc the security groups are in security_group_id - the id of the security group add - the outbound rules to associate with the security group remove - the outbound rules to associate with the security group
# File lib/security/manager/Manager.rb, line 183 def update_outbound(vpc_id, security_group_id, add, remove) update_rules( vpc_id, security_group_id, add, remove, { :type => "outbound", :add_action => @ec2.method(:authorize_security_group_egress), :remove_action => @ec2.method(:revoke_security_group_egress) } ) end
Internal: Update rules associated with a security group. Called by inbound and outbound.
vpc_id - - the id of the vpc the security groups are in security_group_id - the id of the security group add - the rules to associate with the security group remove - the rules to remove from the security group options - a hash containing options about the operation to run. Should contain:
- type - a string representing the type of rules to process - add_action - the client method to call to add rules - remove_action - the client method to call to remove rules
# File lib/security/manager/Manager.rb, line 208 def update_rules(vpc_id, security_group_id, add, remove, options) if !add.empty? puts Colors.blue("\tadding #{options[:type]} rules...") options[:add_action].call({ group_id: security_group_id, ip_permissions: add.map do |added| missing_group = added.security_groups.find do |s| !SecurityGroups::vpc_security_groups[vpc_id].include?(s) end if missing_group puts Colors.red("\t\tNo such security group: #{missing_group}. Security group not added.") end added.to_aws(vpc_id) end }) end if !remove.empty? puts Colors.blue("\tremoving #{options[:type]} rules...") options[:remove_action].call({ group_id: security_group_id, ip_permissions: remove.map do |removed| missing_group = removed.security_groups.find do |s| !SecurityGroups::vpc_security_groups[vpc_id].include?(s) end if missing_group puts Colors.red("\t\tNo such security group: #{missing_group}. Security group not removed.") end removed.to_aws(vpc_id) end }) end end