qops 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dd70c30cc7c37b5ecd6518aed0f7a7acbb2f7674
4
- data.tar.gz: a565c04736b4e3e6248a08093a4f72c29825a64a
3
+ metadata.gz: 162f89d3372a53371e18045f54ef22d6b1be4d4e
4
+ data.tar.gz: a2532b2299fcdb585506a0d7717cf079a1fa307b
5
5
  SHA512:
6
- metadata.gz: 3a665a0f24d8bd0870ea908baa0019f1edd3fd143d684c73282a6bc244c4fe421efc8c834746e151844860d7448dfffb4749dde4bb4ae4684ad6537caa536d72
7
- data.tar.gz: 522219fb5a32b183826ab4655a13b13390e22e993d6bcaa5e654615a7f53236b27df410e72b4ad6b22d0a48413b08e4c4d6da12b15c3fe466d11bb2341e57262
6
+ metadata.gz: 5360220d992d093303b5a2423ebc41d44de8447e4a7bd03384f4094b6d2f6f48b66dbb051f47bb6da8e86d2ff434d480944af75848aa1d2f7b0bc52bb2784015
7
+ data.tar.gz: d66505a29b10ef61410553ccb214ae83957e55801aa06244cc798c93ba31a3406225fc829d3553a36b24736e6601d5ba84ef0b9423da56351cafda903c3155eb
@@ -16,6 +16,7 @@ require_relative 'qops/helpers'
16
16
  require_relative 'qops/deployment/helpers'
17
17
  require_relative 'qops/deployment/app'
18
18
  require_relative 'qops/deployment/instances'
19
+ require_relative 'qops/deployment/stacks'
19
20
  require_relative 'qops/cookbook/cookbook'
20
21
 
21
22
  # Migrate this into quandl config project
@@ -130,10 +130,14 @@ class Qops::Cookbook < Thor
130
130
  end
131
131
 
132
132
  def s3
133
- @s3 ||= Aws::S3::Client.new(
134
- region: 'us-east-1',
135
- credentials: config.opsworks.config.credentials.credentials
136
- )
133
+ @s3 ||= Aws::S3::Client.new(**aws_configs)
134
+ end
135
+
136
+ def aws_configs
137
+ aws_config = { region: 'us-east-1' }
138
+ # use the profile if found
139
+ options[:profile] ? aws_config[:profile] = options[:profile] : aws_config[:credentials] = config.opsworks.config.credentials.credentials
140
+ aws_config
137
141
  end
138
142
 
139
143
  def local_artifact_file
@@ -103,15 +103,17 @@ class Qops::Deploy < Thor
103
103
  if config.application_id
104
104
  application_name = config.opsworks.describe_apps(app_ids: [config.application_id]).apps.first.name
105
105
 
106
- @_custom_json[:deploy] = {
107
- revision: revision_used,
108
- # the following is to be deprecated in favor of the former...
109
- application_name => {
110
- scm: {
111
- revision: revision_used
112
- }
113
- }
114
- }
106
+ @_custom_json[:deploy] = if config.chef_version >= 12
107
+ { revision: revision_used }
108
+ else
109
+ {
110
+ application_name => {
111
+ scm: {
112
+ revision: revision_used
113
+ }
114
+ }
115
+ }
116
+ end
115
117
  end
116
118
 
117
119
  if options[:custom_json].present?
@@ -7,15 +7,16 @@ module Qops::DeployHelpers
7
7
  class_option :custom_json, type: :string, aliases: '-j', desc: 'A custom json that will be used during a deployment of the app. ex: \'{ "custom_attrs": "are awesome!"}\''
8
8
  class_option :branch, type: :string, aliases: '-b', desc: 'The branch to use when deploying to staging type environments'
9
9
  class_option :hostname, type: :string, aliases: '-h', desc: 'Fully override the hostname that qops would normally give the instance'
10
+ class_option :profile, type: :string, aliases: '-p', desc: 'An AWS profile to use'
11
+ class_option :force_config, type: :boolean, aliases: '-f', desc: 'force qops to read options from config. by default qops will search aws opsworks stack'
10
12
  end
11
13
 
12
14
  private
13
15
 
14
16
  def config
15
17
  return @_config if @_config
16
-
17
18
  Qops::Environment.notifiers
18
- @_config ||= Qops::Environment.new
19
+ @_config ||= Qops::Environment.new(profile: options[:profile], force_config: options[:force_config])
19
20
 
20
21
  fail "Invalid configure deploy_type detected: #{@_config.deploy_type}" unless %w[staging production].include?(@_config.deploy_type)
21
22
 
@@ -113,4 +114,17 @@ module Qops::DeployHelpers
113
114
  'master'
114
115
  end
115
116
  end
