cucloud 0.6.1 → 0.7.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTI1MTYwMTY3YzBhZDI0YjA5YjBjM2M0NDc3MGMzYjA1YzAwZDZjZQ==
4
+ MmNkOGQyOTA4NGFiNzQ3NmNmMWIxNTMwNDM1MTQwMzFiZjRmYTZkMw==
5
5
  data.tar.gz: !binary |-
6
- NTI0MjVhN2M1MGE0MDE2Mjc1NmNlZTIzZWYyZmVhNDJjZDRhYTM0Mg==
6
+ MWVjZjQzODJiNGFjNWVmYTEzYzQzMDFlMjBlNDZhMzE4OTgwYWY5OQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Mzk2YjU0MTNlZDJmMWRiMmJlOGYxNzUxZGI1MGVjMzRhNDFjZGJiNDY1NjI3
10
- MTg3YjhkM2I2MzhmMjI0YjZhMDBmN2FkZGMzMDFlYzBlNWQ4Yjc1ZTgzMTcy
11
- MjQ2OWQ3NzcwYWRmOWVmODg5ZTEwMzc5NTM0YzBiOTBhYzYzMmY=
9
+ YTBkMzBhOGI2YWRlMGE0NzI5YzM2ZDc5OTc3NGNkOTgzNjFmMDg5NjU0ZDY2
10
+ NDA0Y2E2ODI2ZTc0NTM4NzlmZjRkZTUwMTg0YTVhOGFmNDczODAzM2U0ZDg1
11
+ NTU1ZTM1OWUxY2Q5Yjc4YjAyMjdkNTcxODdjMGM4MDZiMTMwMDY=
12
12
  data.tar.gz: !binary |-
13
- MWVlMDNkYTY5NzgxZDQ1YmE3ODk2MThjMGQ2ZWMzN2JiNzMxYmQ1MTA3MDU5
14
- ZGI3ODZiYjE3MGY2ZTQ1MTZmZWJhYTUyMDM2MzNlYmZiMjMyYTkwYTAzYTQy
15
- OWNiODUxOTAwYjRkOGRlYzc4YjdjOGI4Mjk0NWVlM2RhODNmNmI=
13
+ YzM3MTBmYTQyNTRhM2E3YjM2OGQzODk2NjVmMzBhNmYyMjgxNjM1ZmQ3Yjli
14
+ NjZhYTM2MWY3MDZiMGJhZDM5M2U5MGYzMjg3NzY1MTVjMzEwZGI2NWM0NDZi
15
+ ODk4MTgwYzI0NDRhZmVmOTMyYjAxMGE0NTQ3NzI4YTBkNzMyZDY=
data/lib/cucloud.rb CHANGED
@@ -4,12 +4,14 @@ require 'aws-sdk'
4
4
  module Cucloud
5
5
  require 'cucloud/version'
6
6
  require 'cucloud/ec2_utils'
7
+ require 'cucloud/ecs_utils'
7
8
  require 'cucloud/asg_utils'
8
9
  require 'cucloud/ssm_utils'
9
10
  require 'cucloud/iam_utils'
10
11
  require 'cucloud/vpc_utils'
11
12
  require 'cucloud/config_service_utils'
12
13
  require 'cucloud/cloud_trail_utils'
14
+ require 'cucloud/rds_utils'
13
15
 
14
16
  # This is the default region API calls are made against
15
17
  DEFAULT_REGION = 'us-east-1'.freeze
@@ -214,5 +214,27 @@ module Cucloud
214
214
  end
215
215
  volumes_backed_up_recently
216
216
  end
217
+
218
+ # Find snapshots with supplied properties, currently only supports days_old
219
+ # @param options [Hash]
220
+ # @return [Array] list of snapshot ids
221
+ def find_ebs_snapshots(options = {})
222
+ days_old = options[:days_old]
223
+ found_snapshots = []
224
+ snapshots = @ec2.describe_snapshots(owner_ids: ['self'], filters: [{ name: 'status', values: ['completed'] }])
225
+
226
+ snapshots.snapshots.each do |snapshot|
227
+ if !days_old.nil?
228
+ snapshot_days_old = (Time.now.to_i - snapshot.start_time.to_i) / SECONDS_IN_A_DAY
229
+
230
+ if snapshot_days_old > days_old
231
+ found_snapshots.push(snapshot.snapshot_id)
232
+ end
233
+ else
234
+ found_snapshots.push(snapshot.snapshot_id)
235
+ end
236
+ end
237
+ found_snapshots
238
+ end
217
239
  end
218
240
  end
