cucloud 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: {}
|