117
+
118
+ def show_stack(options = {})
119
+ stack = config.stack(options)
120
+ {
121
+ name: stack.name,
122
+ stack_id: stack.stack_id,
123
+ subnet: stack.default_subnet_id,
124
+ layers: config.layers(options).map { |layer| layer.to_h.slice(:name, :layer_id, :shortname) },
125
+ apps: config.apps(options).map { |app| app.to_h.slice(:name, :app_id) },
126
+ config_manager: stack.configuration_manager.to_h,
127
+ default_os: stack.default_os
128
+ }
129
+ end
116
130
  end
@@ -103,8 +103,8 @@ class Qops::Instance < Thor # rubocop:disable Metrics/ClassLength
103
103
  # For Elasticsearch cluster, register with public elb
104
104
  if config.option?(:public_search_elb)
105
105
  print "Register instance #{instance.ec2_instance_id} to elb #{config.public_search_elb}"
106
- elb.register_instances_with_load_balancer(load_balancer_name: config.public_search_elb.to_s,
107
- instances: [{ instance_id: instance.ec2_instance_id.to_s }])
106
+ config.elb.register_instances_with_load_balancer(load_balancer_name: config.public_search_elb.to_s,
107
+ instances: [{ instance_id: instance.ec2_instance_id.to_s }])
108
108
  end
109
109
 
110
110
  # Deploy the latest code to instance
@@ -250,13 +250,6 @@ class Qops::Instance < Thor # rubocop:disable Metrics/ClassLength
250
250
 
251
251
  private
252
252
 
253
- def elb
254
- @elb ||= Aws::ElasticLoadBalancing::Client.new(
255
- region: 'us-east-1',
256
- credentials: config.opsworks.config.credentials.credentials
257
- )
258
- end
259
-
260
253
  def setup_instance(instance, initial_instance_state, manifest)
261
254
  print 'Setup instance ...'
262
255
 
@@ -313,7 +306,7 @@ class Qops::Instance < Thor # rubocop:disable Metrics/ClassLength
313
306
 
314
307
  # For Elasticsearch cluster, remove from from public elb
315
308
  if config.option?(:public_search_elb)