@@ -0,0 +1,97 @@
1
+ module Cucloud
2
+ # ECSUtils class - anything ecs related goes here!
3
+ class EcsUtils
4
+ # Define error classes
5
+ class InvalidTaskDefinitionError < ArgumentError
6
+ end
7
+
8
+ # Constructor for EcsUtils class
9
+ # @param ecs_client [Aws::ECS::Client] AWS ECS SDK Client
10
+ def initialize(ecs_client = Aws::ECS::Client.new)
11
+ ## DI for testing purposes
12
+ @ecs = ecs_client
13
+ end
14
+
15
+ # Get task definition details for given revision of task. If revision is nil, return latest task
16
+ # @param family_prefix [String] Task family prefix
17
+ # @param revision [Integer] Specific revision
18
+ # @return [Aws::ECS::Types::TaskDefinition] Task definition object
19
+ def get_task_definition(family_prefix, revision = nil)
20
+ task = if revision.nil?
21
+ family_prefix
22
+ else
23
+ "#{family_prefix}:#{revision}"
24
+ end
25
+
26
+ # https://docs.aws.amazon.com/sdkforruby/api/Aws/ECS/Client.html#describe_task_definition-instance_method
27
+ @ecs.describe_task_definition(task_definition: task)['task_definition']
28
+ end
29
+
30
+ # Generate task definition options hash (that can be sumitted to AWS SDK) w/ new image
31
+ # @param task_definition [Aws::ECS::Types::TaskDefinition] Task definition object
32
+ # @param container_name [String] Name of container for which image should be updated
33
+ # @param new_image_dtr_uri [String] Location of new image in registry
34
+ # @return [Hash] An options hash that can be submitted via AWS sdk
35
+ def generate_td_options_hash_with_new_image(task_definition, container_name, new_image_dtr_uri)
36
+ options_hash = generate_td_options_hash(task_definition)
37
+
38
+ # Definitions can contain more than one container. Update the targetted def.
39
+ target_container_index = options_hash[:container_definitions].index { |c| c[:name] == container_name }
40
+ options_hash[:container_definitions][target_container_index][:image] = new_image_dtr_uri
41
+
42
+ options_hash
43
+ end
44
+
45
+ # Generate task definition options hash (that can be sumitted to AWS SDK) from existing definition
46
+ # @param task_definition [Aws::ECS::Types::TaskDefinition] Task definition object
47
+ # @return [Hash] An options hash that can be submitted via AWS sdk
48
+ def generate_td_options_hash(task_definition)
49
+ # make sure we got a valid launch config
50
+ raise InvalidTaskDefinitionError.new,
51
+ 'Provided task definition is not valid' unless task_definition.is_a? Aws::ECS::Types::TaskDefinition
52
+
53
+ # convert to hash (required for aws sdk) and update necessary values
54
+ options_hash = task_definition.to_h
55
+
56
+ # request cannot have arn, revision or keys with empty values
57
+ options_hash.delete_if do |key, value|
58
+ key == :task_definition_arn || key == :revision || key == :status || key == :requires_attributes || value == ''
59
+ end
60
+ end
61
+
62
+ # Create new task definition in AWS
63
+ # @param options [Hash] Options hash to be passed along in request
64
+ # @return [Hash] Hash w/ task definition arn, family and revision
65
+ def register_task_definition(task_definition)
66
+ # https://docs.aws.amazon.com/sdkforruby/api/Aws/ECS/Client.html#register_task_definition-instance_method
67
+ new_def = @ecs.register_task_definition(task_definition)['task_definition']
68
+
69
+ {
70
+ arn: new_def['task_definition_arn'],
71
+ family: new_def['family'],
72
+ revision: new_def['revision']
73
+ }
74
+ end
75
+
76
+ # Get definition for service based on service name
77
+ # @param cluster_name [String] Name of cluster on which this service is configured
78
+ # @param service_name [String] Name of service
79
+ # @return [Aws::ECS::Types::Service] Service definition
80
+ def get_service(cluster_name, service_name)
81
+ # https://docs.aws.amazon.com/sdkforruby/api/Aws/ECS/Client.html#describe_services-instance_method
82
+ @ecs.describe_services(cluster: cluster_name, services: [service_name])[:services].first
83
+ end
84
+
85
+ # Update the task definition associated with a service - this effectively deploys new task on service
86
+ # @param cluster_name [String] Name of cluster on which this service is configured
87
+ # @param service_name [String] Name of service
88
+ # @param task_arn [String] Task ARN to be used by service
89
+ # @return [Aws::ECS::Types::Service] Updated service
90
+ def update_service_task_definition!(cluster_name, service_name, task_arn)
91
+ # https://docs.aws.amazon.com/sdkforruby/api/Aws/ECS/Client.html#update_service-instance_method
92
+ @ecs.update_service(cluster: cluster_name,
93
+ service: service_name,
94
+ task_definition: task_arn)['service']
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,87 @@
1
+ module Cucloud
2
+ # RdsUtils class - for interacting with the AWS relational database service
3
+ class RdsUtils
4
+ def initialize(rds_client = Aws::RDS::Client.new)
5
+ @rds = rds_client
6
+ end
7
+
8
+ # Get the RDS instance object with the given name
9
+ # @param db_instance_identifier [String] RDS instance identifier (e.g., "jadu-test-dev")
10
+ # @return [Aws::RDS::DBInstance] the instance object
11
+ def get_instance(db_instance_identifier)
12
+ resource = Aws::RDS::Resource.new(client: @rds)
13
+ resource.db_instance(db_instance_identifier)
14
+ end
15
+
16
+ # Begins the creation of a snapshot of the given RDS instance.
17
+ # This is a non-blocking call so it will return before the snapshot
18
+ # is created and available.
19
+ # @param rds_instance [Aws::RDS::DBInstance] the RDS instance which to snapshot
20
+ # @param tags [Array<Hash>] tags to assign to the snapshot;
21
+ # each array element should be of the form { key: "some key", value: "some value" }
22
+ # @return [Aws::RDS::DBSnapshot] handle to the new snapshot
23
+ def start_snapshot(rds_instance, tags = [])
24
+ date = Time.new
25
+ snap_id = rds_instance.db_instance_identifier + '-' + date.year.to_s + '-' \
26
+ + zerofill2(date.month) + '-' + zerofill2(date.day) + '-' \
27
+ + zerofill2(date.hour) + '-' + zerofill2(date.min)
28
+ rds_instance.create_snapshot(
29
+ db_snapshot_identifier: snap_id,
30
+ tags: tags
31
+ )
32
+ end
33
+
34
+ # Return list of pending snapshots for the instance.
35
+ # New snapshots cannot be created if there are any snapshots in the process
36
+ # of being created for the given instance.
37
+ # @param rds_instance [Aws::RDS::DBInstance] the RDS instance to examine
38
+ # @return [Collection<Aws::RDS::DBSnapshot>] the collection of snapshots in the process of being created
39
+ def pending_snapshots(rds_instance)
40
+ snaps = rds_instance.snapshots
41
+ snaps.select do |snap|
42
+ snap.status == 'creating'
43
+ end
44
+ end
45
+
46
+ # Wait for the completion and availability of a snapshot.
47
+ # @param snapshot [Aws::RDS::DBSnapshot] the snapshot of interest
48
+ # @param max_attempts [Integer] (optional) maximum number of times to poll the snapshot
49
+ # for status updates; defaults to nil which polls indefinitely
50
+ # @param delay [Integer] (optional) number of seconds to delay between polling;
51
+ # defaults to 10
52
+ # @return [Aws::RDS::DBSnapshot] snapshot with updated attributes;
53
+ # returns nil if the snapshot did not complete within the allowed time.
54
+ def wait_until_snapshot_available(snapshot, max_attempts = nil, delay = 10)
55
+ snapshot.wait_until(max_attempts: max_attempts, delay: delay) do |snap|
56
+ # Status == available is a conservative test for completion.
57
+ # A more liberal test would be percent_progress == 100.
58
+ snap.status == 'available'
59
+ end
60
+ rescue Aws::Waiters::Errors::WaiterFailed
61
+ nil
62
+ end
63
+
64
+ # Create a new snapshot of the instance, if no snapshots are already
65
+ # in the process of being created, and wait indefinitely
66
+ # until the snapshot is complete.
67
+ # @param rds_instance [Aws::RDS::DBInstance] the RDS instance which to snapshot
68
+ # @param tags [Array<Hash>] tags to assign to the snapshot;
69
+ # each array element should be of the form { key: "some key", value: "some value" }
70
+ # @return [Aws::RDS::DBSnapshot] handle to the new snapshot;
71
+ # nil if a new snapshot cannot be created because of other pending snapshots
72
+ def create_snapshot_and_wait_until_available(rds_instance, tags = [])
73
+ return nil unless pending_snapshots(rds_instance).empty?
74
+ snap = start_snapshot(rds_instance, tags)
75
+ wait_until_snapshot_available(snap, nil, 10)
76
+ end
77
+
78
+ private
79
+
80
+ # Return the given non-negative number as a string, zero-padded to 2 digits.
81
+ # @param n [Integet] a number 0-99
82
+ # @return [String] the zero-padded string
83
+ def zerofill2(n)
84
+ n.to_s.rjust(2, '0')
85
+ end
86
+ end
87
+ end
@@ -1,5 +1,5 @@
1
1
  module Cucloud
2
2
  # Disable mutable constant warning - freezing this oddly breaks bundler
3
3
  # rubocop:disable Style/MutableConstant
4
- VERSION = '0.6.1'
4
+ VERSION = '0.7.0'
5
5
  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.6.1
4
+ version: 0.7.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-08-17 00:00:00.000000000 Z
13
+ date: 2016-09-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk
@@ -152,8 +152,10 @@ files:
152
152
  - lib/cucloud/cloud_trail_utils.rb
153
153
  - lib/cucloud/config_service_utils.rb
154
154
  - lib/cucloud/ec2_utils.rb
155
+ - lib/cucloud/ecs_utils.rb
155
156
  - lib/cucloud/elb_utils.rb
156
157
  - lib/cucloud/iam_utils.rb
158
+ - lib/cucloud/rds_utils.rb
157
159
  - lib/cucloud/ssm_utils.rb
158
160
  - lib/cucloud/version.rb
159
161
  - lib/cucloud/vpc_utils.rb