cucloud 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.rubocop.yml +6 -0
- data/README.md +2 -1
- data/lib/cucloud.rb +11 -1
- data/lib/cucloud/cloud_trail_utils.rb +78 -0
- data/lib/cucloud/config_service_utils.rb +95 -0
- data/lib/cucloud/ec2_utils.rb +35 -23
- data/lib/cucloud/elb_utils.rb +5 -0
- data/lib/cucloud/iam_utils.rb +0 -3
- data/lib/cucloud/ssm_utils.rb +3 -0
- data/lib/cucloud/version.rb +1 -1
- data/lib/cucloud/vpc_utils.rb +90 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDViMDhjYmM3ZGFmYjc1ZmU4OWZmNzM5YzJkNDZhNjkzMzVmZmMzNQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MmQ0YmQ5OWI3N2RhMGZiOTkwY2IyYzY3ZmJkYzJkM2E3NzhiYTMyNw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MWU4NWQzZDM3ZmQxYzAzNWNmYzcwNzA3MjAwZDQ1ZTJhZjcyYWFhYTYxNDNl
|
10
|
+
YTZjMjBjZDQxYzRiOTczOWU3Y2E4MGUwMWQzOGFmNjhlNjRkNWZjNjE2MTM5
|
11
|
+
ZmY0NGQxZDIzMTg4MWYwZTRlMjAxMGUwMzViNjQxNjhmZGY0MmU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2Q5ZjQ4ZmU5NTZlMzYyNDc5NjM2NWQzNmI5ZDg1MDRjN2RjMTI2ZGM5ZWY4
|
14
|
+
MmJkYzU5YzM2ODExZDIwM2RmNzA1YmUwYmY4ZjU1MDRiMDFiZmY4Zjk5YjYz
|
15
|
+
MGU0NmQ1NWQxZDIwYWYzMzc3NTUyZDdkOGZhMjEyMjlkN2RmMjQ=
|
data/.rubocop.yml
CHANGED
@@ -10,6 +10,12 @@ Metrics/MethodLength:
|
|
10
10
|
Metrics/AbcSize:
|
11
11
|
Max: 50
|
12
12
|
|
13
|
+
Metrics/CyclomaticComplexity:
|
14
|
+
Max: 10
|
15
|
+
|
16
|
+
Metrics/PerceivedComplexity:
|
17
|
+
Max: 10
|
18
|
+
|
13
19
|
# disable get/set warnings - many of our methods are performing API calls and get_ seems appropriate naming
|
14
20
|
Style/AccessorMethodName:
|
15
21
|
Enabled: false
|
data/README.md
CHANGED
@@ -68,6 +68,8 @@ To install this gem onto your local machine:
|
|
68
68
|
|
69
69
|
It's helpful to reference a local copy of the gem while developing (so you can add methods to cucloud and reference them in the utility you are developing) -- see https://rossta.net/blog/how-to-specify-local-ruby-gems-in-your-gemfile.html for a recommended approach.
|
70
70
|
|
71
|
+
Development documentation is generated automatically from yard and is available at: http://www.rubydoc.info/gems/cucloud
|
72
|
+
|
71
73
|
## Contributing
|
72
74
|
|
73
75
|
Bug reports and pull requests are welcome on GitHub at https://github.com/CU-CloudCollab/cucloud_ruby. The library includes functions that have been needed somewhere already - it is in no way complete yet and we love contributions!
|
@@ -80,4 +82,3 @@ General guidance for contributions:
|
|
80
82
|
* Code should conform to Ruby Community Styleguide and pass rubocop checks using the included rubocop config (https://github.com/bbatsov/ruby-style-guide).
|
81
83
|
|
82
84
|
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
83
|
-
|
data/lib/cucloud.rb
CHANGED
@@ -7,11 +7,17 @@ module Cucloud
|
|
7
7
|
require 'cucloud/asg_utils'
|
8
8
|
require 'cucloud/ssm_utils'
|
9
9
|
require 'cucloud/iam_utils'
|
10
|
+
require 'cucloud/vpc_utils'
|
11
|
+
require 'cucloud/config_service_utils'
|
12
|
+
require 'cucloud/cloud_trail_utils'
|
10
13
|
|
14
|
+
# This is the default region API calls are made against
|
11
15
|
DEFAULT_REGION = 'us-east-1'.freeze
|
12
16
|
|
13
17
|
Aws.config = { region: DEFAULT_REGION }
|
14
18
|
|
19
|
+
# This is the public certificate for shibbloeth,
|
20
|
+
# used to check for proper account setup
|
15
21
|
CORNELL_SAML_X509 = %(<ds:X509Certificate>MIIDSDCCAjCgAwIBAgIVAOZ8NfBem6sHcI7F39sYmD/JG4YDMA0GCSqGSIb3DQEB
|
16
22
|
BQUAMCIxIDAeBgNVBAMTF3NoaWJpZHAuY2l0LmNvcm5lbGwuZWR1MB4XDTA5MTEy
|
17
23
|
MzE4NTI0NFoXDTI5MTEyMzE4NTI0NFowIjEgMB4GA1UEAxMXc2hpYmlkcC5jaXQu
|
@@ -31,10 +37,14 @@ prGI2oAv/ShPBOyrkadectHzvu5K6CL7AxNTWCSXswtfdsuxcKo65tO5TRO1hWlr
|
|
31
37
|
p36uB6TmSYl1nBmS5LgWF4EpEuODPSmy4sIV6jl1otuyI/An2dOcNqcgu7tYEXLX
|
32
38
|
C8N6DXggDWPtPRdpk96UW45huvXudpZenrcd7A==</ds:X509Certificate>).freeze
|
33
39
|
|
40
|
+
# Returns the current region the mdule is using
|
41
|
+
# @ return [string]
|
34
42
|
def region
|
35
|
-
@region
|
43
|
+
@region || @region = DEFAULT_REGION
|
36
44
|
end
|
37
45
|
|
46
|
+
# sets the current region for the module to use
|
47
|
+
# @param region [string] this is the AWS region to use, ie 'us-east-1'
|
38
48
|
def region=(region)
|
39
49
|
@region = region
|
40
50
|
Aws.config = { region: @region }
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Cucloud
|
2
|
+
# CloudTrailUtils - Utilities for Cloud Trail
|
3
|
+
class CloudTrailUtils
|
4
|
+
# Regex used to determine if a cloudtrail rule belongs to ITSO
|
5
|
+
ITSO_CLOUDTRAIL_ARN_REGEX = %r{arn:aws:cloudtrail:us-east-1:.*:trail\/.*[Ii][Tt][Ss][Oo].*}
|
6
|
+
|
7
|
+
# Constructor for CloudTrailUtils class
|
8
|
+
# @param ct_client [Aws::CloudTrail::Client] AWS CloudTrail SDK Client
|
9
|
+
def initialize(ct_client = Aws::CloudTrail::Client.new, cs_utils = Cucloud::ConfigServiceUtils.new)
|
10
|
+
## DI for testing purposes
|
11
|
+
@ct = ct_client
|
12
|
+
@cs_utils = cs_utils
|
13
|
+
@region = Cucloud.region
|
14
|
+
end
|
15
|
+
|
16
|
+
# Get all cloud trails for this region
|
17
|
+
# @return [Array<Aws::CloudTrail::Types::Trail>]
|
18
|
+
def get_cloud_trails
|
19
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/CloudTrail/Client.html#describe_trails-instance_method
|
20
|
+
@ct.describe_trails(include_shadow_trails: false).trail_list
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get all cloud trail config rules for this region
|
24
|
+
# @return [Array<Aws::ConfigService::Types::ConfigRule>]
|
25
|
+
def get_config_rules
|
26
|
+
@cs_utils.get_config_rules.select do |rule|
|
27
|
+
rule.source.source_identifier == 'CLOUD_TRAIL_ENABLED' && rule.source.owner == 'AWS'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get all cloud trails for this region
|
32
|
+
# @return [Aws::CloudTrail::Types::Trail]
|
33
|
+
def get_cloud_trail_by_name(trail_name)
|
34
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/CloudTrail/Client.html#describe_trails-instance_method
|
35
|
+
@ct.describe_trails(trail_name_list: [trail_name], include_shadow_trails: false).trail_list.first
|
36
|
+
end
|
37
|
+
|
38
|
+
# Is this trail a global trail
|
39
|
+
# @param [Aws::CloudTrail::Types::Trail]
|
40
|
+
# @return [Aws::CloudTrail::Types::GetTrailStatusResponse]
|
41
|
+
def get_trail_status(trail)
|
42
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/CloudTrail/Client.html#get_trail_status-instance_method
|
43
|
+
@ct.get_trail_status(name: trail.name)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Is this trail a global trail
|
47
|
+
# @param [Aws::CloudTrail::Types::Trail]
|
48
|
+
# @return [Boolean]
|
49
|
+
def global_trail?(trail)
|
50
|
+
trail.include_global_service_events && trail.is_multi_region_trail
|
51
|
+
end
|
52
|
+
|
53
|
+
# Is Cornell ITSO Trail?
|
54
|
+
# @param [Aws::CloudTrail::Types::Trail]
|
55
|
+
# @return [Boolean]
|
56
|
+
def cornell_itso_trail?(trail)
|
57
|
+
!(trail.trail_arn =~ ITSO_CLOUDTRAIL_ARN_REGEX).nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Is this trail logging?
|
61
|
+
# @param [Aws::CloudTrail::Types::Trail]
|
62
|
+
# @return [Boolean]
|
63
|
+
def trail_logging_active?(trail)
|
64
|
+
status = get_trail_status(trail)
|
65
|
+
status.is_logging && !status.latest_delivery_time.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
# Get hours since last delivery
|
69
|
+
# @param [Aws::CloudTrail::Types::Trail]
|
70
|
+
# @return [Integer] Hours
|
71
|
+
def hours_since_last_delivery(trail)
|
72
|
+
status = get_trail_status(trail)
|
73
|
+
return nil if status.latest_delivery_time.nil?
|
74
|
+
|
75
|
+
((Time.now - status.latest_delivery_time) / 60 / 60).to_i
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Cucloud
|
2
|
+
# ConfigServiceUtils - Utilities for Config Service
|
3
|
+
class ConfigServiceUtils
|
4
|
+
# http://docs.aws.amazon.com/general/latest/gr/rande.html#awsconfig_region
|
5
|
+
CONFIG_REGIONS = ['us-east-1',
|
6
|
+
'us-west-2',
|
7
|
+
'eu-west-1',
|
8
|
+
'eu-central-1',
|
9
|
+
'ap-northeast-1'].freeze
|
10
|
+
|
11
|
+
# Declare error classes
|
12
|
+
class UnsupportedRegionError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
# Config service is limited to a subset of regions - get currently supported list
|
16
|
+
# @return [Array<String>] Array of region names
|
17
|
+
def self.get_available_regions
|
18
|
+
CONFIG_REGIONS
|
19
|
+
end
|
20
|
+
|
21
|
+
# Constructor for ConfigServiceUtilsclass
|
22
|
+
# @param [Aws::ConfigService::Client] AWS ConfigService SDK Client
|
23
|
+
def initialize(cs_client = Aws::ConfigService::Client.new)
|
24
|
+
unless Cucloud::ConfigServiceUtils.get_available_regions.include? Cucloud.region
|
25
|
+
raise Cucloud::ConfigServiceUtils::UnsupportedRegionError,
|
26
|
+
"Region #{Cucloud.region} not yet supported by config service"
|
27
|
+
end
|
28
|
+
|
29
|
+
@cs = cs_client
|
30
|
+
@region = Cucloud.region
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get array of configuration rules for given region
|
34
|
+
# @return [Array<Aws::ConfigService::Types::ConfigRule>] Array of config rules
|
35
|
+
def get_config_rules
|
36
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/ConfigService/Client.html#describe_config_rules-instance_method
|
37
|
+
@cs.describe_config_rules.config_rules
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get specific config rule by name
|
41
|
+
# @param [String] Config rule name
|
42
|
+
# @return [Aws::ConfigService::Types::ConfigRule] Rule
|
43
|
+
def get_config_rule_by_name(rule_name)
|
44
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/ConfigService/Client.html#describe_config_rules-instance_method
|
45
|
+
@cs.describe_config_rules(
|
46
|
+
config_rule_names: [rule_name]
|
47
|
+
).config_rules.first
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get evaluation status of rule by name
|
51
|
+
# @param [String] Rule name
|
52
|
+
# @return [Types::ConfigRuleEvaluationStatus] Evaluation status of rule
|
53
|
+
def get_rule_evaluation_status_by_name(rule_name)
|
54
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/ConfigService/Client.html#describe_config_rule_evaluation_status-instance_method
|
55
|
+
@cs.describe_config_rule_evaluation_status(
|
56
|
+
config_rule_names: [rule_name]
|
57
|
+
).config_rules_evaluation_status.first
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get compliance details for a given rule by name
|
61
|
+
# @param [String] Rule name
|
62
|
+
# @return [Types::EvaluationResult]
|
63
|
+
# @TODO verify that first return is always what we want? i.e, always ordered decending by date?
|
64
|
+
def get_rule_compliance_by_name(rule_name)
|
65
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/ConfigService/Client.html#describe_config_rule_evaluation_status-instance_method
|
66
|
+
@cs.get_compliance_details_by_config_rule(
|
67
|
+
config_rule_name: rule_name
|
68
|
+
).evaluation_results.first
|
69
|
+
end
|
70
|
+
|
71
|
+
# Is this rule active?
|
72
|
+
# @param [Aws::ConfigService::Types::ConfigRule] Rule
|
73
|
+
# @return [Boolean]
|
74
|
+
def rule_active?(rule)
|
75
|
+
rule.config_rule_state == 'ACTIVE'
|
76
|
+
end
|
77
|
+
|
78
|
+
# Is this rule currently passing?
|
79
|
+
# @param [Aws::ConfigService::Types::ConfigRule] Rule
|
80
|
+
# @return [Boolean]
|
81
|
+
def rule_compliant?(rule)
|
82
|
+
get_rule_compliance_by_name(rule.config_rule_name).compliance_type == 'COMPLIANT'
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get hours since last config check invocation
|
86
|
+
# @param [Aws::ConfigService::Types::ConfigRule] Rule
|
87
|
+
# @return [Integer] Hours
|
88
|
+
def hours_since_last_run(rule)
|
89
|
+
last_run_time = get_rule_evaluation_status_by_name(rule.config_rule_name).last_successful_invocation_time
|
90
|
+
return nil if last_run_time.nil?
|
91
|
+
|
92
|
+
((Time.now - last_run_time) / 60 / 60).to_i
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/cucloud/ec2_utils.rb
CHANGED
@@ -1,68 +1,74 @@
|
|
1
1
|
module Cucloud
|
2
2
|
# EC2Utils class - anything ec2 related goes here!
|
3
3
|
class Ec2Utils
|
4
|
-
|
5
|
-
SECONDS_IN_A_DAY = 86_400
|
4
|
+
# This is the command sent to ubuntu for patching
|
6
5
|
UBUNTU_PATCH_COMMAND = 'apt-get update; apt-get -y upgrade; reboot'.freeze
|
6
|
+
# THis is the command sent to amazon linux machines for patching
|
7
7
|
AMAZON_PATCH_COMMAND = 'yum update -y; reboot & disown '.freeze
|
8
8
|
|
9
9
|
def initialize(ec2_client = Aws::EC2::Client.new, ssm_utils = Cucloud::SSMUtils.new)
|
10
|
-
## DI for testing purposes
|
11
10
|
@ec2 = ec2_client
|
12
11
|
@ssm_utils = ssm_utils
|
13
12
|
end
|
14
13
|
|
14
|
+
# Get instance information for a specific instance
|
15
15
|
def get_instance(instance)
|
16
|
-
## Get instance information for a specific instance
|
17
16
|
@ec2.describe_instances(instance_ids: [instance])
|
18
17
|
end
|
19
18
|
|
19
|
+
# Stop ec2 instance for a specific instance number. The function will wait
|
20
|
+
# until the instance has entered the stopped state.
|
21
|
+
# @param instance [String] instance id in the format of i-121231231231
|
20
22
|
def stop_instance(instance)
|
21
|
-
# Stop ec2 instance for a specific instance number. The function will wait until the instance has entered
|
22
|
-
# the stopped state.
|
23
23
|
@ec2.stop_instances(instance_ids: [instance])
|
24
24
|
end
|
25
25
|
|
26
|
+
# Start ec2 instance for a specific instance number. The function will wait
|
27
|
+
# until the instance has entered the running state.
|
28
|
+
# @param instance [String] instance id in the format of i-121231231231
|
26
29
|
def start_instance(instance)
|
27
|
-
# Start ec2 instance for a specific instance number. The function will wait until the instance has entered
|
28
|
-
# the running state.
|
29
30
|
@ec2.start_instances(instance_ids: [instance])
|
30
31
|
end
|
31
32
|
|
33
|
+
# Set the name of the instance that will be displayed in the ec2 console
|
32
34
|
def rename_instance(instance, name)
|
33
|
-
# Set the name of the instance that will be displayed in the ec2 console
|
34
35
|
end
|
35
36
|
|
37
|
+
# reboot instance
|
36
38
|
def reboot_instance(instance)
|
37
39
|
end
|
38
40
|
|
41
|
+
# Terminate ec2 instance for a specific instance number.
|
39
42
|
def delete_instance(instance)
|
40
|
-
## Terminate ec2 instance for a specific instance number.
|
41
43
|
end
|
42
44
|
|
45
|
+
# Assoications an Elastic IP adress with a specific instance number.
|
46
|
+
# @return association_id as a string in the form of eipassoc-569cd631.
|
47
|
+
# This is the link between between the
|
48
|
+
# elastic network interface and the elastic IP address.
|
43
49
|
def associate_eip(instance, allocation_id)
|
44
|
-
# Assoications an Elastic IP adress with a specific instance number.
|
45
|
-
|
46
|
-
# Return: association_id as a string in the form of eipassoc-569cd631. This is the link between between the
|
47
|
-
# elastic network interface and the elastic IP address.
|
48
50
|
end
|
49
51
|
|
52
|
+
# Create ec2 instance based on parameters provided. The function will pull
|
53
|
+
# in default information from ?????.
|
54
|
+
# @param options [hash] will be hash that will override the default
|
50
55
|
def create_instance(options)
|
51
|
-
## Create ec2 instance based on parameters provided. The function will pull in default information from ?????.
|
52
|
-
## Options will be hash that will override the default
|
53
|
-
## Default will need to be pulled from ... ??
|
54
56
|
end
|
55
57
|
|
58
|
+
# Remove private AMI
|
56
59
|
def deregister_image(image)
|
57
|
-
# Remove private AMI
|
58
60
|
end
|
59
61
|
|
62
|
+
# Find ami based on a search of Name
|
60
63
|
def find_ami(name)
|
61
|
-
# Find ami based on a search of Name
|
62
64
|
end
|
63
65
|
|
66
|
+
# Based on tag name and value, return instances
|
67
|
+
# @param tag_name [string] name of tag
|
68
|
+
# @param tag_value [string] the value of the tag
|
69
|
+
# @return [array] aws reservations see
|
70
|
+
# http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Client.html#describe_instances-instance_method
|
64
71
|
def get_instances_by_tag(tag_name, tag_value)
|
65
|
-
## Based on tag name and value, return instances
|
66
72
|
@ec2.describe_instances(filters: [
|
67
73
|
{
|
68
74
|
name: "tag:#{tag_name}",
|
@@ -71,21 +77,27 @@ module Cucloud
|
|
71
77
|
])
|
72
78
|
end
|
73
79
|
|
80
|
+
# stop instances based on a tag name and value
|
81
|
+
# @param tag_name [string] name of tag
|
82
|
+
# @param tag_value [string] the value of the tag
|
74
83
|
def stop_instances_by_tag(tag_name, tag_value)
|
75
84
|
get_instances_by_tag(tag_name, tag_value).reservations[0].instances.each do |i|
|
76
85
|
@ec2.stop_instances(instance_ids: [i.instance_id])
|
77
86
|
end
|
78
87
|
end
|
79
88
|
|
89
|
+
# start instances based on a tag name and value
|
90
|
+
# @param tag_name [string] name of tag
|
91
|
+
# @param tag_value [string] the value of the tag
|
80
92
|
def start_instances_by_tag(tag_name, tag_value)
|
81
93
|
get_instances_by_tag(tag_name, tag_value).reservations[0].instances.each do |i|
|
82
94
|
@ec2.start_instances(instance_ids: [i.instance_id])
|
83
95
|
end
|
84
96
|
end
|
85
97
|
|
86
|
-
#
|
87
|
-
#
|
88
|
-
# @
|
98
|
+
# patch instances based on a tag name and value
|
99
|
+
# @param tag_name [string] name of tag
|
100
|
+
# @param tag_value [string] the value of the tag
|
89
101
|
def instances_to_patch_by_tag(tag_name = 'auto_patch', tag_value = ['1'])
|
90
102
|
resp = get_instances_by_tag(tag_name, tag_value)
|
91
103
|
|
data/lib/cucloud/elb_utils.rb
CHANGED
@@ -5,6 +5,11 @@ module Cucloud
|
|
5
5
|
@s3 = s3
|
6
6
|
end
|
7
7
|
|
8
|
+
# Enable logging to a s3 bucket for an ELB
|
9
|
+
# @param elb_name [string] name of the elastic load balancer
|
10
|
+
# @param app_name [string] name of the application, used as prefix inside s3 bucket
|
11
|
+
# @param policy [string] IAM policy to be applied to the bucket
|
12
|
+
# @return [boolean]
|
8
13
|
def enable_logging(elb_name, app_name, policy, _elb = Aws::ElasticLoadBalancing::Client.new)
|
9
14
|
## Added by Scott Ross
|
10
15
|
## Stand alone script found here: https://github.com/CU-CloudCollab/elb-logging/
|
data/lib/cucloud/iam_utils.rb
CHANGED
@@ -59,8 +59,6 @@ module Cucloud
|
|
59
59
|
# example output: [{ key: "minimum_password_length", passes: true }]
|
60
60
|
# @param [Array<Hash>] Policy against which to audit
|
61
61
|
# @return [Array<Hash>] Results of each audit check
|
62
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
63
|
-
# disable complexity check here - doesn't seem worth breaking this function up
|
64
62
|
def audit_password_policy(audit_criteria = [])
|
65
63
|
policy_hash = get_account_password_policy.to_h
|
66
64
|
|
@@ -89,7 +87,6 @@ module Cucloud
|
|
89
87
|
|
90
88
|
audit_array
|
91
89
|
end
|
92
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
93
90
|
|
94
91
|
# Get SAML providers configured for this account
|
95
92
|
# @return [Array<Hash>] Array of hashes in form { arn: <String>, metadata: <String> }
|
data/lib/cucloud/ssm_utils.rb
CHANGED
@@ -5,6 +5,9 @@ module Cucloud
|
|
5
5
|
@ssm = ssm_client
|
6
6
|
end
|
7
7
|
|
8
|
+
# Used to send patching command to ec2 linux instance
|
9
|
+
# @param patch_instances [array] array of instance instance ids
|
10
|
+
# @param command [string] patching command to be sent
|
8
11
|
def send_patch_command(patch_instances, command)
|
9
12
|
@ssm.send_command(
|
10
13
|
instance_ids: patch_instances, # required
|
data/lib/cucloud/version.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
module Cucloud
|
2
|
+
# Utilities library for interacting with VPC
|
3
|
+
class VpcUtils
|
4
|
+
# Define utility class to hold protocol constants
|
5
|
+
# see http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
|
6
|
+
class PROTOCOL
|
7
|
+
# Protocl number for ICMP
|
8
|
+
ICMP = '1'.freeze
|
9
|
+
# Protocl number for TCP
|
10
|
+
TCP = '6'.freeze
|
11
|
+
# Protocl number for UDP
|
12
|
+
UDP = '17'.freeze
|
13
|
+
# Protocl number that denotes the use of all protocols
|
14
|
+
ALL = '-1'.freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(vpc_client = Aws::EC2::Client.new)
|
18
|
+
@vpc = vpc_client
|
19
|
+
end
|
20
|
+
|
21
|
+
# Compare NACLS in a the current region with a specified rule set
|
22
|
+
# @param rules [Array] List of ACL rules to compart with AWS
|
23
|
+
# @param skip_acl [Array] List of ACL ids to skip in comparison
|
24
|
+
# @return [Array<Hash <String, String>>]
|
25
|
+
# * resp[0].acl #=> String
|
26
|
+
# * resp[0].missing[0] #=> Array
|
27
|
+
# * resp[0].missing[0].cidr #=> String
|
28
|
+
# * resp[0]missing[0].protocol #=> String
|
29
|
+
# * resp[0]missing[0].egress #=> String
|
30
|
+
# * resp[0]missing[0].to #=> String
|
31
|
+
# * resp[0]missing[0].from #=> String
|
32
|
+
# * resp[0].additional #=> Array
|
33
|
+
# * resp[0]additional[0].cidr #=> String
|
34
|
+
# * resp[0]additional[0].protocol #=> String
|
35
|
+
# * resp[0]additional[0].egress #=> String
|
36
|
+
# * resp[0]additional[0].to #=> String
|
37
|
+
# * resp[0]additional[0].from #=> String
|
38
|
+
def compare_nacls(rules, skip_acl = [])
|
39
|
+
raise ArgumentError, 'rules is not an array' unless rules.is_a? Array
|
40
|
+
compared_rules = []
|
41
|
+
|
42
|
+
nacls = @vpc.describe_network_acls({})
|
43
|
+
|
44
|
+
nacls.network_acls.each do |acl|
|
45
|
+
next if skip_acl.include?(acl.network_acl_id)
|
46
|
+
compared_rules.push(check_acls(acl, rules))
|
47
|
+
end
|
48
|
+
compared_rules
|
49
|
+
end
|
50
|
+
|
51
|
+
# Does the current region have vpc flow logs?
|
52
|
+
# @return [boolean]
|
53
|
+
def flow_logs?
|
54
|
+
!@vpc.describe_flow_logs({}).empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# Compare ACL entries aganinst a rule set
|
60
|
+
def check_acls(acl, rules)
|
61
|
+
missing_entries = rules
|
62
|
+
additional_entries = []
|
63
|
+
|
64
|
+
acl.entries.each do |entry|
|
65
|
+
next unless entry.rule_number < 32_767
|
66
|
+
|
67
|
+
find_rule = lambda do |rule|
|
68
|
+
test = rule[:cidr] == entry.cidr_block && rule[:protocol] == entry.protocol && rule[:egress] == entry.egress
|
69
|
+
unless entry.port_range.nil?
|
70
|
+
test &= rule[:to] == entry.port_range.to && rule[:from] == entry.port_range.from
|
71
|
+
end
|
72
|
+
test
|
73
|
+
end
|
74
|
+
|
75
|
+
found_at = missing_entries.find_index(&find_rule)
|
76
|
+
|
77
|
+
if found_at
|
78
|
+
missing_entries.delete_at(found_at)
|
79
|
+
else
|
80
|
+
additional_entries.push(cidr: entry.cidr_block,
|
81
|
+
protocol: entry.protocol,
|
82
|
+
egress: entry.egress,
|
83
|
+
to: entry.port_range.nil? ? '-1' : entry.port_range.to,
|
84
|
+
from: entry.port_range.nil? ? '-1' : entry.port_range.from)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
{ acl: acl.network_acl_id, missing: missing_entries, additional: additional_entries }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sbower
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-07-
|
13
|
+
date: 2016-07-28 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws-sdk
|
@@ -149,11 +149,14 @@ files:
|
|
149
149
|
- cucloud.gemspec
|
150
150
|
- lib/cucloud.rb
|
151
151
|
- lib/cucloud/asg_utils.rb
|
152
|
+
- lib/cucloud/cloud_trail_utils.rb
|
153
|
+
- lib/cucloud/config_service_utils.rb
|
152
154
|
- lib/cucloud/ec2_utils.rb
|
153
155
|
- lib/cucloud/elb_utils.rb
|
154
156
|
- lib/cucloud/iam_utils.rb
|
155
157
|
- lib/cucloud/ssm_utils.rb
|
156
158
|
- lib/cucloud/version.rb
|
159
|
+
- lib/cucloud/vpc_utils.rb
|
157
160
|
homepage: https://github.com/CU-CloudCollab/cucloud_ruby
|
158
161
|
licenses: []
|
159
162
|
metadata: {}
|