Class: OpsWorks::Stack

Inherits:
Resource show all
Defined in:
lib/opsworks/stack.rb

Constant Summary collapse

AVAILABLE_CHEF_VERSIONS =
%w(0.9 11.4 11.10).freeze
DEPLOY_NO_INSTANCES_ERROR =
'Please provide at least an instance ID of ' \
'one running instance'.freeze

Instance Attribute Summary collapse

Attributes inherited from Resource

#client

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Resource

account, #initialize

Constructor Details

This class inherits a constructor from OpsWorks::Resource

Instance Attribute Details

#custom_jsonObject

Returns the value of attribute custom_json.



3
4
5
# File 'lib/opsworks/stack.rb', line 3

def custom_json
  @custom_json
end

#idObject

Returns the value of attribute id.



3
4
5
# File 'lib/opsworks/stack.rb', line 3

def id
  @id
end

#nameObject

Returns the value of attribute name.



3
4
5
# File 'lib/opsworks/stack.rb', line 3

def name
  @name
end

Class Method Details

.activeObject



36
37
38
# File 'lib/opsworks/stack.rb', line 36

def self.active
  all.select(&:active?)
end

.allObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/opsworks/stack.rb', line 9

def self.all
  regions = Aws.partition('aws').regions.select do |region|
    region.services.include?('OpsWorks')
  end.map(&:name)

  stack_queue = Queue.new

  threads = regions.map do |region|
    Thread.new do
      client = Aws::OpsWorks::Client.new(region: region)
      client.describe_stacks.stacks.each do |stack|
        stack_queue << new(
          client,
          id: stack.stack_id,
          name: stack.name,
          custom_json: JSON.parse(stack.custom_json || '{}')
        )
      end
    end
  end
  threads.each(&:join)

  stacks = []
  stacks << stack_queue.pop until stack_queue.empty?
  stacks
end

.find_by_name(name) ⇒ Object



40
41
42
# File 'lib/opsworks/stack.rb', line 40

def self.find_by_name(name)
  all.find { |stack| stack.name == name }
end

.latest_chef_versionObject



44
45
46
# File 'lib/opsworks/stack.rb', line 44

def self.latest_chef_version
  AVAILABLE_CHEF_VERSIONS.last
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/opsworks/stack.rb', line 145

def active?
  instances.any?(&:online?)
end

#appsObject



48
49
50
# File 'lib/opsworks/stack.rb', line 48

def apps
  @apps ||= initialize_apps
end

#create_app(name, options = {}) ⇒ Object



162
163
164
165
# File 'lib/opsworks/stack.rb', line 162

def create_app(name, options = {})
  options = options.slice(:type, :shortname).merge(stack_id: id, name: name)
  client.create_app(options)
end

#create_deployment(options = {}) ⇒ Object



135
136
137
138
139
140
141
142
143
# File 'lib/opsworks/stack.rb', line 135

def create_deployment(options = {})
  response = client.create_deployment(
    options.merge(stack_id: id)
  )
rescue Aws::OpsWorks::Errors::ValidationException => e
  raise unless e.message == DEPLOY_NO_INSTANCES_ERROR
else
  Deployment.from_response(client, response)
end

#custom_json_at(key) ⇒ Object



149
150
151
# File 'lib/opsworks/stack.rb', line 149

def custom_json_at(key)
  JsonPath.new(key).first(custom_json)
end

#deploy_app(app, layer: nil, args: {}) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/opsworks/stack.rb', line 115

def deploy_app(app, layer: nil, args: {})
  raise 'App not found' unless app && app.id

  deploy_args = {
    app_id: app.id,
    command: {
      name: 'deploy',
      args: args
    }
  }

  if layer
    layer = layers.find { |l| l.shortname == layer }
    raise "Layer #{layer} not found" unless layer
    deploy_args[:layer_ids] = [layer.id]
  end

  create_deployment(**deploy_args)
end

#deploymentsObject



72
73
74
# File 'lib/opsworks/stack.rb', line 72

def deployments
  @deployments ||= initialize_deployments
end

#execute_recipe(recipe) ⇒ Object



106
107
108
109
110
111
112
113
# File 'lib/opsworks/stack.rb', line 106

def execute_recipe(recipe)
  create_deployment(
    command: {
      name: 'execute_recipes',
      args: { 'recipes' => [recipe] }
    }
  )
end

#find_app_by_name(name) ⇒ Object



60
61
62
# File 'lib/opsworks/stack.rb', line 60

def find_app_by_name(name)
  apps.find { |app| app.name == name }
end

#find_permission_by_user(name) ⇒ Object



56
57
58
# File 'lib/opsworks/stack.rb', line 56

def find_permission_by_user(name)
  permissions.find { |permission| permission.user == name }
end

#instancesObject



64
65
66
# File 'lib/opsworks/stack.rb', line 64

def instances
  @instances ||= initialize_instances
end

#layersObject



68
69
70
# File 'lib/opsworks/stack.rb', line 68

def layers
  @layers ||= initialize_layers
end

#permissionsObject



52
53
54
# File 'lib/opsworks/stack.rb', line 52

def permissions
  @permissions ||= initialize_permissions
end

#set_custom_json_at(key, value) ⇒ Object



153
154
155
156
157
158
159
160
# File 'lib/opsworks/stack.rb', line 153

def set_custom_json_at(key, value)
  self.custom_json = replace_hash_at_path(custom_json, key, value)

  client.update_stack(
    stack_id: id,
    custom_json: JSON.pretty_generate(custom_json)
  )
end

#settled?Boolean

Returns:

  • (Boolean)

Raises:



167
168
169
170
171
172
# File 'lib/opsworks/stack.rb', line 167

def settled?
  instances = initialize_instances
  fatal = instances.select(&:fatal?)
  raise Errors::StackInFatalState.new(self, fatal) if fatal.any?
  instances.all?(&:settled?)
end

#update_chef(options) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/opsworks/stack.rb', line 76

def update_chef(options)
  params = {
    stack_id: id,
    configuration_manager: { name: 'Chef', version: options[:version] },
    chef_configuration: {
      manage_berkshelf: options[:manage_berkshelf],
      berkshelf_version: options[:berkshelf_version]
    }
  }
  if options[:cookbook_git_url]
    params[:custom_cookbooks_source] = {
      type: 'git',
      url: options[:cookbook_git_url],
      revision: options[:cookbook_branch] || 'master'
    }
  elsif options[:cookbook_s3_url]
    params[:custom_cookbooks_source] = {
      type: 's3',
      url: options[:cookbook_s3_url],
      username: options[:cookbook_username],
      password: options[:cookbook_password]
    }
  end
  client.update_stack(params)
end

#update_custom_cookbooksObject



102
103
104
# File 'lib/opsworks/stack.rb', line 102

def update_custom_cookbooks
  create_deployment(command: { name: 'update_custom_cookbooks' })
end