ops_manager_cli 0.5.4 → 0.7.1

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: e200f84440299495f24ab5116f42ee811619f202
4
- data.tar.gz: 34f6349b50099e31de0995fc004d602a47712cdb
3
+ metadata.gz: 8992b156cebae9e672d078b6da9b8657a650b093
4
+ data.tar.gz: 70fab26214ffab2248756aa0e281fb287acd0e5e
5
5
  SHA512:
6
- metadata.gz: adb1d901dd22f681e4f14e1d90a92216d978d650747f3359895a5db86b8ea13716a71608c8729dc653a7b373ea7532c103ce1e5b7f969e1e9f3ae9d071a1a54e
7
- data.tar.gz: 3336b1e3aecfcc730fff8e74ddbd5f928640f3bff5047f690b83c63477b91f25695cb77b0c0441f675270324ee732b3e660a4e4cd4350601d624e34208dec29c
6
+ metadata.gz: c2e769b03f59448e5e415f141d2dac8d6009ae272c748c20aabb98b8c6ea6b70d38ada89d20c335e13daafe79fbb9ec9a44be775a7ca3750d69396a20459606e
7
+ data.tar.gz: 3ef3595a66344221983bdde63e1c770a3422453286656bdf572f2d8b4f66c6e8a4e01ed8549e2bd4672246c4f508e3d789fcee5542fd5f67acc69f138f07d201
data/CHANGELOG.md CHANGED
@@ -1,17 +1,28 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.5.4](https://github.com/compozed/ops_manager_cli/tree/v0.5.4) (2017-06-27)
4
+ [Full Changelog](https://github.com/compozed/ops_manager_cli/compare/v0.5.3...v0.5.4)
5
+
6
+ ## [v0.5.3](https://github.com/compozed/ops_manager_cli/tree/v0.5.3) (2017-06-27)
7
+ [Full Changelog](https://github.com/compozed/ops_manager_cli/compare/v0.5.2...v0.5.3)
8
+
3
9
  ## [v0.5.2](https://github.com/compozed/ops_manager_cli/tree/v0.5.2) (2017-06-27)
4
10
  [Full Changelog](https://github.com/compozed/ops_manager_cli/compare/v0.5.1...v0.5.2)
5
11
 
6
12
  **Closed issues:**
7
13
 
14
+ - CLI should check that UAA is available after Ops Manager upgrades [\#29](https://github.com/compozed/ops_manager_cli/issues/29)
15
+ - When upgrading opsman the token does not reset [\#27](https://github.com/compozed/ops_manager_cli/issues/27)
8
16
  - Support refresh tokens for re-authentication with UAA [\#24](https://github.com/compozed/ops_manager_cli/issues/24)
9
- - Upgrading product does not work with opsman\_cli 0.5.0 on opsman 1.9 [\#23](https://github.com/compozed/ops_manager_cli/issues/23)
10
17
  - Allow toggling ops\_manager.log [\#21](https://github.com/compozed/ops_manager_cli/issues/21)
11
18
 
12
19
  ## [v0.5.1](https://github.com/compozed/ops_manager_cli/tree/v0.5.1) (2017-01-25)
13
20
  [Full Changelog](https://github.com/compozed/ops_manager_cli/compare/v0.5.0...v0.5.1)
14
21
 
22
+ **Closed issues:**
23
+
24
+ - Upgrading product does not work with opsman\_cli 0.5.0 on opsman 1.9 [\#23](https://github.com/compozed/ops_manager_cli/issues/23)
25
+
15
26
  ## [v0.5.0](https://github.com/compozed/ops_manager_cli/tree/v0.5.0) (2017-01-24)
16
27
  [Full Changelog](https://github.com/compozed/ops_manager_cli/compare/v0.4.1...v0.5.0)
17
28
 
@@ -21,6 +32,7 @@
21
32
 
22
33
  **Closed issues:**
23
34
 
35
+ - Upgrade does not merge product installation settings [\#22](https://github.com/compozed/ops_manager_cli/issues/22)
24
36
  - ops\_manager curl -x PUT not working [\#17](https://github.com/compozed/ops_manager_cli/issues/17)
25
37
  - When uploading stemcell it does not show the correct output [\#15](https://github.com/compozed/ops_manager_cli/issues/15)
26
38
 
@@ -30,6 +42,7 @@
30
42
  **Fixed bugs:**
31
43
 
32
44
  - Director template generator does not delete UAA sensitive data [\#13](https://github.com/compozed/ops_manager_cli/issues/13)
45
+ - Product template generator does not delete stemcell metadata properties [\#12](https://github.com/compozed/ops_manager_cli/issues/12)
33
46
 
34
47
  ## [v0.4.0](https://github.com/compozed/ops_manager_cli/tree/v0.4.0) (2016-10-20)
35
48
  [Full Changelog](https://github.com/compozed/ops_manager_cli/compare/v0.3.0...v0.4.0)
@@ -37,12 +50,14 @@
37
50
  **Implemented enhancements:**
38
51
 
39
52
  - Improve output for appliance deploy/upgrade [\#11](https://github.com/compozed/ops_manager_cli/issues/11)
53
+ - Improve output for product deploy/upgrade [\#10](https://github.com/compozed/ops_manager_cli/issues/10)
40
54
  - Run errands when applying changes [\#9](https://github.com/compozed/ops_manager_cli/issues/9)
41
55
  - 1.8 support [\#5](https://github.com/compozed/ops_manager_cli/pull/5) ([bonzofenix](https://github.com/bonzofenix))
42
56
 
43
57
  **Fixed bugs:**
44
58
 
45
59
  - delete-unused-products command not working [\#8](https://github.com/compozed/ops_manager_cli/issues/8)
60
+ - Hardcoded user name admin when logging agains ops\_manager [\#2](https://github.com/compozed/ops_manager_cli/issues/2)
46
61
 
47
62
  **Closed issues:**
48
63
 
data/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  FROM ruby:2.3.0
2
2
 
3
3
  ENV GEM_NAME ops_manager_cli
4
- ENV GEM_VERSION 0.5.4
4
+ ENV GEM_VERSION 0.7.1
5
5
  ENV OVFTOOL_VERSION 4.1.0-2459827
6
6
  ENV OVFTOOL_INSTALLER VMware-ovftool-${OVFTOOL_VERSION}-lin.x86_64.bundle
7
7
  ARG DOWNLOAD_URL
@@ -154,6 +154,9 @@ class OpsManager
154
154
  http.use_ssl = true
155
155
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
156
156
  http.read_timeout = 1200
157
+
158
+ ctx = OpenSSL::SSL::SSLContext.new
159
+ ctx.ssl_version = :TLSv1_2
157
160
  end
158
161
  end
159
162
 
@@ -25,6 +25,10 @@ class OpsManager
25
25
  authenticated_get("/api/v0/staged/products", opts)
26
26
  end
27
27
 
28
+ def get_pending_changes(opts = {})
29
+ authenticated_get("/api/v0/staged/pending_changes", opts)
30
+ end
31
+
28
32
  def get_installation_settings(opts = {})
29
33
  print_green '====> Downloading installation settings ...'
30
34
  res = authenticated_get("/api/installation_settings", opts)
@@ -117,7 +121,7 @@ class OpsManager
117
121
 
118
122
  def get_diagnostic_report
119
123
  authenticated_get("/api/v0/diagnostic_report")
120
- rescue Errno::ETIMEDOUT , Errno::EHOSTUNREACH, Net::HTTPFatalError, Net::OpenTimeout
124
+ rescue Errno::ETIMEDOUT , Errno::EHOSTUNREACH, Net::HTTPFatalError, Net::OpenTimeout, HTTPClient::ConnectTimeoutError
121
125
  nil
122
126
  end
123
127
 
@@ -153,6 +157,23 @@ class OpsManager
153
157
  nil
154
158
  end
155
159
 
160
+ def pending_changes(opts = {})
161
+ print_green '====> Getting pending changes ...'
162
+ res = authenticated_get('/api/v0/staged/pending_changes')
163
+ pendingChanges = JSON.parse(res.body)
164
+
165
+ if pendingChanges['product_changes'].count == 0
166
+ puts "\nNo pending changes"
167
+ else
168
+ pendingChanges['product_changes'].each do |product|
169
+ puts "\n#{product['guid']}"
170
+ end
171
+ end
172
+
173
+ say_green 'done'
174
+ res
175
+ end
176
+
156
177
  def username
157
178
  @username ||= OpsManager.get_conf(:username)
158
179
  end
@@ -174,7 +195,23 @@ class OpsManager
174
195
  @access_token ||= get_token.info['access_token']
175
196
  end
176
197
 
198
+ def wait_for_https_alive(limit)
199
+ @retry_counter = 0
200
+ res = nil
201
+ until(@retry_counter >= limit or (res = check_alive).code.to_i < 400) do
202
+ sleep 1
203
+ @retry_counter += 1
204
+ end
205
+ res
206
+ end
207
+
177
208
  private
209
+ def check_alive
210
+ get("/")
211
+ rescue Net::OpenTimeout, Net::HTTPError, Net::HTTPFatalError, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET => e
212
+ Net::HTTPInternalServerError.new(1.0, 500, e.inspect)
213
+ end
214
+
178
215
  def token_issuer
179
216
  @token_issuer ||= CF::UAA::TokenIssuer.new(
180
217
  "https://#{target}/uaa", 'opsman', nil, skip_ssl_validation: true )
@@ -0,0 +1,89 @@
1
+ require 'fog/aws'
2
+ require 'ops_manager/appliance/base'
3
+
4
+ class OpsManager
5
+ module Appliance
6
+ class AWS < Base
7
+
8
+ def deploy_vm
9
+ image_id = ::YAML.load_file(ami_mapping_file)[config[:opts][:region]]
10
+
11
+ server = connection.servers.create(
12
+ block_device_mapping: [{
13
+ 'DeviceName' => '/dev/xvda',
14
+ 'Ebs.VolumeSize' => config[:opts][:disk_size_in_gb],
15
+ }],
16
+ key_name: config[:opts][:ssh_keypair_name],
17
+ flavor_id: config[:opts][:instance_type],
18
+ subnet_id: config[:opts][:subnet_id],
19
+ image_id: image_id,
20
+ private_ip_address: config[:ip],
21
+ security_group_ids: security_group_ids,
22
+ availability_zone: config[:opts][:availability_zone],
23
+ iam_instance_profile_name: config[:opts][:instance_profile_name],
24
+ tags: {
25
+ 'Name' => vm_name,
26
+ }
27
+ )
28
+ server.wait_for { ready? }
29
+ return server
30
+ end
31
+
32
+ def stop_current_vm(name)
33
+ server = connection.servers.all("private-ip-address" => config[:ip], "tag:Name" => name).first
34
+ if ! server
35
+ fail "VM not found matching IP '#{config[:ip]}', named '#{name}'"
36
+ end
37
+ server.stop
38
+ server.wait_for { server.state == "stopped" }
39
+
40
+ # Create ami of stopped server
41
+ response = connection.create_image(server.id, "#{name}-backup", "Backup of #{name}")
42
+ image = connection.images.get( response.data[:body]['imageId'])
43
+ image.wait_for { image.state == "available" }
44
+ if image.state != "available"
45
+ fail "Error creating backup AMI, bailing out before destroying the VM"
46
+ end
47
+
48
+ puts "Saved #{name} to AMI #{image.id} (#{name}-backup) for safe-keeping"
49
+
50
+ server.destroy
51
+ if !Fog.mocking?
52
+ server.wait_for { server.state == 'terminated' }
53
+ else
54
+ # Fog's mock doesn't support transitioning state from terminating -> terminated
55
+ # so we have to hack this here
56
+ server.wait_for { server.state == 'terminating' }
57
+ end
58
+ end
59
+
60
+ private
61
+ def ami_mapping_file
62
+ Dir.glob(config[:opts][:ami_mapping_file]).first
63
+ end
64
+
65
+ def security_group_ids
66
+ config[:opts][:security_groups].collect do |sg|
67
+ connection.security_groups.get(sg).group_id
68
+ end
69
+ end
70
+
71
+ def connection
72
+ if config[:opts][:use_iam_profile]
73
+ @connection ||= Fog::Compute.new({
74
+ provider: config[:provider],
75
+ use_iam_profile: config[:opts][:use_iam_profile],
76
+ aws_access_key_id: "",
77
+ aws_secret_access_key: "",
78
+ })
79
+ else
80
+ @connection ||= Fog::Compute.new({
81
+ provider: config[:provider],
82
+ aws_access_key_id: config[:opts][:access_key],
83
+ aws_secret_access_key: config[:opts][:secret_key],
84
+ })
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,23 @@
1
+
2
+ class OpsManager
3
+ module Appliance
4
+ class Base
5
+ attr_reader :config
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+ def deploy_vm
11
+ raise NotImplementedError.new("You must implement deploy_vm.")
12
+ end
13
+ def stop_current_vm(name)
14
+ raise NotImplementedError.new("You must implement stop_current_vm.")
15
+ end
16
+
17
+ private
18
+ def vm_name
19
+ @vm_name ||= "#{config[:name]}-#{config[:desired_version]}"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ require 'rbvmomi'
2
+ require "uri"
3
+ require 'shellwords'
4
+ require "ops_manager/logging"
5
+ require 'ops_manager/appliance/base'
6
+
7
+ class OpsManager
8
+ module Appliance
9
+ class Vsphere < Base
10
+ include OpsManager::Logging
11
+ attr_reader :config
12
+
13
+ def deploy_vm
14
+ print '====> Deploying ova ...'.green
15
+ vcenter_target= "vi://#{vcenter_username}:#{vcenter_password}@#{config[:opts][:vcenter][:host]}/#{config[:opts][:vcenter][:datacenter]}/host/#{config[:opts][:vcenter][:cluster]}"
16
+ cmd = "echo yes | ovftool --acceptAllEulas --noSSLVerify --powerOn --X:waitForIp --net:\"Network 1=#{config[:opts][:portgroup]}\" --name=#{vm_name} -ds=#{config[:opts][:datastore]} --prop:ip0=#{config[:ip]} --prop:netmask0=#{config[:opts][:netmask]} --prop:gateway=#{config[:opts][:gateway]} --prop:DNS=#{config[:opts][:dns]} --prop:ntp_servers=#{config[:opts][:ntp_servers].join(',')} --prop:admin_password=#{config[:password]} #{config[:opts][:ova_path]} #{vcenter_target}"
17
+ logger.info "Running: #{cmd}"
18
+ logger.info `#{cmd}`
19
+ puts 'done'.green
20
+ end
21
+
22
+ def stop_current_vm(name)
23
+ print "====> Stopping vm #{name} ...".green
24
+ dc = vim.serviceInstance.find_datacenter(config[:opts][:vcenter][:datacenter])
25
+ logger.info "finding vm: #{name}"
26
+ vm = dc.find_vm(name) or fail "VM not found"
27
+ vm.PowerOffVM_Task.wait_for_completion
28
+ puts 'done'.green
29
+ end
30
+
31
+ private
32
+ def vim
33
+ RbVmomi::VIM.connect host: config[:opts][:vcenter][:host], user: URI.unescape(config[:opts][:vcenter][:username]), password: URI.unescape(config[:opts][:vcenter][:password]), insecure: true
34
+ end
35
+
36
+ def vcenter_username
37
+ Shellwords.escape(URI.encode(config[:opts][:vcenter][:username]))
38
+ end
39
+
40
+ def vcenter_password
41
+ Shellwords.escape(URI.encode(config[:opts][:vcenter][:password]))
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+
@@ -1,15 +1,18 @@
1
1
  require "ops_manager/api/opsman"
2
2
  require "ops_manager/api/pivnet"
3
- require 'ops_manager/configs/opsman_deployment'
3
+ require 'ops_manager/config/opsman_deployment'
4
4
  require 'fileutils'
5
5
 
6
6
  class OpsManager::ApplianceDeployment
7
7
  extend Forwardable
8
+ attr_reader :config
9
+
8
10
  def_delegators :pivnet_api, :get_product_releases, :accept_product_release_eula,
9
11
  :get_product_release_files, :download_product_release_file
10
- def_delegators :opsman_api, :create_user, :trigger_installation, :get_installation_assets,
12
+ def_delegators :opsman_api, :create_user, :get_installation_assets,
11
13
  :get_installation_settings, :get_diagnostic_report, :upload_installation_assets, :get_ensure_availability,
12
- :import_stemcell, :target, :password, :username, :ops_manager_version= , :reset_access_token
14
+ :import_stemcell, :target, :password, :username, :ops_manager_version= , :reset_access_token, :get_pending_changes,
15
+ :wait_for_https_alive
13
16
 
14
17
  attr_reader :config_file
15
18
 
@@ -18,35 +21,37 @@ class OpsManager::ApplianceDeployment
18
21
  end
19
22
 
20
23
  def run
21
- OpsManager.set_conf(:target, config.ip)
22
- OpsManager.set_conf(:username, config.username)
23
- OpsManager.set_conf(:password, config.password)
24
- OpsManager.set_conf(:pivnet_token, config.pivnet_token)
24
+ OpsManager.set_conf(:target, config[:ip])
25
+ OpsManager.set_conf(:username, config[:username])
26
+ OpsManager.set_conf(:password, config[:password])
27
+ OpsManager.set_conf(:pivnet_token, config[:pivnet_token])
25
28
 
26
- self.extend(OpsManager::Deployments::Vsphere)
27
29
 
28
30
  case
29
31
  when current_version.empty?
30
- puts "No OpsManager deployed at #{config.ip}. Deploying ...".green
32
+ puts "No OpsManager deployed at #{config[:ip]}. Deploying ...".green
31
33
  deploy
32
34
  create_first_user
33
35
  when current_version < desired_version then
34
- puts "OpsManager at #{config.ip} version is #{current_version}. Upgrading to #{desired_version} .../".green
36
+ puts "OpsManager at #{config[:ip]} version is #{current_version}. Upgrading to #{desired_version} .../".green
35
37
  upgrade
36
38
  when current_version == desired_version then
37
- puts "OpsManager at #{config.ip} version is already #{config.desired_version}. Skiping ...".green
39
+ if pending_changes?
40
+ puts "OpsManager at #{config[:ip]} version has pending changes. Applying changes...".green
41
+ OpsManager::InstallationRunner.trigger!.wait_for_result
42
+ else
43
+ puts "OpsManager at #{config[:ip]} version is already #{config[:desired_version]}. Skiping ...".green
44
+ end
38
45
  end
39
46
 
40
47
  puts '====> Finish!'.green
41
48
  end
42
49
 
43
- def deploy
44
- deploy_vm(desired_vm_name , config.ip)
45
- end
46
-
47
- %w{ stop_current_vm deploy_vm }.each do |m|
48
- define_method(m) do
49
- raise NotImplementedError
50
+ def appliance
51
+ @appliance ||= if config[:provider] =~/vsphere/i
52
+ OpsManager::Appliance::Vsphere.new(config)
53
+ else
54
+ OpsManager::Appliance::AWS.new(config)
50
55
  end
51
56
  end
52
57
 
@@ -57,10 +62,15 @@ class OpsManager::ApplianceDeployment
57
62
  end
58
63
  end
59
64
 
65
+ def deploy
66
+ appliance.deploy_vm
67
+ wait_for_https_alive 300
68
+ end
69
+
60
70
  def upgrade
61
71
  get_installation_assets
62
72
  download_current_stemcells
63
- stop_current_vm(current_vm_name)
73
+ appliance.stop_current_vm(current_name)
64
74
  deploy
65
75
  upload_installation_assets
66
76
  wait_for_uaa
@@ -113,21 +123,30 @@ class OpsManager::ApplianceDeployment
113
123
  list_current_stemcells.each do |stemcell_version|
114
124
  release_id = find_stemcell_release(stemcell_version)
115
125
  accept_product_release_eula('stemcells', release_id )
116
- file_id, file_name = find_stemcell_file(release_id, /vsphere/)
126
+ stemcell_regex = /vsphere/
127
+ if config[:provider] == "AWS"
128
+ stemcell_regex = /aws/
129
+ end
130
+
131
+ file_id, file_name = find_stemcell_file(release_id, stemcell_regex)
117
132
  download_product_release_file('stemcells', release_id, file_id, write_to: "#{current_stemcell_dir}/#{file_name}")
118
133
  end
119
134
  end
120
135
 
121
136
  def new_vm_name
122
- @new_vm_name ||= "#{config.name}-#{config.desired_version}"
137
+ @new_vm_name ||= "#{config[:name]}-#{config[:desired_version]}"
123
138
  end
124
139
 
125
140
  def current_version
126
141
  @current_version ||= OpsManager::Semver.new(version_from_diagnostic_report)
127
142
  end
128
143
 
144
+ def current_name
145
+ @current_name ||= "#{config[:name]}-#{current_version}"
146
+ end
147
+
129
148
  def desired_version
130
- @desired_version ||= OpsManager::Semver.new(config.desired_version)
149
+ @desired_version ||= OpsManager::Semver.new(config[:desired_version])
131
150
  end
132
151
 
133
152
  def provision_stemcells
@@ -167,12 +186,9 @@ class OpsManager::ApplianceDeployment
167
186
  end
168
187
 
169
188
  def current_vm_name
170
- @current_vm_name ||= "#{config.name}-#{current_version}"
189
+ @current_vm_name ||= "#{config[:name]}-#{current_version}"
171
190
  end
172
191
 
173
- def desired_vm_name
174
- @desired_vm_name ||= "#{config.name}-#{config.desired_version}"
175
- end
176
192
 
177
193
  def pivnet_api
178
194
  @pivnet_api ||= OpsManager::Api::Pivnet.new
@@ -183,10 +199,10 @@ class OpsManager::ApplianceDeployment
183
199
  end
184
200
 
185
201
  def config
186
- parsed_yml = ::YAML.load_file(@config_file)
187
- @config ||= OpsManager::Configs::OpsmanDeployment.new(parsed_yml)
202
+ @config ||= OpsManager::Config::OpsmanDeployment.new(YAML.load_file(@config_file))
188
203
  end
189
204
 
205
+
190
206
  def desired_version?(version)
191
207
  !!(desired_version.to_s =~/#{version}/)
192
208
  end
@@ -206,4 +222,8 @@ class OpsManager::ApplianceDeployment
206
222
  def current_stemcell_dir
207
223
  "/tmp/current_stemcells"
208
224
  end
225
+
226
+ def pending_changes?
227
+ !JSON.parse(get_pending_changes.body).fetch('product_changes').empty?
228
+ end
209
229
  end
@@ -72,6 +72,12 @@ class OpsManager
72
72
  end
73
73
  end
74
74
 
75
+ class PendingChanges < Clamp::Command
76
+ def execute
77
+ OpsManager::Api::Opsman.new.pending_changes
78
+ end
79
+ end
80
+
75
81
  class DeleteUnusedProducts < Clamp::Command
76
82
 
77
83
  def execute
@@ -158,6 +164,7 @@ class OpsManager
158
164
  subcommand "get-installation-settings", "Gets installation settings", GetInstallationSettings
159
165
  subcommand "get-installation-logs", "Gets installation logs", GetInstallationLogs
160
166
  subcommand "import-stemcell", "Uploads stemcell to OpsManager", ImportStemcell
167
+ subcommand "pending-changes", "View pending changes in OpsManager", PendingChanges
161
168
 
162
169
  end
163
170
  end
@@ -0,0 +1,42 @@
1
+ require 'ostruct'
2
+
3
+ class OpsManager
4
+ module Config
5
+ class Base < OpenStruct
6
+ def initialize(config)
7
+ super(config.to_symbolize)
8
+ end
9
+
10
+ def validate_presence_of!(*attrs)
11
+ attrs.each do |attr|
12
+ raise "missing #{attr} on config" unless self.to_h.has_key?(attr)
13
+ end
14
+ end
15
+
16
+ def expand_path_for!(*attrs)
17
+ attrs.each do |attr|
18
+ path = self[attr]
19
+ self[attr] = if path =~ %r{^file://}
20
+ path = Dir.glob(path.gsub!('file://','')).first
21
+ "file://#{path}"
22
+ else
23
+ Dir.glob(path).first
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ class Hash
32
+ def to_symbolize
33
+ Hash[self.map do |k, v|
34
+ if v.kind_of?(Hash)
35
+ [k.to_sym, v.to_symbolize]
36
+ else
37
+ [k.to_sym, v]
38
+ end
39
+ end]
40
+ end
41
+ end
42
+
@@ -1,7 +1,7 @@
1
- require 'ops_manager/configs/base'
1
+ require 'ops_manager/config/base'
2
2
 
3
3
  class OpsManager
4
- class Configs
4
+ module Config
5
5
  class OpsmanDeployment < Base
6
6
  def initialize(config)
7
7
  super(config)
@@ -0,0 +1,13 @@
1
+ require 'ops_manager/config/base'
2
+
3
+ class OpsManager
4
+ module Config
5
+ class ProductDeployment < Base
6
+ def initialize(config)
7
+ super(config)
8
+ validate_presence_of! :name, :desired_version
9
+ expand_path_for! :stemcell
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,7 +2,7 @@ require 'ostruct'
2
2
 
3
3
  class OpsManager
4
4
  class Configs
5
- class Base < OpenStruct
5
+ class Base < Hash
6
6
  def initialize(config)
7
7
  @config = config
8
8
  super(config)
@@ -6,7 +6,7 @@ class OpsManager
6
6
  attr_reader :id
7
7
 
8
8
  def trigger!
9
- res = trigger_installation( body: body )
9
+ res = trigger_installation( :headers => {"Content-Type"=>"application/json"}, :body => body )
10
10
  @id = JSON.parse(res.body).fetch('install').fetch('id').to_i
11
11
  self
12
12
  end
@@ -25,27 +25,19 @@ class OpsManager
25
25
 
26
26
  private
27
27
  def body
28
- @body ||= [ 'ignore_warnings=true' ]
29
- @body << errands_body
30
- @body.join('&')
28
+ @body ||= {'errands' => errands, 'ignore_warnings' => true }.to_json
31
29
  end
32
-
33
30
  def opsman_api
34
31
  @opsman_api ||= OpsManager::Api::Opsman.new
35
32
  end
36
33
 
37
- def errands_body
38
- staged_products_guids.collect { |product_guid| post_deploy_errands_body_for(product_guid) }
39
- end
40
-
41
- def post_deploy_errands_body_for(product_guid)
42
- post_deploy_errands = post_deploy_errands_for(product_guid)
43
-
44
- if post_deploy_errands.empty?
45
- "enabled_errands[#{product_guid}]{}"
46
- else
47
- post_deploy_errands.collect{ |e| "enabled_errands[#{product_guid}][post_deploy_errands][]=#{e}" }
34
+ def errands
35
+ res = { }
36
+ staged_products_guids.each do |product_guid|
37
+ errands = errands_for(product_guid).keep_if { |an_errand| an_errand['post_deploy'] }
38
+ errands.each { |e| res[product_guid] = {'run_post_deploy' => { e['name'] => true}}}
48
39
  end
40
+ res
49
41
  end
50
42
 
51
43
  def staged_products_guids
@@ -56,9 +48,6 @@ class OpsManager
56
48
  JSON.parse(get_staged_products.body)
57
49
  end
58
50
 
59
- def post_deploy_errands_for(product_guid)
60
- errands_for(product_guid).keep_if{ |errand| errand['post_deploy'] }.map{ |o| o['name']}
61
- end
62
51
 
63
52
  def errands_for(product_guid)
64
53
  res = get_staged_products_errands(product_guid)
@@ -7,6 +7,8 @@ require "ops_manager/semver"
7
7
  class OpsManager
8
8
  class ProductDeployment
9
9
  extend Forwardable
10
+ attr_reader :config
11
+
10
12
  def_delegators :opsman_api, :current_version, :upload_product, :get_installation_settings,
11
13
  :upgrade_product_installation, :get_installation, :get_available_products, :upload_installation_settings,
12
14
  :trigger_installation, :import_stemcell, :add_staged_products
@@ -19,12 +21,12 @@ class OpsManager
19
21
  end
20
22
 
21
23
  def installation
22
- OpsManager::ProductInstallation.find(config.name)
24
+ OpsManager::ProductInstallation.find(config[:name])
23
25
  end
24
26
 
25
27
  def run
26
- OpsManager.target_and_login(config.target, config.username, config.password)
27
- import_stemcell(config.stemcell)
28
+ OpsManager.target_and_login(config[:target], config[:username], config[:password])
29
+ import_stemcell(config[:stemcell])
28
30
 
29
31
  case
30
32
  when installation.nil? || forced_deployment?
@@ -37,15 +39,15 @@ class OpsManager
37
39
  end
38
40
 
39
41
  def desired_version
40
- Semver.new(config.desired_version)
42
+ Semver.new(config[:desired_version])
41
43
  end
42
44
 
43
45
  def upload
44
46
  print "====> Uploading product ...".green
45
- if ProductDeployment.exists?(config.name, config.desired_version)
47
+ if ProductDeployment.exists?(config[:name], config[:desired_version])
46
48
  puts "product already exists".green
47
- elsif config.filepath
48
- upload_product(config.filepath)
49
+ elsif config[:filepath]
50
+ upload_product(config[:filepath])
49
51
  puts "done".green
50
52
  else
51
53
  puts "no filepath provided, skipping product upload.".green
@@ -57,9 +59,9 @@ class OpsManager
57
59
  puts "====> Skipping as this product has a pending installation!".red
58
60
  return
59
61
  end
60
- puts "====> Upgrading #{config.name} version from #{installation.current_version.to_s} to #{config.desired_version}...".green
62
+ puts "====> Upgrading #{config[:name]} version from #{installation.current_version.to_s} to #{config[:desired_version]}...".green
61
63
  upload
62
- upgrade_product_installation(installation.guid, config.desired_version)
64
+ upgrade_product_installation(installation.guid, config[:desired_version])
63
65
  merge_product_installation_settings
64
66
  OpsManager::InstallationRunner.trigger!.wait_for_result
65
67
 
@@ -68,12 +70,12 @@ class OpsManager
68
70
 
69
71
  def add_to_installation
70
72
  unless installation
71
- add_staged_products(config.name, config.desired_version)
73
+ add_staged_products(config[:name], config[:desired_version])
72
74
  end
73
75
  end
74
76
 
75
77
  def deploy
76
- puts "====> Deploying #{config.name} version #{config.desired_version}...".green
78
+ puts "====> Deploying #{config[:name]} version #{config[:desired_version]}...".green
77
79
  upload
78
80
  add_to_installation
79
81
  merge_product_installation_settings
@@ -85,7 +87,7 @@ class OpsManager
85
87
 
86
88
  def merge_product_installation_settings
87
89
  get_installation_settings({write_to: '/tmp/is.yml'})
88
- puts `DEBUG=false spruce merge /tmp/is.yml #{config.installation_settings_file} > /tmp/new_is.yml`
90
+ puts `DEBUG=false spruce merge /tmp/is.yml #{config[:installation_settings_file]} > /tmp/new_is.yml`
89
91
  upload_installation_settings('/tmp/new_is.yml')
90
92
  end
91
93
 
@@ -96,7 +98,7 @@ class OpsManager
96
98
 
97
99
  private
98
100
  def desired_version
99
- @desired_version ||= OpsManager::Semver.new(config.desired_version)
101
+ @desired_version ||= OpsManager::Semver.new(config[:desired_version])
100
102
  end
101
103
 
102
104
  def forced_deployment?
@@ -108,7 +110,7 @@ class OpsManager
108
110
  end
109
111
 
110
112
  def config
111
- OpsManager::Configs::ProductDeployment.new(::YAML.load_file(@config_file))
113
+ OpsManager::Config::ProductDeployment.new(::YAML.load_file(@config_file))
112
114
  end
113
115
  end
114
116
  end
@@ -1,3 +1,3 @@
1
1
  class OpsManager
2
- VERSION = "0.5.4"
2
+ VERSION = "0.7.1"
3
3
  end
data/lib/ops_manager.rb CHANGED
@@ -83,9 +83,10 @@ end
83
83
 
84
84
  require "ops_manager/version"
85
85
  require "ops_manager/semver"
86
- require "ops_manager/deployments/vsphere"
87
- require 'ops_manager/configs/product_deployment'
88
- require 'ops_manager/configs/opsman_deployment'
86
+ require "ops_manager/appliance/vsphere"
87
+ require "ops_manager/appliance/aws"
88
+ require 'ops_manager/config/product_deployment'
89
+ require 'ops_manager/config/opsman_deployment'
89
90
  require "ops_manager/cli"
90
91
  require "ops_manager/errors"
91
92
  require "net/https"
data/ops_manager.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "rbvmomi"
27
27
  spec.add_dependency "multipart-post"
28
28
  spec.add_dependency "clamp"
29
+ spec.add_dependency "fog-aws"
29
30
  spec.add_dependency "net-ping"
30
31
  spec.add_dependency "cf-uaa-lib"
31
32
  spec.add_dependency "session_config"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ops_manager_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - CompoZed
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-27 00:00:00.000000000 Z
11
+ date: 2017-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: fog-aws
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: net-ping
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -218,12 +232,15 @@ files:
218
232
  - lib/ops_manager/api/base.rb
219
233
  - lib/ops_manager/api/opsman.rb
220
234
  - lib/ops_manager/api/pivnet.rb
235
+ - lib/ops_manager/appliance/aws.rb
236
+ - lib/ops_manager/appliance/base.rb
237
+ - lib/ops_manager/appliance/vsphere.rb
221
238
  - lib/ops_manager/appliance_deployment.rb
222
239
  - lib/ops_manager/cli.rb
240
+ - lib/ops_manager/config/base.rb
241
+ - lib/ops_manager/config/opsman_deployment.rb
242
+ - lib/ops_manager/config/product_deployment.rb
223
243
  - lib/ops_manager/configs/base.rb
224
- - lib/ops_manager/configs/opsman_deployment.rb
225
- - lib/ops_manager/configs/product_deployment.rb
226
- - lib/ops_manager/deployments/vsphere.rb
227
244
  - lib/ops_manager/director_template_generator.rb
228
245
  - lib/ops_manager/errors.rb
229
246
  - lib/ops_manager/installation.rb
@@ -1,16 +0,0 @@
1
- require 'ops_manager/configs/base'
2
-
3
- class OpsManager
4
- class Configs
5
- class ProductDeployment < Base
6
- def initialize(config)
7
- super(config)
8
- validate_presence_of!(:name, :desired_version)
9
- end
10
-
11
- def stemcell
12
- find_full_path(@config['stemcell'])
13
- end
14
- end
15
- end
16
- end
@@ -1,45 +0,0 @@
1
- require 'rbvmomi'
2
- require "uri"
3
- require 'shellwords'
4
- require "ops_manager/logging"
5
-
6
- class OpsManager
7
- module Deployments
8
- module Vsphere
9
- include OpsManager::Logging
10
-
11
- def deploy_vm(name, ip)
12
- print '====> Deploying ova ...'.green
13
- vcenter_target= "vi://#{vcenter_username}:#{vcenter_password}@#{config.opts['vcenter']['host']}/#{config.opts['vcenter']['datacenter']}/host/#{config.opts['vcenter']['cluster']}"
14
- cmd = "echo yes | ovftool --acceptAllEulas --noSSLVerify --powerOn --X:waitForIp --net:\"Network 1=#{config.opts['portgroup']}\" --name=#{name} -ds=#{config.opts['datastore']} --prop:ip0=#{ip} --prop:netmask0=#{config.opts['netmask']} --prop:gateway=#{config.opts['gateway']} --prop:DNS=#{config.opts['dns']} --prop:ntp_servers=#{config.opts['ntp_servers'].join(',')} --prop:admin_password=#{config.password} #{config.opts['ova_path']} #{vcenter_target}"
15
- logger.info "Running: #{cmd}"
16
- logger.info `#{cmd}`
17
- puts 'done'.green
18
- end
19
-
20
- def stop_current_vm(name)
21
- print "====> Stopping vm #{name} ...".green
22
- dc = vim.serviceInstance.find_datacenter(config.opts['vcenter']['datacenter'])
23
- logger.info "finding vm: #{name}"
24
- vm = dc.find_vm(name) or fail "VM not found"
25
- vm.PowerOffVM_Task.wait_for_completion
26
- puts 'done'.green
27
- end
28
-
29
- private
30
- def vim
31
- RbVmomi::VIM.connect host: config.opts['vcenter']['host'], user: URI.unescape(config.opts['vcenter']['username']), password: URI.unescape(config.opts['vcenter']['password']), insecure: true
32
- end
33
-
34
- def vcenter_username
35
- Shellwords.escape(URI.encode(config.opts['vcenter']['username']))
36
- end
37
-
38
- def vcenter_password
39
- Shellwords.escape(URI.encode(config.opts['vcenter']['password']))
40
- end
41
- end
42
- end
43
- end
44
-
45
-