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 +8 -8
- data/lib/cucloud.rb +2 -0
- data/lib/cucloud/ec2_utils.rb +22 -0
- data/lib/cucloud/ecs_utils.rb +97 -0
- data/lib/cucloud/rds_utils.rb +87 -0
- data/lib/cucloud/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MmNkOGQyOTA4NGFiNzQ3NmNmMWIxNTMwNDM1MTQwMzFiZjRmYTZkMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MWVjZjQzODJiNGFjNWVmYTEzYzQzMDFlMjBlNDZhMzE4OTgwYWY5OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTBkMzBhOGI2YWRlMGE0NzI5YzM2ZDc5OTc3NGNkOTgzNjFmMDg5NjU0ZDY2
|
10
|
+
NDA0Y2E2ODI2ZTc0NTM4NzlmZjRkZTUwMTg0YTVhOGFmNDczODAzM2U0ZDg1
|
11
|
+
NTU1ZTM1OWUxY2Q5Yjc4YjAyMjdkNTcxODdjMGM4MDZiMTMwMDY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
data/lib/cucloud/ec2_utils.rb
CHANGED
@@ -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
|
data/lib/cucloud/version.rb
CHANGED
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.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-
|
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
|