cucloud 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|