morpheus-cli 2.11.3.4 → 2.12.4
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/lib/morpheus/api/api_client.rb +12 -0
- data/lib/morpheus/api/cloud_policies_interface.rb +47 -0
- data/lib/morpheus/api/group_policies_interface.rb +47 -0
- data/lib/morpheus/api/policies_interface.rb +63 -0
- data/lib/morpheus/api/virtual_images_interface.rb +16 -6
- data/lib/morpheus/cli.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +1 -1
- data/lib/morpheus/cli/option_types.rb +5 -5
- data/lib/morpheus/cli/policies_command.rb +847 -0
- data/lib/morpheus/cli/roles.rb +2 -2
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +6 -6
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b980bc7c2a00f5b68e939530252141590e2f787b
|
4
|
+
data.tar.gz: 5e29d80365f8fea25225cb12e2dd29eb40aadf87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a86f6cd4acc16da2a54a6f22900ee4c4d12e010e5b7da5521b2ebe61166d53885724ab42f4a155d520468aec93bda688c45f0e71855fe27b91aee05f5bf22ceb
|
7
|
+
data.tar.gz: 75207d59b6dcb48403f95f299472a071f8ec8e84069a8303570f763bd3cb4e59a6e95896924c5196b396a16df9ef9c5a614adc8bf283c7b5fc9f68d8dda03a87
|
@@ -191,4 +191,16 @@ class Morpheus::APIClient
|
|
191
191
|
# monitoring.incidents
|
192
192
|
# end
|
193
193
|
|
194
|
+
def policies
|
195
|
+
Morpheus::PoliciesInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
196
|
+
end
|
197
|
+
|
198
|
+
def group_policies
|
199
|
+
Morpheus::GroupPoliciesInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
200
|
+
end
|
201
|
+
|
202
|
+
def cloud_policies
|
203
|
+
Morpheus::CloudPoliciesInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
|
204
|
+
end
|
205
|
+
|
194
206
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
|
3
|
+
class Morpheus::CloudPoliciesInterface < Morpheus::APIClient
|
4
|
+
def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
|
5
|
+
@access_token = access_token
|
6
|
+
@refresh_token = refresh_token
|
7
|
+
@base_url = base_url
|
8
|
+
@expires_at = expires_at
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(cloud_id, id, params={})
|
12
|
+
raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
|
13
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/policies/#{id}"
|
14
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
15
|
+
opts = {method: :get, url: url, headers: headers}
|
16
|
+
execute(opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def list(cloud_id, params={})
|
20
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/policies"
|
21
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
22
|
+
opts = {method: :get, url: url, headers: headers}
|
23
|
+
execute(opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create(cloud_id, payload)
|
27
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/policies"
|
28
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
29
|
+
opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
|
30
|
+
execute(opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
def update(cloud_id, id, payload)
|
34
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/policies/#{id}"
|
35
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
36
|
+
opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
|
37
|
+
execute(opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy(cloud_id, id, params={})
|
41
|
+
url = "#{@base_url}/api/zones/#{cloud_id}/policies/#{id}"
|
42
|
+
headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
43
|
+
opts = {method: :delete, url: url, timeout: 30, headers: headers}
|
44
|
+
execute(opts)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
|
3
|
+
class Morpheus::GroupPoliciesInterface < Morpheus::APIClient
|
4
|
+
def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
|
5
|
+
@access_token = access_token
|
6
|
+
@refresh_token = refresh_token
|
7
|
+
@base_url = base_url
|
8
|
+
@expires_at = expires_at
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(group_id, id, params={})
|
12
|
+
raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
|
13
|
+
url = "#{@base_url}/api/groups/#{group_id}/policies/#{id}"
|
14
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
15
|
+
opts = {method: :get, url: url, headers: headers}
|
16
|
+
execute(opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def list(group_id, params={})
|
20
|
+
url = "#{@base_url}/api/groups/#{group_id}/policies"
|
21
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
22
|
+
opts = {method: :get, url: url, headers: headers}
|
23
|
+
execute(opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create(group_id, payload)
|
27
|
+
url = "#{@base_url}/api/groups/#{group_id}/policies"
|
28
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
29
|
+
opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
|
30
|
+
execute(opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
def update(group_id, id, payload)
|
34
|
+
url = "#{@base_url}/api/groups/#{group_id}/policies/#{id}"
|
35
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
36
|
+
opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
|
37
|
+
execute(opts)
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy(group_id, id, params={})
|
41
|
+
url = "#{@base_url}/api/groups/#{group_id}/policies/#{id}"
|
42
|
+
headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
43
|
+
opts = {method: :delete, url: url, timeout: 30, headers: headers}
|
44
|
+
execute(opts)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'morpheus/api/api_client'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
class Morpheus::PoliciesInterface < Morpheus::APIClient
|
5
|
+
def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
|
6
|
+
@access_token = access_token
|
7
|
+
@refresh_token = refresh_token
|
8
|
+
@base_url = base_url
|
9
|
+
@expires_at = expires_at
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(id, params={})
|
13
|
+
raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
|
14
|
+
url = "#{@base_url}/api/policies/#{id}"
|
15
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
16
|
+
opts = {method: :get, url: url, headers: headers}
|
17
|
+
execute(opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def list(params={})
|
21
|
+
url = "#{@base_url}/api/policies"
|
22
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
23
|
+
opts = {method: :get, url: url, headers: headers}
|
24
|
+
execute(opts)
|
25
|
+
end
|
26
|
+
|
27
|
+
def create(payload)
|
28
|
+
url = "#{@base_url}/api/policies"
|
29
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
30
|
+
opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
|
31
|
+
execute(opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(id, payload)
|
35
|
+
url = "#{@base_url}/api/policies/#{id}"
|
36
|
+
headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
37
|
+
opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
|
38
|
+
execute(opts)
|
39
|
+
end
|
40
|
+
|
41
|
+
def destroy(id, params={})
|
42
|
+
url = "#{@base_url}/api/policies/#{id}"
|
43
|
+
headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
44
|
+
opts = {method: :delete, url: url, timeout: 30, headers: headers}
|
45
|
+
execute(opts)
|
46
|
+
end
|
47
|
+
|
48
|
+
def list_policy_types(params={})
|
49
|
+
url = "#{@base_url}/api/policy-types"
|
50
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
51
|
+
opts = {method: :get, url: url, headers: headers}
|
52
|
+
execute(opts)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_policy_type(id, params={})
|
56
|
+
raise "#{self.class}.get_policy_type() passed a blank id!" if id.to_s == ''
|
57
|
+
url = "#{@base_url}/api/policy-types/#{URI.escape(id.to_s)}"
|
58
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
59
|
+
opts = {method: :get, url: url, headers: headers}
|
60
|
+
execute(opts)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -51,13 +51,23 @@ class Morpheus::VirtualImagesInterface < Morpheus::APIClient
|
|
51
51
|
execute(method: :delete, url: url, headers: headers)
|
52
52
|
end
|
53
53
|
|
54
|
-
#
|
55
|
-
def upload(id, image_file)
|
54
|
+
# multipart file upload
|
55
|
+
# def upload(id, image_file)
|
56
|
+
# url = "#{@base_url}/api/virtual-images/#{id}/upload"
|
57
|
+
# headers = { :params => {}, :authorization => "Bearer #{@access_token}"}
|
58
|
+
# payload = {}
|
59
|
+
# payload[:file] = image_file
|
60
|
+
# payload[:multipart] = true
|
61
|
+
# execute(method: :post, url: url, headers: headers, payload: payload)
|
62
|
+
# end
|
63
|
+
|
64
|
+
# no multipart
|
65
|
+
def upload(id, image_file, filename=nil)
|
66
|
+
filename = filename || File.basename(image_file)
|
56
67
|
url = "#{@base_url}/api/virtual-images/#{id}/upload"
|
57
|
-
headers = { :params => {}, :authorization => "Bearer #{@access_token}"}
|
58
|
-
|
59
|
-
payload
|
60
|
-
payload[:multipart] = true
|
68
|
+
headers = { :params => {}, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/octet-stream'}
|
69
|
+
headers[:params][:filename] = filename
|
70
|
+
payload = image_file
|
61
71
|
execute(method: :post, url: url, headers: headers, payload: payload)
|
62
72
|
end
|
63
73
|
|
data/lib/morpheus/cli.rb
CHANGED
@@ -94,7 +94,7 @@ module Morpheus
|
|
94
94
|
load 'morpheus/cli/monitoring_contacts_command.rb'
|
95
95
|
load 'morpheus/cli/monitoring_groups_command.rb'
|
96
96
|
load 'morpheus/cli/monitoring_apps_command.rb'
|
97
|
-
|
97
|
+
load 'morpheus/cli/policies_command.rb'
|
98
98
|
# nice to have commands
|
99
99
|
load 'morpheus/cli/curl_command.rb'
|
100
100
|
load 'morpheus/cli/set_prompt_command.rb'
|
@@ -194,7 +194,7 @@ module Morpheus
|
|
194
194
|
|
195
195
|
when :options
|
196
196
|
options[:options] ||= {}
|
197
|
-
opts.on( '-O', '--option OPTION', "Option in the format
|
197
|
+
opts.on( '-O', '--option OPTION', "Option in the format -O field=\"value\"" ) do |option|
|
198
198
|
# todo: look ahead and parse ALL the option=value args after -O switch
|
199
199
|
#custom_option_args = option.split('=')
|
200
200
|
custom_option_args = option.sub(/\s?\=\s?/, '__OPTION_DELIM__').split('__OPTION_DELIM__')
|
@@ -194,7 +194,7 @@ module Morpheus
|
|
194
194
|
value_found = false
|
195
195
|
value = nil
|
196
196
|
while !value_found do
|
197
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
197
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
198
198
|
input = $stdin.gets.chomp!
|
199
199
|
value = input.empty? ? option_type['defaultValue'] : input
|
200
200
|
value = value.to_s.include?('.') ? value.to_f : value.to_i
|
@@ -259,7 +259,7 @@ module Morpheus
|
|
259
259
|
Readline.completion_append_character = ""
|
260
260
|
Readline.basic_word_break_characters = ''
|
261
261
|
Readline.completion_proc = proc {|s| select_options.clone.collect{|opt| opt['name']}.grep(/^#{Regexp.escape(s)}/)}
|
262
|
-
input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
|
262
|
+
input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
|
263
263
|
input = input.chomp.strip
|
264
264
|
if input.empty?
|
265
265
|
value = option_type['defaultValue']
|
@@ -323,7 +323,7 @@ module Morpheus
|
|
323
323
|
value_found = false
|
324
324
|
value = nil
|
325
325
|
while !value_found do
|
326
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
326
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
327
327
|
input = $stdin.gets.chomp!
|
328
328
|
value = input.empty? ? option_type['defaultValue'] : input
|
329
329
|
if input == '?'
|
@@ -378,11 +378,11 @@ module Morpheus
|
|
378
378
|
value_found = false
|
379
379
|
value = nil
|
380
380
|
while !value_found do
|
381
|
-
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
381
|
+
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
382
382
|
Readline.completion_append_character = ""
|
383
383
|
Readline.basic_word_break_characters = ''
|
384
384
|
Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
|
385
|
-
input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
|
385
|
+
input = Readline.readline("#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''} ['?' for options]: ", false).to_s
|
386
386
|
input = input.chomp.strip
|
387
387
|
#input = $stdin.gets.chomp!
|
388
388
|
value = input.empty? ? option_type['defaultValue'] : input.to_s
|
@@ -0,0 +1,847 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'rest_client'
|
4
|
+
require 'optparse'
|
5
|
+
require 'filesize'
|
6
|
+
require 'table_print'
|
7
|
+
require 'morpheus/cli/cli_command'
|
8
|
+
require 'morpheus/cli/mixins/infrastructure_helper'
|
9
|
+
|
10
|
+
class Morpheus::Cli::PoliciesCommand
|
11
|
+
include Morpheus::Cli::CliCommand
|
12
|
+
include Morpheus::Cli::InfrastructureHelper
|
13
|
+
|
14
|
+
set_command_name :policies
|
15
|
+
|
16
|
+
register_subcommands :list, :get, :add, :update, :remove #, :generate_pool
|
17
|
+
register_subcommands :'list-types' => :list_types
|
18
|
+
register_subcommands :'get-type' => :get_type
|
19
|
+
|
20
|
+
# set_default_subcommand :list
|
21
|
+
|
22
|
+
def initialize()
|
23
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
24
|
+
end
|
25
|
+
|
26
|
+
def connect(opts)
|
27
|
+
@api_client = establish_remote_appliance_connection(opts)
|
28
|
+
# @policies_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).policies
|
29
|
+
@policies_interface = @api_client.policies
|
30
|
+
@group_policies_interface = @api_client.group_policies
|
31
|
+
@cloud_policies_interface = @api_client.cloud_policies
|
32
|
+
@clouds_interface = @api_client.clouds
|
33
|
+
@groups_interface = @api_client.groups
|
34
|
+
@active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle(args)
|
38
|
+
handle_subcommand(args)
|
39
|
+
end
|
40
|
+
|
41
|
+
def list(args)
|
42
|
+
options = {}
|
43
|
+
params = {}
|
44
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
45
|
+
opts.banner = subcommand_usage()
|
46
|
+
opts.on( '-g', '--group GROUP', "Group Name or ID" ) do |val|
|
47
|
+
options[:group] = val
|
48
|
+
end
|
49
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
|
50
|
+
options[:cloud] = val
|
51
|
+
end
|
52
|
+
opts.on( '-G', '--global', "Exclude policies scoped to a group or cloud" ) do
|
53
|
+
params[:global] = true
|
54
|
+
end
|
55
|
+
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
|
56
|
+
opts.footer = "List policies."
|
57
|
+
end
|
58
|
+
optparse.parse!(args)
|
59
|
+
connect(options)
|
60
|
+
begin
|
61
|
+
group, cloud = nil, nil
|
62
|
+
if options[:group]
|
63
|
+
group = find_group_by_name_or_id(options[:group])
|
64
|
+
elsif options[:cloud]
|
65
|
+
cloud = find_cloud_by_name_or_id(options[:cloud])
|
66
|
+
end
|
67
|
+
[:phrase, :offset, :max, :sort, :direction].each do |k|
|
68
|
+
params[k] = options[k] unless options[k].nil?
|
69
|
+
end
|
70
|
+
if options[:dry_run]
|
71
|
+
if group
|
72
|
+
print_dry_run @group_policies_interface.dry.list(group['id'], params)
|
73
|
+
elsif cloud
|
74
|
+
print_dry_run @cloud_policies_interface.dry.list(cloud['id'], params)
|
75
|
+
else
|
76
|
+
# global
|
77
|
+
print_dry_run @policies_interface.dry.list(params)
|
78
|
+
end
|
79
|
+
return 0
|
80
|
+
end
|
81
|
+
json_response = nil
|
82
|
+
if group
|
83
|
+
json_response = @group_policies_interface.list(group['id'], params)
|
84
|
+
elsif cloud
|
85
|
+
json_response = @cloud_policies_interface.list(cloud['id'], params)
|
86
|
+
else
|
87
|
+
json_response = @policies_interface.list(params)
|
88
|
+
end
|
89
|
+
policies = json_response["policies"]
|
90
|
+
if options[:include_fields]
|
91
|
+
json_response = {"policies" => filter_data(policies, options[:include_fields]) }
|
92
|
+
end
|
93
|
+
if options[:json]
|
94
|
+
puts as_json(json_response, options)
|
95
|
+
return 0
|
96
|
+
elsif options[:yaml]
|
97
|
+
puts as_yaml(json_response, options)
|
98
|
+
return 0
|
99
|
+
elsif options[:csv]
|
100
|
+
puts records_as_csv(policies, options)
|
101
|
+
return 0
|
102
|
+
end
|
103
|
+
title = "Morpheus Policies"
|
104
|
+
subtitles = []
|
105
|
+
if group
|
106
|
+
subtitles << "Group: #{group['name']}".strip
|
107
|
+
end
|
108
|
+
if cloud
|
109
|
+
subtitles << "Cloud: #{cloud['name']}".strip
|
110
|
+
end
|
111
|
+
if params[:global]
|
112
|
+
subtitles << "(Global)".strip
|
113
|
+
end
|
114
|
+
if params[:phrase]
|
115
|
+
subtitles << "Search: #{params[:phrase]}".strip
|
116
|
+
end
|
117
|
+
print_h1 title, subtitles
|
118
|
+
if policies.empty?
|
119
|
+
print cyan,"No policies found.",reset,"\n"
|
120
|
+
else
|
121
|
+
rows = policies.collect {|policy|
|
122
|
+
# we got a policy.site and policy.zone now!
|
123
|
+
# ref_type, ref_id = policy['refType'], policy['refId']
|
124
|
+
# ref_str = ""
|
125
|
+
# if ref_type == 'ComputeZone'
|
126
|
+
# ref_str = "Cloud #{ref_id}"
|
127
|
+
# elsif ref_type == 'ComputeSite'
|
128
|
+
# ref_str = "Group #{ref_id}"
|
129
|
+
# end
|
130
|
+
config_str = JSON.generate(policy['config'] || {})
|
131
|
+
row = {
|
132
|
+
id: policy['id'],
|
133
|
+
name: policy['name'], # always blank right now?
|
134
|
+
description: policy['description'], # always blank right now?
|
135
|
+
type: policy['policyType'] ? policy['policyType']['name'] : '',
|
136
|
+
#for: ref_str,
|
137
|
+
group: policy['site'] ? policy['site']['name'] : '',
|
138
|
+
cloud: policy['zone'] ? policy['zone']['name'] : '',
|
139
|
+
tenants: truncate_string(format_tenants(policy['accounts']), 15),
|
140
|
+
config: truncate_string(config_str, 50),
|
141
|
+
enabled: policy['enabled'] ? 'Yes' : 'No',
|
142
|
+
}
|
143
|
+
row
|
144
|
+
}
|
145
|
+
columns = [:id, :name, :description, :group, :cloud, :tenants, :type, :config, :enabled]
|
146
|
+
if group || cloud
|
147
|
+
columns = [:id, :description, :type, :config]
|
148
|
+
end
|
149
|
+
if options[:include_fields]
|
150
|
+
columns = options[:include_fields]
|
151
|
+
end
|
152
|
+
print cyan
|
153
|
+
print as_pretty_table(rows, columns, options)
|
154
|
+
print reset
|
155
|
+
print_results_pagination(json_response, {:label => "policy", :n_label => "policies"})
|
156
|
+
end
|
157
|
+
print reset,"\n"
|
158
|
+
return 0
|
159
|
+
rescue RestClient::Exception => e
|
160
|
+
print_rest_exception(e, options)
|
161
|
+
exit 1
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def get(args)
|
166
|
+
options = {}
|
167
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
168
|
+
opts.banner = subcommand_usage("[policy]")
|
169
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
170
|
+
opts.footer = "Get details about a policy." + "\n" +
|
171
|
+
"[policy] is required. This is the id of a policy."
|
172
|
+
end
|
173
|
+
optparse.parse!(args)
|
174
|
+
if args.count != 1
|
175
|
+
print_error Morpheus::Terminal.angry_prompt
|
176
|
+
puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
|
177
|
+
return 1
|
178
|
+
end
|
179
|
+
connect(options)
|
180
|
+
begin
|
181
|
+
if options[:dry_run]
|
182
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
183
|
+
print_dry_run @policies_interface.dry.get(args[0].to_i)
|
184
|
+
else
|
185
|
+
print_dry_run @policies_interface.dry.list({name:args[0]})
|
186
|
+
end
|
187
|
+
return
|
188
|
+
end
|
189
|
+
policy = find_policy_by_name_or_id(args[0])
|
190
|
+
return 1 if policy.nil?
|
191
|
+
json_response = {'policy' => policy} # skip redundant request
|
192
|
+
# json_response = @policies_interface.get(policy['id'])
|
193
|
+
policy = json_response['policy']
|
194
|
+
if options[:include_fields]
|
195
|
+
json_response = {'policy' => filter_data(policy, options[:include_fields]) }
|
196
|
+
end
|
197
|
+
if options[:json]
|
198
|
+
puts as_json(json_response, options)
|
199
|
+
return 0
|
200
|
+
elsif options[:yaml]
|
201
|
+
puts as_yaml(json_response, options)
|
202
|
+
return 0
|
203
|
+
elsif options[:csv]
|
204
|
+
puts records_as_csv([policy], options)
|
205
|
+
return 0
|
206
|
+
end
|
207
|
+
print_h1 "Policy Details"
|
208
|
+
print cyan
|
209
|
+
description_cols = {
|
210
|
+
"ID" => 'id',
|
211
|
+
"Name" => 'name',
|
212
|
+
"Description" => 'description',
|
213
|
+
"Type" => lambda {|it| it['policyType'] ? it['policyType']['name'] : '' },
|
214
|
+
"Group" => lambda {|it| it['site'] ? it['site']['name'] : '' },
|
215
|
+
"Cloud" => lambda {|it| it['zone'] ? it['zone']['name'] : '' },
|
216
|
+
"Enabled" => lambda {|it| it['enabled'] ? 'Yes' : 'No' },
|
217
|
+
# "All Accounts" => lambda {|it| it['allAccounts'] ? 'Yes' : 'No' },
|
218
|
+
# "Ref Type" => 'refType',
|
219
|
+
# "Ref ID" => 'refId',
|
220
|
+
# "Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
|
221
|
+
"Tenants" => lambda {|it| format_tenants(policy["accounts"]) },
|
222
|
+
}
|
223
|
+
print_description_list(description_cols, policy)
|
224
|
+
# print reset,"\n"
|
225
|
+
|
226
|
+
print_h2 "Policy Config"
|
227
|
+
print cyan
|
228
|
+
puts as_json(policy['config'])
|
229
|
+
print reset, "\n"
|
230
|
+
return 0
|
231
|
+
rescue RestClient::Exception => e
|
232
|
+
print_rest_exception(e, options)
|
233
|
+
return 1
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def add(args)
|
238
|
+
options = {}
|
239
|
+
policy_type_id = nil
|
240
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
241
|
+
opts.banner = subcommand_usage("-t TYPE")
|
242
|
+
opts.on( '-g', '--group GROUP', "Group Name or ID, for scoping the policy to a group." ) do |val|
|
243
|
+
options[:group] = val
|
244
|
+
end
|
245
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID, for scoping the policy to a cloud" ) do |val|
|
246
|
+
options[:cloud] = val
|
247
|
+
end
|
248
|
+
opts.on('-t', '--type ID', "Policy Type Name or ID") do |val|
|
249
|
+
options['type'] = val
|
250
|
+
end
|
251
|
+
opts.on('--name VALUE', String, "Name for this policy") do |val|
|
252
|
+
options['name'] = val
|
253
|
+
end
|
254
|
+
opts.on('--description VALUE', String, "Description of policy") do |val|
|
255
|
+
options['description'] = val
|
256
|
+
end
|
257
|
+
opts.on('--accounts LIST', Array, "Tenant accounts, comma separated list of account IDs") do |list|
|
258
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
259
|
+
options['accounts'] = []
|
260
|
+
else
|
261
|
+
options['accounts'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
262
|
+
end
|
263
|
+
end
|
264
|
+
opts.on('--enabled [on|off]', String, "Can be used to disable a policy") do |val|
|
265
|
+
options['enabled'] = val.to_s == 'on' || val.to_s == 'true'
|
266
|
+
end
|
267
|
+
opts.on('--config JSON', String, "Policy Config JSON") do |val|
|
268
|
+
options['config'] = JSON.parse(val.to_s)
|
269
|
+
end
|
270
|
+
opts.on('--config-yaml YAML', String, "Policy Config YAML") do |val|
|
271
|
+
options['config'] = YAML.load(val.to_s)
|
272
|
+
end
|
273
|
+
opts.on('--config-file FILE', String, "Policy Config from a local JSON or YAML file") do |val|
|
274
|
+
options['configFile'] = val.to_s
|
275
|
+
end
|
276
|
+
build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
|
277
|
+
opts.footer = "Create a new policy." + "\n" +
|
278
|
+
"[name] is optional and can be passed as --name instead."
|
279
|
+
end
|
280
|
+
optparse.parse!(args)
|
281
|
+
if args.count > 1
|
282
|
+
print_error Morpheus::Terminal.angry_prompt
|
283
|
+
puts_error "wrong number of arguments, expected 0-1 and got #{args.count}\n#{optparse}"
|
284
|
+
return 1
|
285
|
+
end
|
286
|
+
connect(options)
|
287
|
+
begin
|
288
|
+
group, cloud = nil, nil
|
289
|
+
if options[:group]
|
290
|
+
group = find_group_by_name_or_id(options[:group])
|
291
|
+
elsif options[:cloud]
|
292
|
+
cloud = find_cloud_by_name_or_id(options[:cloud])
|
293
|
+
end
|
294
|
+
|
295
|
+
# merge -O options into normally parsed options
|
296
|
+
options.deep_merge!(options[:options]) if options[:options] && options[:options].keys.size > 0
|
297
|
+
|
298
|
+
# support [name] as first argument
|
299
|
+
if args[0]
|
300
|
+
options['name'] = args[0]
|
301
|
+
end
|
302
|
+
|
303
|
+
# construct payload
|
304
|
+
payload = {
|
305
|
+
'policy' => {
|
306
|
+
'config' => {}
|
307
|
+
}
|
308
|
+
}
|
309
|
+
|
310
|
+
# prompt for policy options
|
311
|
+
|
312
|
+
# Policy Type
|
313
|
+
# allow user as id, name or code
|
314
|
+
available_policy_types = @policies_interface.list_policy_types({})['policyTypes']
|
315
|
+
if available_policy_types.empty?
|
316
|
+
print_red_alert "No available policy types found!"
|
317
|
+
return 1
|
318
|
+
end
|
319
|
+
policy_types_dropdown = available_policy_types.collect {|it| {'name' => it['name'], 'value' => it['id']} }
|
320
|
+
policy_type_id = nil
|
321
|
+
policy_type = nil
|
322
|
+
if options['type']
|
323
|
+
policy_type_id = options['type']
|
324
|
+
else
|
325
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Policy Type', 'type' => 'select', 'selectOptions' => policy_types_dropdown, 'required' => true, 'description' => 'Choose a policy type.'}], options[:options])
|
326
|
+
policy_type_id = v_prompt['type']
|
327
|
+
end
|
328
|
+
if !policy_type_id.to_s.empty?
|
329
|
+
policy_type = available_policy_types.find {|it|
|
330
|
+
it['id'] == policy_type_id.to_i || it['name'] == policy_type_id.to_s || it['code'] == policy_type_id.to_s
|
331
|
+
}
|
332
|
+
end
|
333
|
+
if !policy_type
|
334
|
+
print_red_alert "Policy Type not found by id '#{policy_type_id}'"
|
335
|
+
return 1
|
336
|
+
end
|
337
|
+
# payload['policy']['policyTypeId'] = policy_type['id']
|
338
|
+
payload['policy']['policyType'] = {'id' => policy_type['id']}
|
339
|
+
|
340
|
+
# Name (this is not even used at the moment!)
|
341
|
+
if options['name']
|
342
|
+
payload['policy']['name'] = options['name']
|
343
|
+
else
|
344
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false, 'description' => 'Name for this policy.'}], options)
|
345
|
+
payload['policy']['name'] = v_prompt['name']
|
346
|
+
end
|
347
|
+
|
348
|
+
# Description (this is not even used at the moment!)
|
349
|
+
if options['description']
|
350
|
+
payload['policy']['description'] = options['description']
|
351
|
+
else
|
352
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false, 'description' => 'Description of policy.'}], options)
|
353
|
+
policy_type_id = v_prompt['type']
|
354
|
+
end
|
355
|
+
|
356
|
+
# Enabled
|
357
|
+
if options['enabled']
|
358
|
+
payload['policy']['enabled'] = options['enabled']
|
359
|
+
else
|
360
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'required' => false, 'description' => 'Can be used to disable a policy', 'defaultValue' => true}], options)
|
361
|
+
payload['policy']['enabled'] = v_prompt['enabled']
|
362
|
+
end
|
363
|
+
|
364
|
+
# Tenants
|
365
|
+
if options['accounts']
|
366
|
+
# payload['policy']['accounts'] = options['accounts'].collect {|it| {'id' => it } }
|
367
|
+
payload['policy']['accounts'] = options['accounts']
|
368
|
+
else
|
369
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'accounts', 'fieldLabel' => 'Tenants', 'type' => 'text', 'required' => false, 'description' => 'Tenant accounts, comma separated list of account IDs'}], options)
|
370
|
+
payload['policy']['accounts'] = v_prompt['accounts']
|
371
|
+
end
|
372
|
+
|
373
|
+
# Config
|
374
|
+
if options['config']
|
375
|
+
payload['policy']['config'] = options['config']
|
376
|
+
elsif options['configFile']
|
377
|
+
config_file = File.expand_path(options['configFile'])
|
378
|
+
if !File.exists?(config_file) || !File.file?(config_file)
|
379
|
+
print_red_alert "File not found: #{config_file}"
|
380
|
+
return false
|
381
|
+
end
|
382
|
+
if config_file =~ /\.ya?ml\Z/
|
383
|
+
payload['policy']['config'] = YAML.load_file(config_file)
|
384
|
+
else
|
385
|
+
payload['policy']['config'] = JSON.parse(File.read(config_file))
|
386
|
+
end
|
387
|
+
else
|
388
|
+
# prompt for policy specific options
|
389
|
+
policy_type_option_types = policy_type['optionTypes']
|
390
|
+
# puts "POLICY OPTION TYPES:\n #{policy_type_option_types.inspect}"
|
391
|
+
if policy_type_option_types
|
392
|
+
config_prompt = Morpheus::Cli::OptionTypes.prompt(policy_type_option_types, options, @api_client)
|
393
|
+
# everything should be under fieldContext:'config'
|
394
|
+
# payload['policy'].deep_merge!(config_prompt)
|
395
|
+
if config_prompt['config']
|
396
|
+
payload['policy']['config'].deep_merge!(config_prompt['config'])
|
397
|
+
end
|
398
|
+
else
|
399
|
+
puts "No options found for policy type! Proceeding without config options..."
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
|
404
|
+
if options[:dry_run]
|
405
|
+
if group
|
406
|
+
print_dry_run @group_policies_interface.dry.create(group['id'], payload)
|
407
|
+
elsif cloud
|
408
|
+
print_dry_run @cloud_policies_interface.dry.create(cloud['id'], payload)
|
409
|
+
else
|
410
|
+
# global
|
411
|
+
print_dry_run @policies_interface.dry.create(payload)
|
412
|
+
end
|
413
|
+
return
|
414
|
+
end
|
415
|
+
json_response = nil
|
416
|
+
if group
|
417
|
+
json_response = @group_policies_interface.create(group['id'], payload)
|
418
|
+
elsif cloud
|
419
|
+
json_response = @cloud_policies_interface.create(cloud['id'], payload)
|
420
|
+
else
|
421
|
+
# global
|
422
|
+
json_response = @policies_interface.create(payload)
|
423
|
+
end
|
424
|
+
if options[:json]
|
425
|
+
print JSON.pretty_generate(json_response)
|
426
|
+
print "\n"
|
427
|
+
elsif !options[:quiet]
|
428
|
+
print_green_success "Added policy"
|
429
|
+
# list([])
|
430
|
+
policy = json_response['policy']
|
431
|
+
get([policy['id']])
|
432
|
+
end
|
433
|
+
return 0
|
434
|
+
rescue RestClient::Exception => e
|
435
|
+
print_rest_exception(e, options)
|
436
|
+
exit 1
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
def update(args)
|
441
|
+
options = {}
|
442
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
443
|
+
opts.banner = subcommand_usage("[policy] [options]")
|
444
|
+
# opts.on('-t', '--type ID', "Policy Type Name or ID") do |val|
|
445
|
+
# options['type'] = val
|
446
|
+
# end
|
447
|
+
opts.on('--name VALUE', String, "Name for this policy") do |val|
|
448
|
+
options['name'] = val
|
449
|
+
end
|
450
|
+
opts.on('--description VALUE', String, "Description of policy") do |val|
|
451
|
+
options['description'] = val
|
452
|
+
end
|
453
|
+
opts.on('--accounts LIST', Array, "Tenant accounts, comma separated list of account IDs") do |list|
|
454
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
455
|
+
options['accounts'] = []
|
456
|
+
else
|
457
|
+
options['accounts'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
458
|
+
end
|
459
|
+
end
|
460
|
+
opts.on('--enabled [on|off]', String, "Can be used to disable a policy") do |val|
|
461
|
+
options['enabled'] = val.to_s == 'on' || val.to_s == 'true'
|
462
|
+
end
|
463
|
+
opts.on('--config JSON', String, "Policy Config JSON") do |val|
|
464
|
+
options['config'] = JSON.parse(val.to_s)
|
465
|
+
end
|
466
|
+
opts.on('--config-yaml YAML', String, "Policy Config YAML") do |val|
|
467
|
+
options['config'] = YAML.load(val.to_s)
|
468
|
+
end
|
469
|
+
opts.on('--config-file FILE', String, "Policy Config from a local JSON or YAML file") do |val|
|
470
|
+
options['configFile'] = val.to_s
|
471
|
+
end
|
472
|
+
build_common_options(opts, options, [:options, :json, :dry_run, :remote])
|
473
|
+
opts.footer = "Update a policy." + "\n" +
|
474
|
+
"[policy] is required. This is the id of a policy."
|
475
|
+
end
|
476
|
+
optparse.parse!(args)
|
477
|
+
if args.count != 1
|
478
|
+
print_error Morpheus::Terminal.angry_prompt
|
479
|
+
puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
|
480
|
+
return 1
|
481
|
+
end
|
482
|
+
connect(options)
|
483
|
+
|
484
|
+
begin
|
485
|
+
policy = find_policy_by_name_or_id(args[0])
|
486
|
+
return 1 if policy.nil?
|
487
|
+
group = policy['site'] || policy['group']
|
488
|
+
cloud = policy['zone'] || policy['cloud']
|
489
|
+
|
490
|
+
payload = {
|
491
|
+
'policy' => {}
|
492
|
+
}
|
493
|
+
|
494
|
+
# no prompting, just collect all user passed options
|
495
|
+
params = {}
|
496
|
+
params.deep_merge!(options.reject {|k,v| k.is_a?(Symbol) })
|
497
|
+
params.deep_merge!(options[:options]) if options[:options]
|
498
|
+
|
499
|
+
if params.empty?
|
500
|
+
print_error Morpheus::Terminal.angry_prompt
|
501
|
+
puts_error "Specify atleast one option to update\n#{optparse}"
|
502
|
+
return 1
|
503
|
+
end
|
504
|
+
payload['policy'].deep_merge!(params)
|
505
|
+
|
506
|
+
# Config
|
507
|
+
if options['config']
|
508
|
+
payload['policy']['config'] = options['config']
|
509
|
+
elsif options['configFile']
|
510
|
+
config_file = File.expand_path(options['configFile'])
|
511
|
+
if !File.exists?(config_file) || !File.file?(config_file)
|
512
|
+
print_red_alert "File not found: #{config_file}"
|
513
|
+
return false
|
514
|
+
end
|
515
|
+
if config_file =~ /\.ya?ml\Z/
|
516
|
+
payload['policy']['config'] = YAML.load_file(config_file)
|
517
|
+
else
|
518
|
+
payload['policy']['config'] = JSON.parse(File.read(config_file))
|
519
|
+
end
|
520
|
+
else
|
521
|
+
# this allows adding/updating a single config setting.
|
522
|
+
# use --config or --configFile to overwrite the entire config
|
523
|
+
if policy['config'] && payload['policy']['config']
|
524
|
+
payload['policy']['config'] = policy['config'].merge(payload['policy']['config'])
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
# if options[:dry_run]
|
529
|
+
# print_dry_run @policies_interface.dry.update(policy["id"], payload)
|
530
|
+
# return
|
531
|
+
# end
|
532
|
+
# json_response = @policies_interface.update(policy["id"], payload)
|
533
|
+
|
534
|
+
if options[:dry_run]
|
535
|
+
if group
|
536
|
+
print_dry_run @group_policies_interface.dry.update(group['id'], policy["id"], payload)
|
537
|
+
elsif cloud
|
538
|
+
print_dry_run @cloud_policies_interface.dry.update(cloud['id'], policy["id"], payload)
|
539
|
+
else
|
540
|
+
print_dry_run @policies_interface.dry.update(policy["id"], payload)
|
541
|
+
end
|
542
|
+
return
|
543
|
+
end
|
544
|
+
json_response = nil
|
545
|
+
if group
|
546
|
+
json_response = @group_policies_interface.update(group['id'], policy["id"], payload)
|
547
|
+
elsif cloud
|
548
|
+
json_response = @cloud_policies_interface.update(cloud['id'], policy["id"], payload)
|
549
|
+
else
|
550
|
+
json_response = @policies_interface.update(policy["id"], payload)
|
551
|
+
end
|
552
|
+
if options[:json]
|
553
|
+
puts as_json(json_response)
|
554
|
+
else
|
555
|
+
print_green_success "Updated policy #{policy['id']}"
|
556
|
+
get([policy['id']])
|
557
|
+
end
|
558
|
+
return 0
|
559
|
+
rescue RestClient::Exception => e
|
560
|
+
print_rest_exception(e, options)
|
561
|
+
return 1
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
def remove(args)
|
566
|
+
options = {}
|
567
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
568
|
+
opts.banner = subcommand_usage("[policy]")
|
569
|
+
build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run, :remote])
|
570
|
+
opts.footer = "Delete a policy." + "\n" +
|
571
|
+
"[policy] is required. This is the id of a policy."
|
572
|
+
end
|
573
|
+
optparse.parse!(args)
|
574
|
+
|
575
|
+
if args.count != 1
|
576
|
+
print_error Morpheus::Terminal.angry_prompt
|
577
|
+
puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
|
578
|
+
return 1
|
579
|
+
end
|
580
|
+
|
581
|
+
connect(options)
|
582
|
+
begin
|
583
|
+
policy = find_policy_by_name_or_id(args[0])
|
584
|
+
return 1 if policy.nil?
|
585
|
+
group = policy['site'] || policy['group']
|
586
|
+
cloud = policy['zone'] || policy['cloud']
|
587
|
+
|
588
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the policy: #{policy['id']}?")
|
589
|
+
return 9, "aborted command"
|
590
|
+
end
|
591
|
+
# if options[:dry_run]
|
592
|
+
# print_dry_run @policies_interface.dry.destroy(policy['id'])
|
593
|
+
# return 0
|
594
|
+
# end
|
595
|
+
# json_response = @policies_interface.destroy(policy['id'])
|
596
|
+
if options[:dry_run]
|
597
|
+
if group
|
598
|
+
print_dry_run @group_policies_interface.dry.destroy(group['id'], policy["id"])
|
599
|
+
elsif cloud
|
600
|
+
print_dry_run @cloud_policies_interface.dry.destroy(cloud['id'], policy["id"])
|
601
|
+
else
|
602
|
+
print_dry_run @policies_interface.dry.destroy(policy["id"])
|
603
|
+
end
|
604
|
+
return
|
605
|
+
end
|
606
|
+
json_response = nil
|
607
|
+
if group
|
608
|
+
json_response = @group_policies_interface.destroy(group['id'], policy["id"])
|
609
|
+
elsif cloud
|
610
|
+
json_response = @cloud_policies_interface.destroy(cloud['id'], policy["id"])
|
611
|
+
else
|
612
|
+
json_response = @policies_interface.destroy(policy["id"])
|
613
|
+
end
|
614
|
+
if options[:json]
|
615
|
+
print JSON.pretty_generate(json_response)
|
616
|
+
print "\n"
|
617
|
+
else
|
618
|
+
print_green_success "Deleted policy #{policy['id']}"
|
619
|
+
# list([])
|
620
|
+
end
|
621
|
+
return 0
|
622
|
+
rescue RestClient::Exception => e
|
623
|
+
print_rest_exception(e, options)
|
624
|
+
return 1
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
def list_types(args)
|
629
|
+
params = {}
|
630
|
+
options = {}
|
631
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
632
|
+
opts.banner = subcommand_usage()
|
633
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
634
|
+
opts.footer = "List policy types."
|
635
|
+
end
|
636
|
+
optparse.parse!(args)
|
637
|
+
|
638
|
+
if args.count != 0
|
639
|
+
print_error Morpheus::Terminal.angry_prompt
|
640
|
+
puts_error "wrong number of arguments, expected 0 and got #{args.count}\n#{optparse}"
|
641
|
+
return 1
|
642
|
+
end
|
643
|
+
|
644
|
+
connect(options)
|
645
|
+
begin
|
646
|
+
if options[:dry_run]
|
647
|
+
print_dry_run @policies_interface.dry.list_policy_types(params)
|
648
|
+
return 0
|
649
|
+
end
|
650
|
+
json_response = @policies_interface.list_policy_types()
|
651
|
+
policy_types = json_response['policyTypes']
|
652
|
+
if options[:json]
|
653
|
+
puts as_json(json_response)
|
654
|
+
else
|
655
|
+
print_h1 "Morpheus Policy Types"
|
656
|
+
rows = policy_types.collect {|policy_type|
|
657
|
+
row = {
|
658
|
+
id: policy_type['id'],
|
659
|
+
name: policy_type['name'],
|
660
|
+
code: policy_type['code'],
|
661
|
+
description: policy_type['description']
|
662
|
+
}
|
663
|
+
row
|
664
|
+
}
|
665
|
+
columns = [:id, :name]
|
666
|
+
if options[:include_fields]
|
667
|
+
columns = options[:include_fields]
|
668
|
+
end
|
669
|
+
print cyan
|
670
|
+
print as_pretty_table(rows, columns, options)
|
671
|
+
print_results_pagination(json_response, {:label => "policy type", :n_label => "policy types"})
|
672
|
+
print reset, "\n"
|
673
|
+
end
|
674
|
+
return 0
|
675
|
+
rescue RestClient::Exception => e
|
676
|
+
print_rest_exception(e, options)
|
677
|
+
return 1
|
678
|
+
end
|
679
|
+
@policies_interface.list_policy_types
|
680
|
+
end
|
681
|
+
|
682
|
+
def get_type(args)
|
683
|
+
params = {}
|
684
|
+
options = {}
|
685
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
686
|
+
opts.banner = subcommand_usage("[policy-type]")
|
687
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
688
|
+
opts.footer = "Get details about a policy type." + "\n" +
|
689
|
+
"[policy-type] is required. This is ID of a policy type."
|
690
|
+
end
|
691
|
+
optparse.parse!(args)
|
692
|
+
|
693
|
+
if args.count != 1
|
694
|
+
print_error Morpheus::Terminal.angry_prompt
|
695
|
+
puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
|
696
|
+
return 1
|
697
|
+
end
|
698
|
+
|
699
|
+
connect(options)
|
700
|
+
begin
|
701
|
+
policy_type_id = args[0].to_s
|
702
|
+
if options[:dry_run]
|
703
|
+
print_dry_run @policies_interface.dry.get_policy_type(policy_type_id, params)
|
704
|
+
return 0
|
705
|
+
end
|
706
|
+
json_response = @policies_interface.get_policy_type(policy_type_id, params)
|
707
|
+
policy_type = json_response['policyType']
|
708
|
+
if options[:json]
|
709
|
+
puts as_json(json_response)
|
710
|
+
else
|
711
|
+
print_h1 "Policy Type Details"
|
712
|
+
print cyan
|
713
|
+
description_cols = {
|
714
|
+
"ID" => 'id',
|
715
|
+
"Name" => 'name',
|
716
|
+
# "Description" => 'description',
|
717
|
+
"Code" => 'code',
|
718
|
+
"Category" => 'category',
|
719
|
+
# "Load Method" => 'loadMethod',
|
720
|
+
# "Enforce Method" => 'enforceMethod',
|
721
|
+
# "Prepare Method" => 'prepareMethod',
|
722
|
+
# "Validate Method" => 'validateMethod',
|
723
|
+
"Provision Enforced" => lambda {|it| it['enforceOnProvision'] ? 'Yes' : 'No' },
|
724
|
+
"Managed Enforced" => lambda {|it| it['enforceOnManaged'] ? 'Yes' : 'No' },
|
725
|
+
}
|
726
|
+
print_description_list(description_cols, policy_type)
|
727
|
+
print reset,"\n"
|
728
|
+
|
729
|
+
# show option types
|
730
|
+
print_h2 "Policy Type Options"
|
731
|
+
policy_type_option_types = policy_type['optionTypes']
|
732
|
+
if !policy_type_option_types || policy_type_option_types.size() == 0
|
733
|
+
puts "No options found for policy type"
|
734
|
+
else
|
735
|
+
rows = policy_type_option_types.collect {|option_type|
|
736
|
+
field_str = option_type['fieldName'].to_s
|
737
|
+
if !option_type['fieldContext'].to_s.empty?
|
738
|
+
field_str = option_type['fieldContext'] + "." + field_str
|
739
|
+
end
|
740
|
+
description_str = option_type['description'].to_s
|
741
|
+
if option_type['helpBlock']
|
742
|
+
if description_str.empty?
|
743
|
+
description_str = option_type['helpBlock']
|
744
|
+
else
|
745
|
+
description_str += " " + option_type['helpBlock']
|
746
|
+
end
|
747
|
+
end
|
748
|
+
row = {
|
749
|
+
#code: option_type['code'],
|
750
|
+
field: field_str,
|
751
|
+
type: option_type['type'],
|
752
|
+
description: description_str,
|
753
|
+
default: option_type['defaultValue'],
|
754
|
+
required: option_type['required'] ? 'Yes' : 'No'
|
755
|
+
}
|
756
|
+
row
|
757
|
+
}
|
758
|
+
columns = [:field, :type, :description, :default, :required]
|
759
|
+
print cyan
|
760
|
+
print as_pretty_table(rows, columns)
|
761
|
+
print reset,"\n"
|
762
|
+
end
|
763
|
+
return 0
|
764
|
+
end
|
765
|
+
return 0
|
766
|
+
rescue RestClient::Exception => e
|
767
|
+
print_rest_exception(e, options)
|
768
|
+
return 1
|
769
|
+
end
|
770
|
+
@policies_interface.list_policy_types
|
771
|
+
end
|
772
|
+
|
773
|
+
private
|
774
|
+
|
775
|
+
def find_policy_by_name_or_id(val)
|
776
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
777
|
+
return find_policy_by_id(val)
|
778
|
+
else
|
779
|
+
return find_policy_by_name(val)
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
def find_policy_by_id(id)
|
784
|
+
begin
|
785
|
+
json_response = @policies_interface.get(id.to_i)
|
786
|
+
return json_response['policy']
|
787
|
+
rescue RestClient::Exception => e
|
788
|
+
if e.response && e.response.code == 404
|
789
|
+
print_red_alert "Policy not found by id #{id}"
|
790
|
+
return nil
|
791
|
+
else
|
792
|
+
raise e
|
793
|
+
end
|
794
|
+
end
|
795
|
+
end
|
796
|
+
|
797
|
+
def find_policy_by_name(name)
|
798
|
+
json_response = @policies_interface.list({name: name.to_s})
|
799
|
+
policies = json_response['policies']
|
800
|
+
if policies.empty?
|
801
|
+
print_red_alert "Policy not found by name #{name}"
|
802
|
+
return nil
|
803
|
+
elsif policies.size > 1
|
804
|
+
print_red_alert "#{policies.size} policies found by name #{name}"
|
805
|
+
# print_policies_table(policies, {color: red})
|
806
|
+
rows = policies.collect do |policy|
|
807
|
+
{id: policy['id'], name: policy['name']}
|
808
|
+
end
|
809
|
+
print red
|
810
|
+
tp rows, [:id, :name]
|
811
|
+
print reset,"\n"
|
812
|
+
return nil
|
813
|
+
else
|
814
|
+
policy = policies[0]
|
815
|
+
# merge in tenants map
|
816
|
+
if json_response['tenants'] && json_response['tenants'][policy['id']]
|
817
|
+
policy['tenants'] = json_response['tenants'][policy['id']]
|
818
|
+
end
|
819
|
+
return policy
|
820
|
+
end
|
821
|
+
end
|
822
|
+
|
823
|
+
def find_policy_type_by_id(id)
|
824
|
+
begin
|
825
|
+
json_response = @policies_interface.get_type(id.to_s)
|
826
|
+
return json_response['policyType']
|
827
|
+
rescue RestClient::Exception => e
|
828
|
+
if e.response && e.response.code == 404
|
829
|
+
print_red_alert "Policy Type not found by id #{id}"
|
830
|
+
return nil
|
831
|
+
else
|
832
|
+
raise e
|
833
|
+
end
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
837
|
+
def format_tenants(accounts)
|
838
|
+
if accounts && accounts.size > 0
|
839
|
+
account_ids = accounts.collect {|it| it['id'] }.uniq
|
840
|
+
account_names = accounts.collect {|it| it['name'] }.uniq
|
841
|
+
"(#{account_ids.join(',')}) #{account_names.join(',')}"
|
842
|
+
else
|
843
|
+
""
|
844
|
+
end
|
845
|
+
end
|
846
|
+
|
847
|
+
end
|
data/lib/morpheus/cli/roles.rb
CHANGED
@@ -463,10 +463,10 @@ class Morpheus::Cli::Roles
|
|
463
463
|
end
|
464
464
|
|
465
465
|
def update_feature_access(args)
|
466
|
-
usage = "Usage: morpheus roles update-feature-access [name] [code] [full|read|none]"
|
466
|
+
usage = "Usage: morpheus roles update-feature-access [name] [code] [full|read|user|yes|no|none]"
|
467
467
|
options = {}
|
468
468
|
optparse = OptionParser.new do|opts|
|
469
|
-
opts.banner = subcommand_usage("[name] [code] [full|read|none]")
|
469
|
+
opts.banner = subcommand_usage("[name] [code] [full|read|user|yes|no|none]")
|
470
470
|
build_common_options(opts, options, [:json, :dry_run])
|
471
471
|
end
|
472
472
|
optparse.parse!(args)
|
data/lib/morpheus/cli/version.rb
CHANGED
@@ -82,13 +82,14 @@ class Morpheus::Cli::VirtualImages
|
|
82
82
|
if images.empty?
|
83
83
|
print yellow,"No virtual images found.",reset,"\n"
|
84
84
|
else
|
85
|
-
|
86
|
-
image_table_data = images.collect do |image|
|
85
|
+
rows = images.collect do |image|
|
87
86
|
image_type = virtual_image_type_for_name_or_code(image['imageType'])
|
88
87
|
image_type_display = image_type ? "#{image_type['name']}" : image['imageType']
|
89
88
|
{name: image['name'], id: image['id'], type: image_type_display, source: image['userUploaded'] ? "#{green}UPLOADED#{cyan}" : (image['systemImage'] ? 'SYSTEM' : "#{white}SYNCED#{cyan}"), storage: !image['storageProvider'].nil? ? image['storageProvider']['name'] : 'Default', size: image['rawSize'].nil? ? 'Unknown' : "#{Filesize.from("#{image['rawSize']} B").pretty}"}
|
90
89
|
end
|
91
|
-
|
90
|
+
columns = [:id, :name, :type, :storage, :size, :source]
|
91
|
+
print cyan
|
92
|
+
print as_pretty_table(rows, columns, options)
|
92
93
|
print_results_pagination(json_response)
|
93
94
|
end
|
94
95
|
print reset,"\n"
|
@@ -274,7 +275,6 @@ class Morpheus::Cli::VirtualImages
|
|
274
275
|
# exit 1
|
275
276
|
# end
|
276
277
|
|
277
|
-
#
|
278
278
|
if image_name
|
279
279
|
options[:options] ||= {}
|
280
280
|
options[:options]['name'] ||= image_name
|
@@ -291,13 +291,13 @@ class Morpheus::Cli::VirtualImages
|
|
291
291
|
end
|
292
292
|
|
293
293
|
begin
|
294
|
-
|
294
|
+
my_option_types = add_virtual_image_option_types(image_type)
|
295
295
|
params = Morpheus::Cli::OptionTypes.prompt(add_virtual_image_option_types(image_type), options[:options], @api_client, options[:params])
|
296
296
|
virtual_image_payload = {}.merge(params)
|
297
297
|
virtual_image_files = virtual_image_payload.delete('virtualImageFiles')
|
298
298
|
virtual_image_payload['imageType'] = image_type['code']
|
299
299
|
storage_provider_id = virtual_image_payload.delete('storageProviderId')
|
300
|
-
if !storage_provider_id.empty?
|
300
|
+
if !storage_provider_id.to_s.empty?
|
301
301
|
virtual_image_payload['storageProvider'] = {id: storage_provider_id}
|
302
302
|
end
|
303
303
|
payload = {virtualImage: virtual_image_payload}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-11-09 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -146,12 +146,14 @@ files:
|
|
146
146
|
- lib/morpheus/api/apps_interface.rb
|
147
147
|
- lib/morpheus/api/auth_interface.rb
|
148
148
|
- lib/morpheus/api/checks_interface.rb
|
149
|
+
- lib/morpheus/api/cloud_policies_interface.rb
|
149
150
|
- lib/morpheus/api/clouds_interface.rb
|
150
151
|
- lib/morpheus/api/containers_interface.rb
|
151
152
|
- lib/morpheus/api/custom_instance_types_interface.rb
|
152
153
|
- lib/morpheus/api/dashboard_interface.rb
|
153
154
|
- lib/morpheus/api/deploy_interface.rb
|
154
155
|
- lib/morpheus/api/deployments_interface.rb
|
156
|
+
- lib/morpheus/api/group_policies_interface.rb
|
155
157
|
- lib/morpheus/api/groups_interface.rb
|
156
158
|
- lib/morpheus/api/incidents_interface.rb
|
157
159
|
- lib/morpheus/api/instance_types_interface.rb
|
@@ -167,6 +169,7 @@ files:
|
|
167
169
|
- lib/morpheus/api/option_type_lists_interface.rb
|
168
170
|
- lib/morpheus/api/option_types_interface.rb
|
169
171
|
- lib/morpheus/api/options_interface.rb
|
172
|
+
- lib/morpheus/api/policies_interface.rb
|
170
173
|
- lib/morpheus/api/provision_types_interface.rb
|
171
174
|
- lib/morpheus/api/roles_interface.rb
|
172
175
|
- lib/morpheus/api/security_group_rules_interface.rb
|
@@ -222,6 +225,7 @@ files:
|
|
222
225
|
- lib/morpheus/cli/monitoring_incidents_command.rb
|
223
226
|
- lib/morpheus/cli/option_parser.rb
|
224
227
|
- lib/morpheus/cli/option_types.rb
|
228
|
+
- lib/morpheus/cli/policies_command.rb
|
225
229
|
- lib/morpheus/cli/recent_activity_command.rb
|
226
230
|
- lib/morpheus/cli/remote.rb
|
227
231
|
- lib/morpheus/cli/roles.rb
|
@@ -266,7 +270,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
270
|
version: '0'
|
267
271
|
requirements: []
|
268
272
|
rubyforge_project:
|
269
|
-
rubygems_version: 2.
|
273
|
+
rubygems_version: 2.4.8
|
270
274
|
signing_key:
|
271
275
|
specification_version: 4
|
272
276
|
summary: Provides CLI Interface to the Morpheus Public/Private Cloud Appliance
|