opsicle 2.6.0 → 2.8.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 +4 -4
- data/bin/opsicle +1 -0
- data/lib/opsicle/cloneable_instance.rb +78 -22
- data/lib/opsicle/commands/clone_instance.rb +11 -7
- data/lib/opsicle/version.rb +1 -1
- data/spec/opsicle/cloneable_instance_spec.rb +12 -6
- data/spec/opsicle/cloneable_layer_spec.rb +3 -3
- data/spec/opsicle/commands/clone_instance_spec.rb +6 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e61d35388f34cdb0123201879ba2a6e0b8737d6
|
4
|
+
data.tar.gz: ba08ee8d2d71fdf3dcefd6e5ba89dfd098f196c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1ec727a15e561239139e17f484a67c4708d8c42102187f47d2df59fd3722e5b547c50e7837c8cae10281d48ad3d94ff7976b797f9a1a6f6995b7ffa9e92a9ed
|
7
|
+
data.tar.gz: f450d31f77ef707f45bc55c921a895a12769374de33d9ec1789d40c10d6b45ae63edcb7596596ef4ea251a1a8a85fd286ce37cd2dadf2bb79c18a5d376c93068
|
data/bin/opsicle
CHANGED
@@ -196,6 +196,7 @@ end
|
|
196
196
|
desc "Clone instances in the given environment stack"
|
197
197
|
arg_name '<environment>'
|
198
198
|
command 'clone-instance' do |c|
|
199
|
+
c.switch [:d, :'with-defaults'], desc: "Clone the instances with no overrides", default_value: false
|
199
200
|
c.action do |global_options, options, args|
|
200
201
|
raise ArgumentError, "Environment is required" unless args.first
|
201
202
|
Opsicle::CloneInstance.new(args.first).execute global_options.merge options
|
@@ -1,8 +1,30 @@
|
|
1
1
|
module Opsicle
|
2
2
|
class CloneableInstance
|
3
|
-
attr_accessor
|
4
|
-
|
5
|
-
|
3
|
+
attr_accessor(
|
4
|
+
:hostname,
|
5
|
+
:status,
|
6
|
+
:layer,
|
7
|
+
:ami_id,
|
8
|
+
:instance_type,
|
9
|
+
:instance_id,
|
10
|
+
:new_instance_id,
|
11
|
+
:agent_version,
|
12
|
+
:stack_id,
|
13
|
+
:layer_ids,
|
14
|
+
:auto_scaling_type,
|
15
|
+
:os,
|
16
|
+
:ssh_key_name,
|
17
|
+
:availability_zone,
|
18
|
+
:virtualization_type,
|
19
|
+
:subnet_id,
|
20
|
+
:architecture,
|
21
|
+
:root_device_type,
|
22
|
+
:install_updates_on_boot,
|
23
|
+
:ebs_optimized,
|
24
|
+
:tenancy,
|
25
|
+
:opsworks,
|
26
|
+
:cli
|
27
|
+
)
|
6
28
|
|
7
29
|
def initialize(instance, layer, opsworks, cli)
|
8
30
|
self.hostname = instance.hostname
|
@@ -26,44 +48,65 @@ module Opsicle
|
|
26
48
|
self.tenancy = instance.tenancy
|
27
49
|
self.opsworks = opsworks
|
28
50
|
self.cli = cli
|
51
|
+
self.instance_id = instance.instance_id
|
52
|
+
self.new_instance_id = nil
|
29
53
|
end
|
30
54
|
|
31
55
|
def clone(options)
|
32
56
|
puts "\nCloning an instance..."
|
33
|
-
|
34
|
-
new_instance_hostname = make_new_hostname
|
57
|
+
|
58
|
+
new_instance_hostname = make_new_hostname
|
35
59
|
ami_id = verify_ami_id
|
36
60
|
agent_version = verify_agent_version
|
37
61
|
subnet_id = verify_subnet_id
|
38
62
|
instance_type = verify_instance_type
|
39
63
|
|
40
64
|
create_new_instance(new_instance_hostname, instance_type, ami_id, agent_version, subnet_id)
|
65
|
+
start_new_instance
|
41
66
|
end
|
42
67
|
|
43
|
-
def make_new_hostname(old_hostname)
|
44
|
-
all_sibling_hostnames = self.layer.instances.collect { |instance| instance.hostname }
|
45
68
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
69
|
+
def clone_with_defaults(options)
|
70
|
+
puts "\nCloning an instance..."
|
71
|
+
new_hostname = auto_generated_hostname
|
72
|
+
create_new_instance(new_hostname, instance_type, ami_id, agent_version, subnet_id)
|
73
|
+
opsworks.start_instance(instance_id: new_instance_id)
|
74
|
+
puts "\nNew instance is starting…"
|
75
|
+
end
|
76
|
+
|
77
|
+
def make_new_hostname
|
78
|
+
new_instance_hostname = auto_generated_hostname
|
52
79
|
puts "\nAutomatically generated hostname: #{new_instance_hostname}\n"
|
53
80
|
new_instance_hostname = ask_for_new_option("instance's hostname") if ask_for_overriding_permission("hostname", false)
|
54
|
-
|
55
81
|
new_instance_hostname
|
56
82
|
end
|
57
83
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
84
|
+
def auto_generated_hostname
|
85
|
+
if hostname =~ /\d\d\z/
|
86
|
+
increment_hostname
|
87
|
+
else
|
88
|
+
hostname << "-clone"
|
61
89
|
end
|
62
|
-
hostname
|
63
90
|
end
|
64
91
|
|
65
|
-
def
|
66
|
-
|
92
|
+
def sibling_hostnames
|
93
|
+
self.layer.instances.collect { |instance| instance.hostname }
|
94
|
+
end
|
95
|
+
|
96
|
+
def increment_hostname
|
97
|
+
name = hostname
|
98
|
+
until hostname_unique?(name) do
|
99
|
+
name = name.gsub(/(\d\d\z)/) { "#{($1.to_i + 1).to_s.rjust(2, '0')}" }
|
100
|
+
end
|
101
|
+
name
|
102
|
+
end
|
103
|
+
|
104
|
+
def sibling_hostnames
|
105
|
+
self.layer.instances.map(&:hostname)
|
106
|
+
end
|
107
|
+
|
108
|
+
def hostname_unique?(name)
|
109
|
+
!sibling_hostnames.include?(name)
|
67
110
|
end
|
68
111
|
|
69
112
|
def verify_ami_id
|
@@ -179,8 +222,21 @@ module Opsicle
|
|
179
222
|
agent_version: agent_version,
|
180
223
|
tenancy: self.tenancy,
|
181
224
|
})
|
182
|
-
self.
|
183
|
-
|
225
|
+
self.new_instance_id = new_instance.instance_id
|
226
|
+
self.layer.add_new_instance(new_instance_id)
|
227
|
+
puts "\nNew instance #{new_instance_hostname} has been created: #{new_instance_id}"
|
228
|
+
end
|
229
|
+
|
230
|
+
def start_new_instance
|
231
|
+
if ask_to_start_instance
|
232
|
+
@opsworks.start_instance(instance_id: self.new_instance_id)
|
233
|
+
puts "\nNew instance is starting…"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def ask_to_start_instance
|
238
|
+
ans = @cli.ask("Do you wish to start this new instance?\n1) Yes\n2) No", Integer)
|
239
|
+
ans == 1
|
184
240
|
end
|
185
241
|
end
|
186
242
|
end
|
@@ -19,16 +19,20 @@ module Opsicle
|
|
19
19
|
puts "Stack ID = #{@stack.id}"
|
20
20
|
layer = select_layer
|
21
21
|
all_instances = layer.get_cloneable_instances
|
22
|
-
|
23
|
-
|
24
|
-
instances_to_clone.each do |instance|
|
25
|
-
instance.clone(options)
|
26
|
-
end
|
27
|
-
|
22
|
+
instance_to_clone = select_instances(all_instances)
|
23
|
+
clone_instances(instance_to_clone, options)
|
28
24
|
layer.ami_id = nil
|
29
25
|
layer.agent_version = nil
|
30
26
|
end
|
31
27
|
|
28
|
+
def clone_instances(instances, options)
|
29
|
+
if options[:'with-defaults']
|
30
|
+
instances.each { |instance| instance.clone_with_defaults(options) }
|
31
|
+
else
|
32
|
+
instances.each { |instance| instance.clone(options) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
32
36
|
def select_layer
|
33
37
|
puts "\nLayers:\n"
|
34
38
|
ops_layers = @opsworks.describe_layers({ :stack_id => @stack.id }).layers
|
@@ -49,7 +53,7 @@ module Opsicle
|
|
49
53
|
instance_indices_string = @cli.ask("Instances? (enter as a comma separated list)\n", String)
|
50
54
|
instance_indices_list = instance_indices_string.split(/,\s*/)
|
51
55
|
instance_indices_list.map! { |instance_index| instance_index.to_i - 1 }
|
52
|
-
|
56
|
+
|
53
57
|
return_array = []
|
54
58
|
instance_indices_list.each do |index|
|
55
59
|
return_array << instances[index]
|
data/lib/opsicle/version.rb
CHANGED
@@ -14,7 +14,7 @@ module Opsicle
|
|
14
14
|
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
15
15
|
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
16
16
|
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
17
|
-
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
17
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy', :instance_id => 'some-id')
|
18
18
|
@layer = double('layer1', :name => 'layer-1', :layer_id => 12345, :instances => [@instance], :ami_id => nil, :agent_version => nil)
|
19
19
|
allow(@layer).to receive(:ami_id=)
|
20
20
|
allow(@layer).to receive(:ami_id)
|
@@ -38,11 +38,10 @@ module Opsicle
|
|
38
38
|
context "#make_new_hostname" do
|
39
39
|
it "should make a unique incremented hostname" do
|
40
40
|
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
41
|
-
expect(instance).to receive(:increment_hostname).and_return('example-hostname-03')
|
42
41
|
instance1 = double('instance', :hostname => 'example-hostname-01')
|
43
42
|
instance2 = double('instance', :hostname => 'example-hostname-02')
|
44
43
|
allow(@layer).to receive(:instances).and_return([instance1, instance2])
|
45
|
-
instance.make_new_hostname('example-hostname-
|
44
|
+
expect(instance.make_new_hostname).to eq('example-hostname-03')
|
46
45
|
end
|
47
46
|
|
48
47
|
it "should make a unique incremented hostname" do
|
@@ -51,8 +50,8 @@ module Opsicle
|
|
51
50
|
instance2 = double('instance', :hostname => 'example-hostname-02')
|
52
51
|
instance3 = double('instance', :hostname => 'example-hostname-03')
|
53
52
|
instance4 = double('instance', :hostname => 'example-hostname-04')
|
54
|
-
|
55
|
-
expect(instance.make_new_hostname
|
53
|
+
allow(@layer).to receive(:instances).and_return([instance1, instance2, instance3, instance4])
|
54
|
+
expect(instance.make_new_hostname).to eq('example-hostname-05')
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
@@ -61,7 +60,7 @@ module Opsicle
|
|
61
60
|
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
62
61
|
expect(instance).to receive(:hostname_unique?).and_return('example-hostname-03')
|
63
62
|
allow(@opsworks).to receive(:describe_agent_version).with({})
|
64
|
-
instance.increment_hostname('example-hostname-01'
|
63
|
+
expect(instance.increment_hostname).to eq('example-hostname-01')
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
@@ -86,6 +85,13 @@ module Opsicle
|
|
86
85
|
expect(instance).to receive(:create_new_instance)
|
87
86
|
instance.clone({})
|
88
87
|
end
|
88
|
+
|
89
|
+
it "should start new instance" do
|
90
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
91
|
+
allow(instance).to receive(:ask_to_start_instance).and_return(true)
|
92
|
+
expect(instance).to receive(:start_new_instance)
|
93
|
+
instance.clone({})
|
94
|
+
end
|
89
95
|
end
|
90
96
|
|
91
97
|
context '#verify_agent_version' do
|
@@ -14,7 +14,7 @@ module Opsicle
|
|
14
14
|
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
15
15
|
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
16
16
|
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
17
|
-
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
17
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy', :instance_id => 'some-id')
|
18
18
|
@instance2 = double('instance2', :hostname => 'example-hostname-02', :status => 'active',
|
19
19
|
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
20
20
|
:agent_version => 'agent_version', :stack_id => 1234567890,
|
@@ -23,7 +23,7 @@ module Opsicle
|
|
23
23
|
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
24
24
|
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
25
25
|
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
26
|
-
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
26
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy', :instance_id => 'some-id')
|
27
27
|
@instance3 = double('instance3', :hostname => 'example-hostname-03', :status => 'stopped',
|
28
28
|
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
29
29
|
:agent_version => 'agent_version', :stack_id => 1234567890,
|
@@ -32,7 +32,7 @@ module Opsicle
|
|
32
32
|
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
33
33
|
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
34
34
|
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
35
|
-
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
35
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy', :instance_id => 'some-id')
|
36
36
|
@instances = double('instances', :instances => [@instance1, @instance2])
|
37
37
|
@new_instance = double('new_instance', :instances => [@instance3])
|
38
38
|
@opsworks = double('opsworks', :describe_instances => @instances)
|
@@ -14,7 +14,7 @@ module Opsicle
|
|
14
14
|
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
15
15
|
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
16
16
|
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
17
|
-
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
17
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy', :instance_id => 'some-id')
|
18
18
|
@instance2 = double('instance2', :hostname => 'example-hostname-02', :status => 'active',
|
19
19
|
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
20
20
|
:agent_version => 'agent_version', :stack_id => 1234567890,
|
@@ -23,7 +23,7 @@ module Opsicle
|
|
23
23
|
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
24
24
|
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
25
25
|
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
26
|
-
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
26
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy', :instance_id => 'some-id')
|
27
27
|
@instances = double('instances', :instances => [@instance1, @instance2])
|
28
28
|
@layer1 = double('layer1', :name => 'layer-1', :layer_id => 12345, :instances => [@instance1, @instance2])
|
29
29
|
@layer2 = double('layer2', :name => 'layer-2', :layer_id => 67890, :instances => [@instance1, @instance2])
|
@@ -32,7 +32,8 @@ module Opsicle
|
|
32
32
|
@stack = double('stack')
|
33
33
|
@stacks = double('stacks', :stacks => [@stack])
|
34
34
|
@opsworks = double('opsworks', :describe_instances => @instances, :describe_layers => @layers,
|
35
|
-
:create_instance => @new_instance, :describe_stacks => @stacks
|
35
|
+
:create_instance => @new_instance, :describe_stacks => @stacks,
|
36
|
+
:start_instance => @new_instance)
|
36
37
|
@config = double('config', :opsworks_config => {:stack_id => 1234567890})
|
37
38
|
@client = double('client', :config => @config, :opsworks => @opsworks)
|
38
39
|
allow(Client).to receive(:new).with(:environment).and_return(@client)
|
@@ -54,8 +55,9 @@ module Opsicle
|
|
54
55
|
allow_any_instance_of(HighLine).to receive(:ask).with("Please write in the new instance type press ENTER:").and_return('t2.micro')
|
55
56
|
allow_any_instance_of(HighLine).to receive(:ask).with("Do you wish to override this subnet ID? By overriding, you are choosing to override the current subnet ID for all instances you are cloning.\n1) Yes\n2) No", Integer).and_return(2)
|
56
57
|
allow_any_instance_of(HighLine).to receive(:ask).with("Which subnet ID?\n", Integer).and_return(1)
|
58
|
+
allow_any_instance_of(HighLine).to receive(:ask).with("Do you wish to start this new instance?\n1) Yes\n2) No", Integer).and_return(1)
|
57
59
|
end
|
58
|
-
|
60
|
+
|
59
61
|
context "#execute" do
|
60
62
|
it "lists all current layers" do
|
61
63
|
expect(@opsworks).to receive(:describe_layers)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opsicle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Fleener
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -282,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
282
|
version: '0'
|
283
283
|
requirements: []
|
284
284
|
rubyforge_project:
|
285
|
-
rubygems_version: 2.
|
285
|
+
rubygems_version: 2.6.12
|
286
286
|
signing_key:
|
287
287
|
specification_version: 4
|
288
288
|
summary: An opsworks specific abstraction on top of the aws sdk
|