316
- elb.deregister_instances_from_load_balancer(
309
+ config.elb.deregister_instances_from_load_balancer(
317
310
  load_balancer_name: config.public_search_elb.to_s,
318
311
  instances: [{ instance_id: instance.ec2_instance_id.to_s }]
319
312
  )
@@ -0,0 +1,10 @@
1
+ class Qops::Stack < Thor
2
+ include Qops::DeployHelpers
3
+
4
+ desc 'describe', 'show basic stack info'
5
+ method_option :name, type: :string, aliases: '-n', desc: 'describe the stack with matching name'
6
+ def describe
7
+ initialize_run
8
+ puts JSON.pretty_generate(show_stack(name: options[:name]))
9
+ end
10
+ end
@@ -31,20 +31,69 @@ module Qops
31
31
  end
32
32
  end
33
33
 
34
- def initialize
35
- %w[deploy_type region stack_id app_name].each do |v|
34
+ def initialize(profile: nil, force_config: false)
35
+ @_aws_config = { region: configuration.region }
36
+ @_aws_config[:profile] = profile unless profile.nil?
37
+ @_force_config = force_config
38
+ puts Rainbow("using aws profile #{profile}").bg(:black).green unless profile.nil?
39
+
40
+ %w[deploy_type region app_name].each do |v|
36
41
  fail "Please configure #{v} before continuing." unless option?(v)
37
42
  end
38
43
 
44
+ fail 'Please configure the layer_name if you are allowing qops to search aws stacks' unless option?('layer_name')
45
+
46
+ # if being forced to use config , then stack_id is a requirement
47
+ fail 'Please configure stack_id or stack_name before continuing' unless option?('stack_id') || option?('stack_name')
48
+
39
49
  begin
40
- opsworks.config.credentials.credentials
50
+ opsworks.config.credentials.credentials unless profile
41
51
  rescue => e # rubocop:disable Lint/RescueWithoutErrorClass
42
52
  raise "There may be a problem with your aws credentials. Please correct with `aws configure`. Error: #{e}"
43
53
  end
44
54
  end
45
55
 
46
- def application_id
47
- configuration.application_id unless configuration.application_id.blank?
56
+ def stack(options = {})
57
+ return @_stack if @_stack
58
+ # find out if the config is using stack id or name
59
+ key = search_key(options)
60
+ value = options[key] || configuration.send(key)
61
+ # aws uses the term 'name' to reference a stack name
62
+ key = :name if key == :stack_name
63
+ @_stack = search_stack(key, value)
64
+ end
65
+
66
+ def stack_id(options = {})
67
+ return configuration.stack_id if @_force_config
68
+ stack(options).stack_id
69
+ end
70
+
71
+ def subnet(options = {})
72
+ return configuration.subnet if @_force_config
73
+ stack(options).default_subnet_id
74
+ end
75
+
76
+ def layers(_options = {})
77
+ opsworks.describe_layers(stack_id: stack_id).layers
78
+ end
79
+
80
+ def layer_id(options = {})
81
+ return configuration.layer_id if @_force_config
82
+ name = options[:layer_name] || configuration.layer_name
83
+ layers.find { |layer| layer.name.casecmp(name) }.layer_id
84
+ end
85
+
86
+ def chef_version(options = {})
87
+ stack(options).configuration_manager.version.to_f
88
+ end
89
+
90
+ def apps(_options = {})
91
+ opsworks.describe_apps(stack_id: stack_id).apps
92
+ end
93
+
94
+ def application_id(options = {})
95
+ return configuration.application_id if @_force_config
96
+ apps(options).first.app_id
48
97
  end
49
98
 
50
99
  def deploy_type
@@ -67,8 +116,9 @@ module Qops
67
116
  configuration.autoscale_type || nil
68
117
  end
69
118
 
70
- def opsworks_os
71
- configuration.os || 'Ubuntu 14.04 LTS'
119
+ def opsworks_os(options = {})
120
+ return configuration.os if @_force_config
121
+ find_stack(options).default_os
72
122
  end
73
123
 
74
124
  # Default 1 days
@@ -85,11 +135,15 @@ module Qops
85
135
  end
86
136
 
87
137
  def opsworks
88
- @_opsworks_client ||= Aws::OpsWorks::Client.new(region: configuration.region)
138
+ @_opsworks_client ||= Aws::OpsWorks::Client.new(**@_aws_config)
89
139
  end
90
140
 
91
141
  def ec2
92
- @_ec2_client ||= Aws::EC2::Client.new(region: configuration.region)
142
+ @_ec2_client ||= Aws::EC2::Client.new(**@_aws_config)
143
+ end
144
+
145
+ def elb
146
+ @_elb_client ||= Aws::ElasticLoadBalancing::Client.new(region: 'us-east-1', profile: @_aws_config[:profile])
93
147
  end
94
148
 
95
149
  def cookbook_json
@@ -114,6 +168,32 @@ module Qops
114
168
 
115
169
  private
116
170
 
171
+ def identity_from_config
172
+ configuration.stack_id ? :stack_id : :stack_name
173
+ end
174
+
175
+ def search_key(options = {})
176
+ if !options[:name].nil?
177
+ :name
178
+ elsif !options[:stack_id].nil?
179
+ :stack_id
180
+ else
181
+ id = identity_from_config
182
+ msg = Rainbow("Using opsworks.yml config #{id}: #{configuration.send(id)}")
183
+ puts(msg.bg(:black).green)
184
+ id
185
+ end
186
+ end
187
+
188
+ def search_stack(key, value)
189
+ stack = opsworks.describe_stacks.stacks.find { |s| s.send(key) == value }
190
+ unless stack
191
+ puts Rainbow("Could not find stack with #{key} = #{value}").bg(:black).red
192
+ exit(-1)
193
+ end
194
+ stack
195
+ end
196
+
117
197
  def method_missing(method_sym, *arguments, &block) # rubocop:disable Style/MethodMissing
118
198
  if configuration.respond_to?(method_sym)
119
199
  configuration.send(method_sym, *arguments, &block)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qops
4
- VERSION = '1.5.0'.freeze
4
+ VERSION = '1.6.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qops
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Basset
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2017-09-25 00:00:00.000000000 Z
15
+ date: 2017-10-18 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: qthor
@@ -32,16 +32,16 @@ dependencies:
32
32
  name: aws-sdk
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - ">="
35
+ - - "~>"
36
36
  - !ruby/object:Gem::Version
37
- version: 2.0.41
37
+ version: '3.0'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
- - - ">="
42
+ - - "~>"
43
43
  - !ruby/object:Gem::Version
44
- version: 2.0.41
44
+ version: '3.0'
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: quandl-config
47
47
  requirement: !ruby/object:Gem::Requirement
@@ -113,6 +113,7 @@ files:
113
113
  - lib/qops/deployment/app.rb
114
114
  - lib/qops/deployment/helpers.rb
115
115
  - lib/qops/deployment/instances.rb
116
+ - lib/qops/deployment/stacks.rb
116
117
  - lib/qops/environment.rb
117
118
  - lib/qops/helpers.rb
118
119
  - lib/qops/version.rb
@@ -136,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
137
  version: '0'
137
138
  requirements: []
138
139
  rubyforge_project:
139
- rubygems_version: 2.6.13
140
+ rubygems_version: 2.6.12
140
141
  signing_key:
141
142
  specification_version: 4
142
143
  summary: Helper commands for deployment of opsworks projects.