Class: Opsicle::CreatableInstance

Inherits:
Object
  • Object
show all
Defined in:
lib/opsicle/creatable_instance.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(layer, stack, opsworks, ec2, cli) ⇒ CreatableInstance

Returns a new instance of CreatableInstance.



5
6
7
8
9
10
11
12
# File 'lib/opsicle/creatable_instance.rb', line 5

def initialize(layer, stack, opsworks, ec2, cli)
  self.layer = layer
  self.stack = stack
  self.opsworks = opsworks
  self.ec2 = ec2
  self.cli = cli
  self.new_instance_id = nil
end

Instance Attribute Details

#cliObject

Returns the value of attribute cli.



3
4
5
# File 'lib/opsicle/creatable_instance.rb', line 3

def cli
  @cli
end

#ec2Object

Returns the value of attribute ec2.



3
4
5
# File 'lib/opsicle/creatable_instance.rb', line 3

def ec2
  @ec2
end

#layerObject

Returns the value of attribute layer.



3
4
5
# File 'lib/opsicle/creatable_instance.rb', line 3

def layer
  @layer
end

#new_instance_idObject

Returns the value of attribute new_instance_id.



3
4
5
# File 'lib/opsicle/creatable_instance.rb', line 3

def new_instance_id
  @new_instance_id
end

#opsworksObject

Returns the value of attribute opsworks.



3
4
5
# File 'lib/opsicle/creatable_instance.rb', line 3

def opsworks
  @opsworks
end

#stackObject

Returns the value of attribute stack.



3
4
5
# File 'lib/opsicle/creatable_instance.rb', line 3

def stack
  @stack
end

Instance Method Details

#add_tagsObject



167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/opsicle/creatable_instance.rb', line 167

def add_tags
  if ask_to_add_tags
    tags = []

    tag_count.times do
      tags << define_tag
    end

    ec2_instance_id = @opsworks.describe_instances(instance_ids: [new_instance_id]).instances.first.ec2_instance_id
    @ec2.create_tags(resources: [ ec2_instance_id ], tags: tags)
  end
end

#ask_for_new_option(description) ⇒ Object



130
131
132
# File 'lib/opsicle/creatable_instance.rb', line 130

def ask_for_new_option(description)
  @cli.ask("Please write in the new #{description} and press ENTER:")
end

#ask_for_overriding_permission(description, overriding_all) ⇒ Object



134
135
136
137
138
139
140
141
# File 'lib/opsicle/creatable_instance.rb', line 134

def ask_for_overriding_permission(description, overriding_all)
  if overriding_all
    ans = @cli.ask("Do you wish to override this #{description}? By overriding, you are choosing to override the current #{description} for all of the following instances you're cloning.\n1) Yes\n2) No", Integer)
  else
    ans = @cli.ask("Do you wish to override this #{description}?\n1) Yes\n2) No", Integer)
  end
  ans == 1
end

#ask_for_possible_options(arr, description) ⇒ Object



124
125
126
127
128
# File 'lib/opsicle/creatable_instance.rb', line 124

def ask_for_possible_options(arr, description)
  arr.each_with_index { |id, index| puts "#{index.to_i + 1}) #{id}"}
  id_index = @cli.ask("Which #{description}?\n", Integer) { |q| q.in = 1..arr.length.to_i } - 1
  arr[id_index]
end

#ask_to_add_tagsObject



190
191
192
193
# File 'lib/opsicle/creatable_instance.rb', line 190

def ask_to_add_tags
  ans = @cli.ask("Do you wish to add EC2 tags to this instance?\n1) Yes\n2) No", Integer)
  ans == 1
end

#ask_to_start_instanceObject



195
196
197
198
# File 'lib/opsicle/creatable_instance.rb', line 195

def ask_to_start_instance
  ans = @cli.ask("Do you wish to start this new instance?\n1) Yes\n2) No", Integer)
  ans == 1
end

#auto_generated_hostnameObject



43
44
45
46
47
# File 'lib/opsicle/creatable_instance.rb', line 43

def auto_generated_hostname
  if hostname =~ /\d\d\z/
    increment_hostname
  end
end

#create(options) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/opsicle/creatable_instance.rb', line 14

def create(options)
  puts "\nCreating an instance..."

  new_instance_hostname = make_new_hostname
  puts ""
  ami_id = select_ami_id
  puts ""
  agent_version = select_agent_version
  puts ""
  subnet_id = select_subnet_id
  puts ""
  instance_type = ask_for_new_option('instance type')
  puts ""

  create_new_instance(new_instance_hostname, instance_type, ami_id, agent_version, subnet_id)
  start_new_instance
end

#create_new_instance(new_instance_hostname, instance_type, ami_id, agent_version, subnet_id) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/opsicle/creatable_instance.rb', line 143

