opsicle 2.0.2 → 2.1.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 +9 -0
- data/lib/opsicle/cloneable_instance.rb +94 -0
- data/lib/opsicle/cloneable_layer.rb +21 -0
- data/lib/opsicle/cloneable_stack.rb +15 -0
- data/lib/opsicle/commands.rb +1 -0
- data/lib/opsicle/commands/clone_instance.rb +57 -0
- data/lib/opsicle/version.rb +1 -1
- data/spec/opsicle/cloneable_instance_spec.rb +84 -0
- data/spec/opsicle/cloneable_layer_spec.rb +46 -0
- data/spec/opsicle/cloneable_stack_spec.rb +23 -0
- data/spec/opsicle/commands/clone_instance_spec.rb +87 -0
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec2a91363560aea651074f4c23361278855ce22d
|
4
|
+
data.tar.gz: c55b4b23ebab64601cc4f211bc2dbb27380bd3af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b214985df18e366ad1e93d2a649a7809e1e2c033e59de932caad7067e56700702428159ec807da4283072b6dfe0165d13244f486e9d17a5347f24f62e50ca52
|
7
|
+
data.tar.gz: f92adf09b8751466df7d5281dcd2e165ed59f7389cbe266079dafd79f4341c0da1faea4ac8709b0e19aee795a2d24e44f4f01627ac2ea0b0bd84906aa46aad1b
|
data/bin/opsicle
CHANGED
@@ -193,6 +193,15 @@ command 'execute-recipes' do |c|
|
|
193
193
|
end
|
194
194
|
end
|
195
195
|
|
196
|
+
desc "Clone instances in the given environment stack"
|
197
|
+
arg_name '<environment>'
|
198
|
+
command 'clone-instance' do |c|
|
199
|
+
c.action do |global_options, options, args|
|
200
|
+
raise ArgumentError, "Environment is required" unless args.first
|
201
|
+
Opsicle::CloneInstance.new(args.first).execute global_options.merge options
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
196
205
|
desc "List all instances in the given environment stack"
|
197
206
|
arg_name '<environment>'
|
198
207
|
command :instances do |c|
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Opsicle
|
2
|
+
class CloneableInstance
|
3
|
+
attr_accessor :hostname, :status, :layer, :ami_id, :instance_type, :agent_version, :stack_id, :layer_ids,
|
4
|
+
:auto_scaling_type, :os, :ssh_key_name, :availability_zone, :virtualization_type, :subnet_id,
|
5
|
+
:architecture, :root_device_type, :install_updates_on_boot, :ebs_optimized, :tenancy, :opsworks, :cli
|
6
|
+
|
7
|
+
def initialize(instance, layer, opsworks, cli)
|
8
|
+
self.hostname = instance.hostname
|
9
|
+
self.status = instance.status
|
10
|
+
self.layer = layer
|
11
|
+
self.ami_id = instance.ami_id
|
12
|
+
self.instance_type = instance.instance_type
|
13
|
+
self.agent_version = instance.agent_version
|
14
|
+
self.stack_id = instance.stack_id
|
15
|
+
self.layer_ids = instance.layer_ids
|
16
|
+
self.auto_scaling_type = instance.auto_scaling_type
|
17
|
+
self.os = instance.os
|
18
|
+
self.ssh_key_name = instance.ssh_key_name
|
19
|
+
self.availability_zone = instance.availability_zone
|
20
|
+
self.virtualization_type = instance.virtualization_type
|
21
|
+
self.subnet_id = instance.subnet_id
|
22
|
+
self.architecture = instance.architecture
|
23
|
+
self.root_device_type = instance.root_device_type
|
24
|
+
self.install_updates_on_boot = instance.install_updates_on_boot
|
25
|
+
self.ebs_optimized = instance.ebs_optimized
|
26
|
+
self.tenancy = instance.tenancy
|
27
|
+
self.opsworks = opsworks
|
28
|
+
self.cli = cli
|
29
|
+
end
|
30
|
+
|
31
|
+
def clone(options)
|
32
|
+
all_sibling_hostnames = self.layer.instances.collect { |instance| instance.hostname }
|
33
|
+
new_instance_hostname = make_new_hostname(self.hostname, all_sibling_hostnames)
|
34
|
+
puts "\nWe will make a new instance with hostname: #{new_instance_hostname}"
|
35
|
+
|
36
|
+
options[:ami] ? ami_id = options[:ami] : ami_id = self.ami_id
|
37
|
+
options[:instance_type] ? instance_type = options[:instance_type] : instance_type = self.instance_type
|
38
|
+
options[:agent_version] ? agent_version = options[:agent_version] : agent_version = self.agent_version
|
39
|
+
|
40
|
+
create_new_instance(new_instance_hostname, instance_type, ami_id, agent_version)
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_new_hostname(old_hostname, all_hostnames)
|
44
|
+
if old_hostname =~ /\d\d\z/
|
45
|
+
new_instance_hostname = increment_hostname(old_hostname, all_hostnames)
|
46
|
+
else
|
47
|
+
new_instance_hostname = old_hostname << "_clone"
|
48
|
+
end
|
49
|
+
|
50
|
+
puts "\nAutomatically generated hostname: #{new_instance_hostname}\n"
|
51
|
+
rewriting = @cli.ask("Do you wish to rewrite this hostname?\n1) Yes\n2) No", Integer)
|
52
|
+
|
53
|
+
if rewriting == 1
|
54
|
+
new_instance_hostname = @cli.ask("Please write in the new instance's hostname and press ENTER:")
|
55
|
+
end
|
56
|
+
|
57
|
+
new_instance_hostname
|
58
|
+
end
|
59
|
+
|
60
|
+
def increment_hostname(hostname, all_hostnames)
|
61
|
+
until hostname_unique?(hostname, all_hostnames) do
|
62
|
+
hostname = hostname.gsub(/(\d\d\z)/) { "#{($1.to_i + 1).to_s.rjust(2, '0')}" }
|
63
|
+
end
|
64
|
+
hostname
|
65
|
+
end
|
66
|
+
|
67
|
+
def hostname_unique?(hostname, all_hostnames)
|
68
|
+
!all_hostnames.include?(hostname)
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_new_instance(new_instance_hostname, instance_type, ami_id, agent_version)
|
72
|
+
new_instance = @opsworks.create_instance({
|
73
|
+
stack_id: self.stack_id, # required
|
74
|
+
layer_ids: self.layer_ids, # required
|
75
|
+
instance_type: instance_type, # required
|
76
|
+
auto_scaling_type: self.auto_scaling_type, # accepts load, timer
|
77
|
+
hostname: new_instance_hostname,
|
78
|
+
os: self.os,
|
79
|
+
ami_id: ami_id,
|
80
|
+
ssh_key_name: self.ssh_key_name,
|
81
|
+
availability_zone: self.availability_zone,
|
82
|
+
virtualization_type: self.virtualization_type,
|
83
|
+
subnet_id: self.subnet_id,
|
84
|
+
architecture: self.architecture, # accepts x86_64, i386
|
85
|
+
root_device_type: self.root_device_type, # accepts ebs, instance-store
|
86
|
+
install_updates_on_boot: self.install_updates_on_boot,
|
87
|
+
#ebs_optimized: self.ebs_optimized,
|
88
|
+
agent_version: agent_version,
|
89
|
+
tenancy: self.tenancy,
|
90
|
+
})
|
91
|
+
puts "New instance is created: #{new_instance.instance_id}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Opsicle
|
2
|
+
class CloneableLayer
|
3
|
+
attr_accessor :name, :layer_id, :instances, :opsworks, :cli
|
4
|
+
|
5
|
+
def initialize(name, layer_id, opsworks, cli)
|
6
|
+
self.name = name
|
7
|
+
self.layer_id = layer_id
|
8
|
+
self.opsworks = opsworks
|
9
|
+
self.cli = cli
|
10
|
+
self.instances = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_cloneable_instances
|
14
|
+
ops_instances = @opsworks.describe_instances({ :layer_id => layer_id }).instances
|
15
|
+
ops_instances.each do |instance|
|
16
|
+
self.instances << CloneableInstance.new(instance, self, @opsworks, @cli)
|
17
|
+
end
|
18
|
+
self.instances
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Opsicle
|
2
|
+
class CloneableStack
|
3
|
+
attr_accessor :id, :opsworks, :stack
|
4
|
+
|
5
|
+
def initialize(stack_id, opsworks)
|
6
|
+
self.id = stack_id
|
7
|
+
self.opsworks = opsworks
|
8
|
+
self.stack = get_stack
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_stack
|
12
|
+
@opsworks.describe_stacks({ :stack_ids => [self.id.to_s] }).stacks.first
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/opsicle/commands.rb
CHANGED
@@ -2,6 +2,7 @@ require 'opsicle/client'
|
|
2
2
|
|
3
3
|
require "opsicle/commands/deploy"
|
4
4
|
require "opsicle/commands/chef_update"
|
5
|
+
require "opsicle/commands/clone_instance"
|
5
6
|
require "opsicle/commands/execute_recipes"
|
6
7
|
require "opsicle/commands/list"
|
7
8
|
require "opsicle/commands/list_instances"
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'gli'
|
2
|
+
require "opsicle/user_profile"
|
3
|
+
require "opsicle/cloneable_layer"
|
4
|
+
require "opsicle/cloneable_instance"
|
5
|
+
require "opsicle/cloneable_stack"
|
6
|
+
|
7
|
+
module Opsicle
|
8
|
+
class CloneInstance
|
9
|
+
|
10
|
+
def initialize(environment)
|
11
|
+
@client = Client.new(environment)
|
12
|
+
@opsworks = @client.opsworks
|
13
|
+
stack_id = @client.config.opsworks_config[:stack_id]
|
14
|
+
@stack = CloneableStack.new(@client.config.opsworks_config[:stack_id], @opsworks)
|
15
|
+
@cli = HighLine.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute(options={})
|
19
|
+
puts "Stack ID = #{@stack.id}"
|
20
|
+
layer = select_layer
|
21
|
+
all_instances = layer.get_cloneable_instances
|
22
|
+
instances_to_clone = select_instances(all_instances)
|
23
|
+
|
24
|
+
instances_to_clone.each do |instance|
|
25
|
+
instance.clone(options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def select_layer
|
30
|
+
puts "\nLayers:\n"
|
31
|
+
ops_layers = @opsworks.describe_layers({ :stack_id => @stack.id }).layers
|
32
|
+
|
33
|
+
layers = []
|
34
|
+
ops_layers.each do |layer|
|
35
|
+
layers << CloneableLayer.new(layer.name, layer.layer_id, @opsworks, @cli)
|
36
|
+
end
|
37
|
+
|
38
|
+
layers.each_with_index { |layer, index| puts "#{index.to_i + 1}) #{layer.name}"}
|
39
|
+
layer_index = @cli.ask("Layer?\n", Integer) { |q| q.in = 1..layers.length.to_i } - 1
|
40
|
+
layers[layer_index]
|
41
|
+
end
|
42
|
+
|
43
|
+
def select_instances(instances)
|
44
|
+
puts "\nInstances:\n"
|
45
|
+
instances.each_with_index { |instance, index| puts "#{index.to_i + 1}) #{instance.status} - #{instance.hostname}" }
|
46
|
+
instance_indices_string = @cli.ask("Instances? (enter as a comma separated list)\n", String)
|
47
|
+
instance_indices_list = instance_indices_string.split(/,\s*/)
|
48
|
+
instance_indices_list.map! { |instance_index| instance_index.to_i - 1 }
|
49
|
+
|
50
|
+
return_array = []
|
51
|
+
instance_indices_list.each do |index|
|
52
|
+
return_array << instances[index]
|
53
|
+
end
|
54
|
+
return_array
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/opsicle/version.rb
CHANGED
@@ -0,0 +1,84 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "opsicle"
|
3
|
+
require 'gli'
|
4
|
+
require "opsicle/user_profile"
|
5
|
+
|
6
|
+
module Opsicle
|
7
|
+
describe CloneableInstance do
|
8
|
+
before do
|
9
|
+
@instance = double('instance1', :hostname => 'example-hostname-01', :status => 'active',
|
10
|
+
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
11
|
+
:agent_version => 'agent_version', :stack_id => 1234567890,
|
12
|
+
:layer_ids => [12345, 67890], :auto_scaling_type => 'auto_scaling_type',
|
13
|
+
:os => 'os', :ssh_key_name => 'ssh_key_name',
|
14
|
+
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
15
|
+
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
16
|
+
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
17
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
18
|
+
@layer = double('layer1', :name => 'layer-1', :layer_id => 12345, :instances => [@instance])
|
19
|
+
@new_instance = double('new_instance', :instance_id => 1029384756)
|
20
|
+
@opsworks = double('opsworks', :create_instance => @new_instance)
|
21
|
+
@cli = double('cli', :ask => 2)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "#make_new_hostname" do
|
25
|
+
it "should make a unique incremented hostname" do
|
26
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
27
|
+
expect(instance).to receive(:increment_hostname).and_return('example-hostname-03')
|
28
|
+
instance.make_new_hostname('example-hostname-01', ['example-hostname-01', 'example-hostname-02'])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "#increment_hostname" do
|
33
|
+
it "should increment the hostname" do
|
34
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
35
|
+
expect(instance).to receive(:hostname_unique?).and_return('example-hostname-03')
|
36
|
+
instance.increment_hostname('example-hostname-01', ['example-hostname-01', 'example-hostname-02'])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "#clone" do
|
41
|
+
it "should grab instances and make new hostname" do
|
42
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
43
|
+
expect(@layer).to receive(:instances)
|
44
|
+
expect(instance).to receive(:make_new_hostname).and_return('example-hostname-03')
|
45
|
+
instance.clone({})
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should get information from old instance" do
|
49
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
50
|
+
expect(instance).to receive(:agent_version)
|
51
|
+
expect(instance).to receive(:ami_id)
|
52
|
+
expect(instance).to receive(:instance_type)
|
53
|
+
instance.clone({})
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should create new instance" do
|
57
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
58
|
+
expect(instance).to receive(:create_new_instance)
|
59
|
+
instance.clone({})
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "#create_new_instance" do
|
64
|
+
it "should create an instance" do
|
65
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
66
|
+
expect(@opsworks).to receive(:create_instance)
|
67
|
+
instance.create_new_instance('hostname', 'type', 'ami', 'agent_version')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should take information from old instance" do
|
71
|
+
instance = CloneableInstance.new(@instance, @layer, @opsworks, @cli)
|
72
|
+
expect(instance).to receive(:stack_id)
|
73
|
+
expect(instance).to receive(:layer_ids)
|
74
|
+
expect(instance).to receive(:auto_scaling_type)
|
75
|
+
expect(instance).to receive(:os)
|
76
|
+
expect(instance).to receive(:ssh_key_name)
|
77
|
+
expect(instance).to receive(:availability_zone)
|
78
|
+
expect(instance).to receive(:virtualization_type)
|
79
|
+
expect(instance).to receive(:subnet_id)
|
80
|
+
instance.create_new_instance('hostname', 'type', 'ami', 'agent_version')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "opsicle"
|
3
|
+
require 'gli'
|
4
|
+
require "opsicle/user_profile"
|
5
|
+
|
6
|
+
module Opsicle
|
7
|
+
describe CloneableLayer do
|
8
|
+
before do
|
9
|
+
@instance1 = double('instance1', :hostname => 'example-hostname-01', :status => 'active',
|
10
|
+
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
11
|
+
:agent_version => 'agent_version', :stack_id => 1234567890,
|
12
|
+
:layer_ids => [12345, 67890], :auto_scaling_type => 'auto_scaling_type',
|
13
|
+
:os => 'os', :ssh_key_name => 'ssh_key_name',
|
14
|
+
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
15
|
+
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
16
|
+
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
17
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
18
|
+
@instance2 = double('instance2', :hostname => 'example-hostname-02', :status => 'active',
|
19
|
+
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
20
|
+
:agent_version => 'agent_version', :stack_id => 1234567890,
|
21
|
+
:layer_ids => [12345, 67890], :auto_scaling_type => 'auto_scaling_type',
|
22
|
+
:os => 'os', :ssh_key_name => 'ssh_key_name',
|
23
|
+
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
24
|
+
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
25
|
+
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
26
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
27
|
+
@instances = double('instances', :instances => [@instance1, @instance2])
|
28
|
+
@opsworks = double('opsworks', :describe_instances => @instances)
|
29
|
+
end
|
30
|
+
|
31
|
+
context "#get_cloneable_instances" do
|
32
|
+
it "should gather opsworks instances for that layer" do
|
33
|
+
layer = CloneableLayer.new('layer-name', 12345, @opsworks, @cli)
|
34
|
+
expect(@opsworks).to receive(:describe_instances).and_return(@instances)
|
35
|
+
expect(@instances).to receive(:instances)
|
36
|
+
layer.get_cloneable_instances
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should make a new CloneableInstance for each instance" do
|
40
|
+
layer = CloneableLayer.new('layer-name', 12345, @opsworks, @cli)
|
41
|
+
expect(CloneableInstance).to receive(:new).twice
|
42
|
+
layer.get_cloneable_instances
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "opsicle"
|
3
|
+
require 'gli'
|
4
|
+
require "opsicle/user_profile"
|
5
|
+
|
6
|
+
module Opsicle
|
7
|
+
describe CloneableStack do
|
8
|
+
before do
|
9
|
+
@stack = double('stack')
|
10
|
+
@stacks = double('stacks', :stacks => [@stack])
|
11
|
+
@opsworks = double('opsworks', :describe_stacks => @stacks)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "#get_stack" do
|
15
|
+
it "should gather opsworks instances for that layer" do
|
16
|
+
stack = CloneableStack.new(12345, @opsworks)
|
17
|
+
expect(@opsworks).to receive(:describe_stacks).and_return(@stacks)
|
18
|
+
expect(@stacks).to receive(:stacks)
|
19
|
+
stack.get_stack
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "opsicle"
|
3
|
+
require 'gli'
|
4
|
+
require "opsicle/user_profile"
|
5
|
+
|
6
|
+
module Opsicle
|
7
|
+
describe CloneInstance do
|
8
|
+
before do
|
9
|
+
@instance1 = double('instance1', :hostname => 'example-hostname-01', :status => 'active',
|
10
|
+
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
11
|
+
:agent_version => 'agent_version', :stack_id => 1234567890,
|
12
|
+
:layer_ids => [12345, 67890], :auto_scaling_type => 'auto_scaling_type',
|
13
|
+
:os => 'os', :ssh_key_name => 'ssh_key_name',
|
14
|
+
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
15
|
+
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
16
|
+
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
17
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
18
|
+
@instance2 = double('instance2', :hostname => 'example-hostname-02', :status => 'active',
|
19
|
+
:ami_id => 'ami_id', :instance_type => 'instance_type',
|
20
|
+
:agent_version => 'agent_version', :stack_id => 1234567890,
|
21
|
+
:layer_ids => [12345, 67890], :auto_scaling_type => 'auto_scaling_type',
|
22
|
+
:os => 'os', :ssh_key_name => 'ssh_key_name',
|
23
|
+
:availability_zone => 'availability_zone', :virtualization_type => 'virtualization_type',
|
24
|
+
:subnet_id => 'subnet_id', :architecture => 'architecture',
|
25
|
+
:root_device_type => 'root_device_type', :install_updates_on_boot => 'install_updates_on_boot',
|
26
|
+
:ebs_optimized => 'ebs_optimized', :tenancy => 'tenancy')
|
27
|
+
@instances = double('instances', :instances => [@instance1, @instance2])
|
28
|
+
@layer1 = double('layer1', :name => 'layer-1', :layer_id => 12345, :instances => [@instance1, @instance2])
|
29
|
+
@layer2 = double('layer2', :name => 'layer-2', :layer_id => 67890, :instances => [@instance1, @instance2])
|
30
|
+
@layers = double('layers', :layers => [@layer1, @layer2])
|
31
|
+
@new_instance = double('new_instance', :instance_id => 1029384756)
|
32
|
+
@stack = double('stack')
|
33
|
+
@stacks = double('stacks', :stacks => [@stack])
|
34
|
+
@opsworks = double('opsworks', :describe_instances => @instances, :describe_layers => @layers,
|
35
|
+
:create_instance => @new_instance, :describe_stacks => @stacks)
|
36
|
+
@config = double('config', :opsworks_config => {:stack_id => 1234567890})
|
37
|
+
@client = double('client', :config => @config, :opsworks => @opsworks)
|
38
|
+
allow(Client).to receive(:new).with(:environment).and_return(@client)
|
39
|
+
allow(@instances).to receive(:each_with_index)
|
40
|
+
allow_any_instance_of(HighLine).to receive(:ask).with("Layer?\n", Integer).and_return(2)
|
41
|
+
allow_any_instance_of(HighLine).to receive(:ask).with("Instances? (enter as a comma separated list)\n", String).and_return('2')
|
42
|
+
allow_any_instance_of(HighLine).to receive(:ask).with("Do you wish to rewrite this hostname?\n1) Yes\n2) No", Integer).and_return(2)
|
43
|
+
allow_any_instance_of(HighLine).to receive(:ask).with("Please write in the new instance's hostname and press ENTER:").and_return('example-hostname')
|
44
|
+
end
|
45
|
+
|
46
|
+
context "#execute" do
|
47
|
+
it "lists all current layers" do
|
48
|
+
expect(@opsworks).to receive(:describe_layers)
|
49
|
+
CloneInstance.new(:environment).execute
|
50
|
+
end
|
51
|
+
|
52
|
+
it "lists all current instances" do
|
53
|
+
expect(@opsworks).to receive(:describe_instances)
|
54
|
+
CloneInstance.new(:environment).execute
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "#select_layer" do
|
59
|
+
it "should list layers" do
|
60
|
+
expect(@opsworks).to receive(:describe_layers)
|
61
|
+
CloneInstance.new(:environment).select_layer
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should get the layer id" do
|
65
|
+
expect(@layer2).to receive(:layer_id)
|
66
|
+
CloneInstance.new(:environment).select_layer
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "#select_instances" do
|
71
|
+
it "should list instances" do
|
72
|
+
expect(@instances).to receive(:[])
|
73
|
+
CloneInstance.new(:environment).select_instances(@instances)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "#client" do
|
78
|
+
it "generates a new AWS client from the given configs" do
|
79
|
+
@config = double('config', :opsworks_config => {:stack_id => 1234567890})
|
80
|
+
@client = double('client', :config => @config,
|
81
|
+
:opsworks => @opsworks)
|
82
|
+
expect(Client).to receive(:new).with(:environment).and_return(@client)
|
83
|
+
CloneInstance.new(:environment)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
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.0
|
4
|
+
version: 2.1.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: 2016-
|
12
|
+
date: 2016-09-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -191,8 +191,12 @@ files:
|
|
191
191
|
- bin/opsicle
|
192
192
|
- lib/opsicle.rb
|
193
193
|
- lib/opsicle/client.rb
|
194
|
+
- lib/opsicle/cloneable_instance.rb
|
195
|
+
- lib/opsicle/cloneable_layer.rb
|
196
|
+
- lib/opsicle/cloneable_stack.rb
|
194
197
|
- lib/opsicle/commands.rb
|
195
198
|
- lib/opsicle/commands/chef_update.rb
|
199
|
+
- lib/opsicle/commands/clone_instance.rb
|
196
200
|
- lib/opsicle/commands/deploy.rb
|
197
201
|
- lib/opsicle/commands/execute_recipes.rb
|
198
202
|
- lib/opsicle/commands/failure_log.rb
|
@@ -231,7 +235,11 @@ files:
|
|
231
235
|
- lib/opsicle/user_profile.rb
|
232
236
|
- lib/opsicle/version.rb
|
233
237
|
- spec/opsicle/client_spec.rb
|
238
|
+
- spec/opsicle/cloneable_instance_spec.rb
|
239
|
+
- spec/opsicle/cloneable_layer_spec.rb
|
240
|
+
- spec/opsicle/cloneable_stack_spec.rb
|
234
241
|
- spec/opsicle/commands/chef_update_spec.rb
|
242
|
+
- spec/opsicle/commands/clone_instance_spec.rb
|
235
243
|
- spec/opsicle/commands/deploy_spec.rb
|
236
244
|
- spec/opsicle/commands/execute_recipes_spec.rb
|
237
245
|
- spec/opsicle/commands/failure_log_spec.rb
|
@@ -280,7 +288,11 @@ specification_version: 4
|
|
280
288
|
summary: An opsworks specific abstraction on top of the aws sdk
|
281
289
|
test_files:
|
282
290
|
- spec/opsicle/client_spec.rb
|
291
|
+
- spec/opsicle/cloneable_instance_spec.rb
|
292
|
+
- spec/opsicle/cloneable_layer_spec.rb
|
293
|
+
- spec/opsicle/cloneable_stack_spec.rb
|
283
294
|
- spec/opsicle/commands/chef_update_spec.rb
|
295
|
+
- spec/opsicle/commands/clone_instance_spec.rb
|
284
296
|
- spec/opsicle/commands/deploy_spec.rb
|
285
297
|
- spec/opsicle/commands/execute_recipes_spec.rb
|
286
298
|
- spec/opsicle/commands/failure_log_spec.rb
|