def create_new_instance(new_instance_hostname, instance_type, ami_id, agent_version, subnet_id)
  new_instance = @opsworks.create_instance({
    stack_id: self.stack.id, # required
    layer_ids: [self.layer.layer_id], # required
    instance_type: instance_type, # required
    hostname: new_instance_hostname,
    ami_id: ami_id,
    subnet_id: subnet_id,
    agent_version: agent_version,
    os: os || 'Custom'
  })
  self.new_instance_id = new_instance.instance_id
  self.layer.add_new_instance(new_instance_id)
  puts "New instance #{new_instance_hostname} has been created: #{new_instance_id}"
end

#define_tagObject



180
181
182
183
184
# File 'lib/opsicle/creatable_instance.rb', line 180

def define_tag
  tag_key = ask_for_new_option('tag name')
  tag_value = ask_for_new_option('tag value')
  { key: tag_key, value: tag_value }
end

#find_subnet_name(subnet) ⇒ Object



69
70
71
72
73
74
# File 'lib/opsicle/creatable_instance.rb', line 69

def find_subnet_name(subnet)
  tags = subnet.tags
  tag = nil
  tags.each { |t| tag = t if t.key == 'Name' }
  tag.value if tag
end

#hostnameObject



39
40
41
# File 'lib/opsicle/creatable_instance.rb', line 39

def hostname
  self.layer.instances.first.hostname if self.layer.instances.first
end

#hostname_unique?(name) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/opsicle/creatable_instance.rb', line 65

def hostname_unique?(name)
  !sibling_hostnames.include?(name)
end

#increment_hostnameObject



53
54
55
56
57
58
59
# File 'lib/opsicle/creatable_instance.rb', line 53

def increment_hostname
  name = hostname
  until hostname_unique?(name) do
    name = name.gsub(/(\d\d\z)/) { "#{($1.to_i + 1).to_s.rjust(2, '0')}" }
  end
  name
end

#make_new_hostnameObject



32
33
34
35
36
37
# File 'lib/opsicle/creatable_instance.rb', line 32

def make_new_hostname
  new_instance_hostname = auto_generated_hostname || nil
  puts "\nAutomatically generated hostname: #{new_instance_hostname}\n" if new_instance_hostname
  new_instance_hostname = ask_for_new_option("instance's hostname") if ask_for_overriding_permission("hostname", false)
  new_instance_hostname
end

#osObject



120
121
122
# File 'lib/opsicle/creatable_instance.rb', line 120

def os
  self.layer.instances.first.os if self.layer.instances.first
end

#select_agent_versionObject



91
92
93
94
95
96
97
# File 'lib/opsicle/creatable_instance.rb', line 91

def select_agent_version
  agents = @opsworks.describe_agent_versions(stack_id: @stack.id).agent_versions
  version_ids = agents.collect { |i| i.version }.uniq
  agent_version = ask_for_possible_options(version_ids, "agent version")
  self.layer.agent_version = agent_version
  agent_version
end

#select_ami_idObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/opsicle/creatable_instance.rb', line 76

def select_ami_id
  instances = @opsworks.describe_instances(stack_id: @stack.id).instances
  ami_ids = instances.collect { |i| i.ami_id }.uniq
  ami_ids << "Provide a different AMI ID."
  ami_id = ask_for_possible_options(ami_ids, "AMI ID")

  if ami_id == "Provide a different AMI ID."
    ami_id = ask_for_new_option('AMI ID')
  end

  self.layer.ami_id = ami_id

  ami_id
end

#select_subnet_idObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/opsicle/creatable_instance.rb', line 99

def select_subnet_id
  ec2_subnets = ec2.describe_subnets.subnets
  subnets = []

  ec2_subnets.each do |subnet|
    if subnet.vpc_id == stack.vpc_id
      subnet_name = find_subnet_name(subnet)
      zone_name = subnet.availability_zone
      subnet_id = subnet.subnet_id
      subnets << "\"#{subnet_name}\" #{zone_name} (#{subnet_id})"
    end
  end

  subnets = subnets.sort
  subnet_id = ask_for_possible_options(subnets, "subnet ID")
  subnet_id = subnet_id.scan(/(subnet-[a-z0-9]*)/).first.first if subnet_id

  self.layer.subnet_id = subnet_id
  subnet_id
end

#sibling_hostnamesObject



49
50
51
# File 'lib/opsicle/creatable_instance.rb', line 49

def sibling_hostnames
  self.layer.instances.collect { |instance| instance.hostname }
end

#start_new_instanceObject



159
160
161
162
163
164
165
# File 'lib/opsicle/creatable_instance.rb', line 159

def start_new_instance
  if ask_to_start_instance
    @opsworks.start_instance(instance_id: self.new_instance_id)
    puts "\nNew instance is starting…"
    add_tags
  end
end

#tag_countObject



186
187
188
# File 'lib/opsicle/creatable_instance.rb', line 186

def tag_count
  @cli.ask("How many tags do you wish to add? Please write in the number as an integer and press ENTER:").to_i
end