morpheus-cli 5.4.0 → 5.4.1
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/Dockerfile +1 -1
- data/lib/morpheus/api/account_users_interface.rb +68 -0
- data/lib/morpheus/api/api_client.rb +51 -9
- data/lib/morpheus/api/audit_interface.rb +9 -0
- data/lib/morpheus/api/instances_interface.rb +21 -0
- data/lib/morpheus/api/load_balancer_monitors_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_pools_interface.rb +4 -4
- data/lib/morpheus/api/load_balancer_profiles_interface.rb +4 -5
- data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +13 -4
- data/lib/morpheus/api/load_balancers_interface.rb +5 -0
- data/lib/morpheus/api/network_routers_interface.rb +9 -0
- data/lib/morpheus/api/network_static_routes_interface.rb +36 -0
- data/lib/morpheus/api/read_interface.rb +4 -3
- data/lib/morpheus/api/rest_interface.rb +3 -3
- data/lib/morpheus/api/secondary_read_interface.rb +1 -1
- data/lib/morpheus/api/secondary_rest_interface.rb +19 -19
- data/lib/morpheus/api/storage_server_types_interface.rb +14 -0
- data/lib/morpheus/api/storage_servers_interface.rb +9 -0
- data/lib/morpheus/api/storage_volume_types_interface.rb +9 -0
- data/lib/morpheus/api/storage_volumes_interface.rb +9 -0
- data/lib/morpheus/api/users_interface.rb +16 -63
- data/lib/morpheus/cli/cli_command.rb +253 -5
- data/lib/morpheus/cli/cli_registry.rb +1 -1
- data/lib/morpheus/cli/commands/alias_command.rb +1 -1
- data/lib/morpheus/cli/commands/apps.rb +14 -78
- data/lib/morpheus/cli/commands/audit.rb +188 -0
- data/lib/morpheus/cli/commands/blueprints_command.rb +1 -1
- data/lib/morpheus/cli/commands/change_password_command.rb +4 -4
- data/lib/morpheus/cli/commands/clusters.rb +37 -12
- data/lib/morpheus/cli/commands/hosts.rb +15 -15
- data/lib/morpheus/cli/commands/instances.rb +109 -2
- data/lib/morpheus/cli/commands/load_balancer_monitors.rb +71 -0
- data/lib/morpheus/cli/commands/load_balancer_pools.rb +30 -50
- data/lib/morpheus/cli/commands/load_balancer_profiles.rb +65 -0
- data/lib/morpheus/cli/commands/load_balancer_types.rb +9 -4
- data/lib/morpheus/cli/commands/load_balancer_virtual_servers.rb +77 -57
- data/lib/morpheus/cli/commands/load_balancers.rb +93 -6
- data/lib/morpheus/cli/commands/network_firewalls_command.rb +22 -5
- data/lib/morpheus/cli/commands/network_routers_command.rb +96 -45
- data/lib/morpheus/cli/commands/network_static_routes_command.rb +446 -0
- data/lib/morpheus/cli/commands/network_transport_zones_command.rb +4 -4
- data/lib/morpheus/cli/commands/open_command.rb +30 -0
- data/lib/morpheus/cli/commands/options.rb +98 -0
- data/lib/morpheus/cli/commands/policies_command.rb +1 -1
- data/lib/morpheus/cli/commands/prices_command.rb +7 -7
- data/lib/morpheus/cli/commands/remote.rb +4 -2
- data/lib/morpheus/cli/commands/roles.rb +1 -1
- data/lib/morpheus/cli/commands/shell.rb +2 -2
- data/lib/morpheus/cli/commands/storage_server_types.rb +50 -0
- data/lib/morpheus/cli/commands/storage_servers.rb +122 -0
- data/lib/morpheus/cli/commands/storage_volume_types.rb +50 -0
- data/lib/morpheus/cli/commands/storage_volumes.rb +103 -0
- data/lib/morpheus/cli/commands/tenants_command.rb +1 -1
- data/lib/morpheus/cli/commands/user_groups_command.rb +1 -1
- data/lib/morpheus/cli/commands/user_settings_command.rb +2 -1
- data/lib/morpheus/cli/commands/user_sources_command.rb +1 -1
- data/lib/morpheus/cli/commands/users.rb +28 -28
- data/lib/morpheus/cli/commands/view.rb +102 -0
- data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -5
- data/lib/morpheus/cli/mixins/load_balancers_helper.rb +24 -4
- data/lib/morpheus/cli/mixins/print_helper.rb +50 -18
- data/lib/morpheus/cli/mixins/processes_helper.rb +1 -2
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +15 -5
- data/lib/morpheus/cli/mixins/rest_command.rb +145 -73
- data/lib/morpheus/cli/mixins/secondary_rest_command.rb +174 -81
- data/lib/morpheus/cli/mixins/storage_servers_helper.rb +156 -0
- data/lib/morpheus/cli/mixins/storage_volumes_helper.rb +119 -0
- data/lib/morpheus/cli/option_types.rb +45 -24
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/ext/string.rb +29 -6
- data/lib/morpheus/routes.rb +238 -0
- data/lib/morpheus/util.rb +6 -1
- metadata +29 -8
@@ -3,31 +3,82 @@ require 'morpheus/cli/cli_command'
|
|
3
3
|
class Morpheus::Cli::LoadBalancerVirtualServers
|
4
4
|
include Morpheus::Cli::CliCommand
|
5
5
|
include Morpheus::Cli::RestCommand
|
6
|
-
|
6
|
+
include Morpheus::Cli::SecondaryRestCommand
|
7
7
|
include Morpheus::Cli::LoadBalancersHelper
|
8
8
|
|
9
|
-
set_command_hidden
|
9
|
+
set_command_hidden
|
10
|
+
set_command_description "View and manage load balancer virtual servers."
|
10
11
|
set_command_name :'load-balancer-virtual-servers'
|
11
12
|
register_subcommands :list, :get, :add, :update, :remove
|
12
13
|
|
13
14
|
register_interfaces :load_balancer_virtual_servers,
|
14
15
|
:load_balancers, :load_balancer_types
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
# set_rest_interface_name :load_balancer_virtual_servers
|
19
|
-
# set_parent_rest_interface_name :load_balancers
|
20
|
-
|
21
|
-
# todo: a configurable way to load the optionTypes
|
22
|
-
# option_types = loadBalancer['vipOptionTypes']
|
23
|
-
# set_rest_has_type true
|
24
|
-
# set_rest_type :load_balancer_virtual_server_types
|
25
|
-
|
17
|
+
set_rest_parent_name :load_balancers
|
26
18
|
set_rest_arg 'vipName'
|
27
19
|
|
20
|
+
# overridden to provide global list functionality without requiring parent argument
|
21
|
+
def list(args)
|
22
|
+
parent_id, parent_record = nil, nil
|
23
|
+
params = {}
|
24
|
+
options = {}
|
25
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
26
|
+
opts.banner = subcommand_usage("[#{rest_parent_arg}] [search]")
|
27
|
+
build_list_options(opts, options, params)
|
28
|
+
opts.footer = <<-EOT
|
29
|
+
List #{rest_label_plural.downcase}.
|
30
|
+
[#{rest_parent_arg}] is optional. This is the #{rest_parent_has_name ? 'name or id' : 'id'} of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
|
31
|
+
[search] is optional. This is a search phrase to filter the results.
|
32
|
+
EOT
|
33
|
+
end
|
34
|
+
optparse.parse!(args)
|
35
|
+
parent_id = args[0]
|
36
|
+
connect(options)
|
37
|
+
if parent_id
|
38
|
+
args = args[1..-1]
|
39
|
+
parent_record = rest_parent_find_by_name_or_id(parent_id)
|
40
|
+
if parent_record.nil?
|
41
|
+
return 1, "#{rest_parent_label} not found for '#{parent_id}"
|
42
|
+
end
|
43
|
+
parent_id = parent_record['id']
|
44
|
+
end
|
45
|
+
parse_list_options!(args, options, params)
|
46
|
+
rest_interface.setopts(options)
|
47
|
+
if options[:dry_run]
|
48
|
+
print_dry_run rest_interface.dry.list(parent_id, params)
|
49
|
+
return
|
50
|
+
end
|
51
|
+
json_response = rest_interface.list(parent_id, params)
|
52
|
+
render_response(json_response, options, rest_list_key) do
|
53
|
+
records = json_response[rest_list_key]
|
54
|
+
print_h1 "Morpheus #{rest_label_plural}"
|
55
|
+
if records.nil? || records.empty?
|
56
|
+
print cyan,"No #{rest_label_plural.downcase} found.",reset,"\n"
|
57
|
+
else
|
58
|
+
print as_pretty_table(records, rest_list_column_definitions(options).upcase_keys!, options)
|
59
|
+
print_results_pagination(json_response) if json_response['meta']
|
60
|
+
end
|
61
|
+
print reset,"\n"
|
62
|
+
end
|
63
|
+
return 0, nil
|
64
|
+
end
|
65
|
+
|
28
66
|
protected
|
29
67
|
|
30
|
-
def
|
68
|
+
def build_list_options(opts, options, params)
|
69
|
+
opts.on('--load-balancer LB', String, "Load Balancer Name or ID") do |val|
|
70
|
+
options[:load_balancer] = val
|
71
|
+
end
|
72
|
+
# build_standard_list_options(opts, options)
|
73
|
+
super
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_list_options!(args, options, params)
|
77
|
+
parse_parameter_as_resource_id!(:load_balancer, options, params)
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
81
|
+
def load_balancer_virtual_server_list_column_definitions(options)
|
31
82
|
{
|
32
83
|
"ID" => 'id',
|
33
84
|
"Name" => 'vipName',
|
@@ -43,7 +94,7 @@ class Morpheus::Cli::LoadBalancerVirtualServers
|
|
43
94
|
}
|
44
95
|
end
|
45
96
|
|
46
|
-
def load_balancer_virtual_server_column_definitions()
|
97
|
+
def load_balancer_virtual_server_column_definitions(options)
|
47
98
|
{
|
48
99
|
"ID" => 'id',
|
49
100
|
"Name" => 'vipName',
|
@@ -63,11 +114,11 @@ class Morpheus::Cli::LoadBalancerVirtualServers
|
|
63
114
|
end
|
64
115
|
|
65
116
|
def load_balancer_virtual_server_object_key
|
66
|
-
'
|
117
|
+
'loadBalancerInstance'
|
67
118
|
end
|
68
119
|
|
69
120
|
def load_balancer_virtual_server_list_key
|
70
|
-
'
|
121
|
+
'loadBalancerInstances'
|
71
122
|
end
|
72
123
|
|
73
124
|
def load_balancer_virtual_server_label
|
@@ -78,52 +129,12 @@ class Morpheus::Cli::LoadBalancerVirtualServers
|
|
78
129
|
'Virtual Servers'
|
79
130
|
end
|
80
131
|
|
81
|
-
def find_load_balancer_virtual_server_by_name_or_id(val)
|
82
|
-
if val.to_s =~ /\A\d{1,}\Z/
|
83
|
-
return find_load_balancer_virtual_server_by_id(val)
|
84
|
-
else
|
85
|
-
return find_load_balancer_virtual_server_by_name(val)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def find_load_balancer_virtual_server_by_id(id)
|
90
|
-
begin
|
91
|
-
json_response = load_balancer_virtual_servers_interface.get(id.to_i)
|
92
|
-
return json_response[load_balancer_virtual_server_object_key]
|
93
|
-
rescue RestClient::Exception => e
|
94
|
-
if e.response && e.response.code == 404
|
95
|
-
print_red_alert "#{load_balancer_virtual_server_label} not found by id #{id}"
|
96
|
-
return nil
|
97
|
-
else
|
98
|
-
raise e
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def find_load_balancer_virtual_server_by_name(name)
|
104
|
-
json_response = load_balancer_virtual_servers_interface.list({name: name.to_s})
|
105
|
-
load_balancer_virtual_servers = json_response[load_balancer_virtual_server_list_key]
|
106
|
-
if load_balancer_virtual_servers.empty?
|
107
|
-
print_red_alert "#{load_balancer_virtual_server_label_plural} not found by name #{name}"
|
108
|
-
return load_balancer_virtual_servers
|
109
|
-
elsif load_balancer_virtual_servers.size > 1
|
110
|
-
print_red_alert "#{load_balancer_virtual_servers.size} #{load_balancer_virtual_server_label_plural.downcase} found by name #{name}"
|
111
|
-
rows = load_balancer_virtual_servers.collect do |it|
|
112
|
-
{id: it['id'], name: it['name']}
|
113
|
-
end
|
114
|
-
puts as_pretty_table(rows, [:id, :name], {color:red})
|
115
|
-
return nil
|
116
|
-
else
|
117
|
-
return load_balancer_virtual_servers[0]
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
132
|
def format_virtual_server_status(virtual_server, return_color=cyan)
|
122
133
|
out = ""
|
123
134
|
status_string = virtual_server['vipStatus'] || virtual_server['status']
|
124
135
|
if status_string.nil? || status_string.empty? || status_string == "unknown"
|
125
136
|
out << "#{white}UNKNOWN#{return_color}"
|
126
|
-
elsif status_string == '
|
137
|
+
elsif status_string == 'online'
|
127
138
|
out << "#{green}#{status_string.upcase}#{return_color}"
|
128
139
|
elsif status_string == 'syncing'
|
129
140
|
out << "#{yellow}#{status_string.upcase}#{return_color}"
|
@@ -133,4 +144,13 @@ class Morpheus::Cli::LoadBalancerVirtualServers
|
|
133
144
|
out
|
134
145
|
end
|
135
146
|
|
147
|
+
def load_option_types_for_load_balancer_virtual_server(type_record, parent_record)
|
148
|
+
load_balancer = parent_record
|
149
|
+
load_balancer_type_id = load_balancer['type']['id']
|
150
|
+
load_balancer_type = find_by_id(:load_balancer_type, load_balancer_type_id)
|
151
|
+
load_balancer_type['vipOptionTypes']
|
152
|
+
end
|
153
|
+
|
154
|
+
## using CliCommand's generic find_by methods
|
155
|
+
|
136
156
|
end
|
@@ -5,8 +5,10 @@ class Morpheus::Cli::LoadBalancers
|
|
5
5
|
include Morpheus::Cli::RestCommand
|
6
6
|
include Morpheus::Cli::LoadBalancersHelper
|
7
7
|
|
8
|
+
set_command_hidden
|
9
|
+
set_command_description "View and manage load balancers."
|
8
10
|
set_command_name :'load-balancers'
|
9
|
-
register_subcommands :list, :get, :add, :update, :remove
|
11
|
+
register_subcommands :list, :get, :add, :update, :remove, :refresh
|
10
12
|
|
11
13
|
# deprecated the `load-balancers types` command in 5.3.2, it moved to `load-balancer-types list`
|
12
14
|
register_subcommands :types
|
@@ -22,7 +24,7 @@ class Morpheus::Cli::LoadBalancers
|
|
22
24
|
record = json_response[rest_object_key]
|
23
25
|
print_h1 rest_label, [], options
|
24
26
|
print cyan
|
25
|
-
print_description_list(rest_column_definitions, record, options)
|
27
|
+
print_description_list(rest_column_definitions(options), record, options)
|
26
28
|
# show LB Ports
|
27
29
|
ports = record['ports']
|
28
30
|
if ports && ports.size > 0
|
@@ -41,6 +43,48 @@ class Morpheus::Cli::LoadBalancers
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
46
|
+
def refresh(args)
|
47
|
+
id = args[0]
|
48
|
+
record_type = nil
|
49
|
+
record_type_id = nil
|
50
|
+
options = {}
|
51
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
52
|
+
opts.banner = subcommand_usage("[#{rest_arg}] [options]")
|
53
|
+
build_standard_update_options(opts, options)
|
54
|
+
opts.footer = <<-EOT
|
55
|
+
Refresh an existing #{rest_label.downcase}.
|
56
|
+
[#{rest_arg}] is required. This is the #{rest_has_name ? 'name or id' : 'id'} of #{a_or_an(rest_label)} #{rest_label.downcase}.
|
57
|
+
EOT
|
58
|
+
end
|
59
|
+
optparse.parse!(args)
|
60
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
61
|
+
connect(options)
|
62
|
+
record = rest_find_by_name_or_id(id)
|
63
|
+
if record.nil?
|
64
|
+
return 1, "#{rest_name} not found for '#{id}'"
|
65
|
+
end
|
66
|
+
passed_options = parse_passed_options(options)
|
67
|
+
payload = {}
|
68
|
+
if options[:payload]
|
69
|
+
payload = options[:payload]
|
70
|
+
payload.deep_merge!({rest_object_key => passed_options}) unless passed_options.empty?
|
71
|
+
else
|
72
|
+
record_payload = passed_options
|
73
|
+
payload[rest_object_key] = record_payload
|
74
|
+
end
|
75
|
+
rest_interface.setopts(options)
|
76
|
+
if options[:dry_run]
|
77
|
+
print_dry_run rest_interface.dry.refresh(record['id'], payload)
|
78
|
+
return
|
79
|
+
end
|
80
|
+
json_response = rest_interface.refresh(record['id'], payload)
|
81
|
+
render_response(json_response, options, rest_object_key) do
|
82
|
+
print_green_success "Refreshing #{rest_label.downcase} #{record['name'] || record['id']}"
|
83
|
+
_get(record["id"], {}, options)
|
84
|
+
end
|
85
|
+
return 0, nil
|
86
|
+
end
|
87
|
+
|
44
88
|
# deprecated, to be removed in the future.
|
45
89
|
def types(args)
|
46
90
|
print_error yellow,"[DEPRECATED] The command `load-balancers types` is deprecated and replaced by `load-balancer-types list`.",reset,"\n"
|
@@ -49,7 +93,7 @@ class Morpheus::Cli::LoadBalancers
|
|
49
93
|
|
50
94
|
protected
|
51
95
|
|
52
|
-
def load_balancer_list_column_definitions()
|
96
|
+
def load_balancer_list_column_definitions(options)
|
53
97
|
{
|
54
98
|
"ID" => 'id',
|
55
99
|
"Name" => 'name',
|
@@ -59,7 +103,7 @@ class Morpheus::Cli::LoadBalancers
|
|
59
103
|
}
|
60
104
|
end
|
61
105
|
|
62
|
-
def load_balancer_column_definitions()
|
106
|
+
def load_balancer_column_definitions(options)
|
63
107
|
{
|
64
108
|
"ID" => 'id',
|
65
109
|
"Name" => 'name',
|
@@ -80,10 +124,53 @@ class Morpheus::Cli::LoadBalancers
|
|
80
124
|
end
|
81
125
|
|
82
126
|
# overridden to work with name or code
|
83
|
-
|
84
|
-
|
127
|
+
# nope, api works with name=code now too
|
128
|
+
# def find_load_balancer_type_by_name_or_id(name)
|
129
|
+
# load_balancer_type_for_name_or_id(name)
|
130
|
+
# end
|
131
|
+
|
132
|
+
# def add_load_balancer_option_types()
|
133
|
+
# [
|
134
|
+
# {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
|
135
|
+
# {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false},
|
136
|
+
# {'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true},
|
137
|
+
# # {'fieldName' => 'type', 'fieldLabel' => 'Storage Server Type', 'type' => 'select', 'optionSource' => 'loadBalancerTypes', 'required' => true},
|
138
|
+
# ]
|
139
|
+
# end
|
140
|
+
|
141
|
+
def add_load_balancer_advanced_option_types()
|
142
|
+
[
|
143
|
+
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'fieldGroup' => 'Advanced', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'},{'name' => 'Public', 'value' => 'public'}], 'required' => false, 'description' => 'Visibility', 'category' => 'permissions', 'defaultValue' => 'public'},
|
144
|
+
{'fieldName' => 'tenants', 'fieldLabel' => 'Tenants', 'fieldGroup' => 'Advanced', 'type' => 'multiSelect', 'optionSource' => lambda { |api_client, api_params|
|
145
|
+
api_client.options.options_for_source("allTenants", {})['data']
|
146
|
+
}},
|
147
|
+
]
|
85
148
|
end
|
86
149
|
|
150
|
+
# def update_load_balancer_option_types()
|
151
|
+
# [
|
152
|
+
# {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text'},
|
153
|
+
# {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'},
|
154
|
+
# {'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox'},
|
155
|
+
# ]
|
156
|
+
# end
|
157
|
+
|
158
|
+
def update_load_balancer_advanced_option_types()
|
159
|
+
add_load_balancer_advanced_option_types()
|
160
|
+
end
|
87
161
|
|
162
|
+
def load_option_types_for_load_balancer(type_record, parent_record)
|
163
|
+
load_balancer_type = type_record
|
164
|
+
# reload it by id to get optionTypes
|
165
|
+
option_types = load_balancer_type['optionTypes']
|
166
|
+
if option_types.nil?
|
167
|
+
load_balancer_type = find_by_id(:load_balancer_type, load_balancer_type['id'])
|
168
|
+
if load_balancer_type.nil?
|
169
|
+
raise_command_error("Load balancer type not found for id '#{id}'")
|
170
|
+
end
|
171
|
+
option_types = load_balancer_type['optionTypes']
|
172
|
+
end
|
173
|
+
return option_types
|
174
|
+
end
|
88
175
|
|
89
176
|
end
|
@@ -4,7 +4,7 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
4
4
|
include Morpheus::Cli::CliCommand
|
5
5
|
include Morpheus::Cli::ProvisioningHelper
|
6
6
|
include Morpheus::Cli::WhoamiHelper
|
7
|
-
|
7
|
+
|
8
8
|
set_command_name :'network-firewalls'
|
9
9
|
register_subcommands :list_rules, :get_rule, :add_rule, :update_rule, :remove_rule
|
10
10
|
register_subcommands :list_rule_groups, :get_rule_group, :add_rule_group, :update_rule_group, :remove_rule_group
|
@@ -65,7 +65,7 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
65
65
|
id: it['id'], group: it['groupName'], name: it['name'], description: it['description'],
|
66
66
|
priority: it['priority'], enabled: format_boolean(it['enabled']), policy: it['policy'], direction: it['direction'],
|
67
67
|
source: it['sources'].kind_of?(Array) && it['sources'].count > 0 ? it['sources'].collect {|it| it['name']}.join(', ') : (it['sources'].nil? || it['sources'].empty? ? 'any' : it['source']),
|
68
|
-
destination: it['destinations'].count > 0 ? it['destinations'].collect {|it| it['name']}.join(', ') : (it['destinations'].nil? || it['destinations'].empty? ? 'any' : it['destination'])
|
68
|
+
destination: it['destinations'].kind_of?(Array) && it['destinations'].count > 0 ? it['destinations'].collect {|it| it['name']}.join(', ') : (it['destinations'].nil? || it['destinations'].empty? ? 'any' : it['destination'])
|
69
69
|
}
|
70
70
|
|
71
71
|
if it['applications'].count
|
@@ -78,9 +78,9 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
78
78
|
|
79
79
|
applied_to = []
|
80
80
|
if server['type']['supportsFirewallRuleAppliedTarget']
|
81
|
-
applied_to << 'All Edges' if
|
82
|
-
applied_to << 'Distributed Firewall' if
|
83
|
-
applied_to +=
|
81
|
+
applied_to << 'All Edges' if it['config']['applyToAllEdges']
|
82
|
+
applied_to << 'Distributed Firewall' if it['config']['applyToAllDistributed']
|
83
|
+
applied_to += it['appliedTargets'].collect {|target| target['name']}
|
84
84
|
row[:applied_to] = applied_to.join(', ')
|
85
85
|
end
|
86
86
|
row
|
@@ -483,6 +483,11 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
483
483
|
server['type']['firewallGroupOptionTypes'].reject {|it| it['type'] == 'hidden'}.sort_by {|it| it['displayOrder']}.each do |option_type|
|
484
484
|
description_cols[option_type['fieldLabel']] = lambda {|it| Morpheus::Cli::OptionTypes.get_option_value(it, option_type, true)}
|
485
485
|
end
|
486
|
+
|
487
|
+
if is_master_account
|
488
|
+
description_cols["Visibility"] = lambda {|it| it['visibility']}
|
489
|
+
description_cols["Tenants"] = lambda {|it| it['tenants'].collect {|tenant| tenant['name']}.join(', ')}
|
490
|
+
end
|
486
491
|
print_description_list(description_cols, group)
|
487
492
|
end
|
488
493
|
else
|
@@ -505,6 +510,7 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
505
510
|
opts.on('--priority VALUE', Integer, "Priority for this firewall rule group") do |val|
|
506
511
|
options[:options]['priority'] = val
|
507
512
|
end
|
513
|
+
add_perms_options(opts, options, ['plans', 'groups'])
|
508
514
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
509
515
|
opts.footer = "Create a network firewall rule group." + "\n" +
|
510
516
|
"[server] is optional. This is the name or id of a network server.\n";
|
@@ -537,6 +543,11 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
537
543
|
|
538
544
|
# prompt options
|
539
545
|
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'ruleGroup' => ''}}), @api_client, {'networkServerId' => server['id']}, nil, true)
|
546
|
+
|
547
|
+
# prompt perms
|
548
|
+
if is_master_account
|
549
|
+
params.merge!(prompt_permissions_v2(options, ['plans', 'groups']))
|
550
|
+
end
|
540
551
|
payload = {'ruleGroup' => params.deep_merge(option_result)}
|
541
552
|
end
|
542
553
|
|
@@ -568,6 +579,7 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
568
579
|
opts.on('--priority VALUE', Integer, "Priority for this firewall rule group") do |val|
|
569
580
|
options[:options]['priority'] = val
|
570
581
|
end
|
582
|
+
add_perms_options(opts, options, ['plans', 'groups'])
|
571
583
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
572
584
|
opts.footer = "Update a network firewall rule group.\n" +
|
573
585
|
"[server] is optional. This is the name or id of an existing network server.\n" +
|
@@ -592,6 +604,11 @@ class Morpheus::Cli::NetworkFirewallsCommand
|
|
592
604
|
group = find_rule_group(server['id'], group_id)
|
593
605
|
return 1 if group.nil?
|
594
606
|
|
607
|
+
if is_master_account
|
608
|
+
params['visibility'] = options[:visibility] if !options[:visibility].nil?
|
609
|
+
params['tenants'] = options[:tenants].collect {|it| {'id' => it}} if !options[:tenants].nil?
|
610
|
+
end
|
611
|
+
|
595
612
|
payload = parse_payload(options) || {'ruleGroup' => params}
|
596
613
|
payload['ruleGroup'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options] && !payload['ruleGroup'].nil?
|
597
614
|
|
@@ -634,59 +634,51 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
634
634
|
end
|
635
635
|
|
636
636
|
def _firewall_rule_group(router_id, group_id, options)
|
637
|
-
|
638
|
-
|
639
|
-
if
|
640
|
-
|
641
|
-
|
637
|
+
@network_routers_interface.setopts(options)
|
638
|
+
if options[:dry_run]
|
639
|
+
if router_id.to_s =~ /\A\d{1,}\Z/
|
640
|
+
print_dry_run @network_routers_interface.dry.list({name:router_id})
|
641
|
+
else
|
642
|
+
if group_id.to_s =~ /\A\d{1,}\Z/
|
643
|
+
print_dry_run @network_routers_interface.dry.get_firewall_rule_group(router_id.to_i, group_id)
|
642
644
|
else
|
643
|
-
print_dry_run @network_routers_interface.dry.
|
645
|
+
print_dry_run @network_routers_interface.dry.list_firewall_rule_groups(router_id.to_i, {phrase:router_id})
|
644
646
|
end
|
645
|
-
return
|
646
647
|
end
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
group = (router['firewall']['ruleGroups'] || []).find {|it| it['id'].to_s == group_id.to_s || it['name'] == group_id.to_s}
|
648
|
+
return
|
649
|
+
end
|
650
|
+
router = find_router(router_id)
|
651
|
+
if router.nil?
|
652
|
+
return 1
|
653
|
+
end
|
654
654
|
|
655
|
-
|
656
|
-
|
655
|
+
if router['type']['hasFirewallGroups']
|
656
|
+
group = find_firewall_rule_group(router['id'], group_id)
|
657
|
+
return 1 if group.nil?
|
657
658
|
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
659
|
+
render_response({ruleGroup: group}, options, 'ruleGroup') do
|
660
|
+
print_h1 "Firewall Rule Group Details"
|
661
|
+
print cyan
|
662
|
+
description_cols = {
|
663
|
+
"ID" => lambda {|it| it['id'] },
|
664
|
+
"Name" => lambda {|it| it['name'] },
|
665
|
+
"Description" => lambda {|it| it['description']},
|
666
|
+
"Priority" => lambda {|it| it['priority']},
|
667
|
+
"Category" => lambda {|it| it['groupLayer']}
|
668
|
+
}
|
669
|
+
print_description_list(description_cols, group)
|
668
670
|
|
669
|
-
|
670
|
-
|
671
|
-
description_cols = {
|
672
|
-
"ID" => lambda {|it| it['id'] },
|
673
|
-
"Name" => lambda {|it| it['name'] },
|
674
|
-
"Description" => lambda {|it| it['description']},
|
675
|
-
"Priority" => lambda {|it| it['priority']},
|
676
|
-
"Category" => lambda {|it| it['groupLayer']}
|
677
|
-
}
|
678
|
-
print_description_list(description_cols, group)
|
679
|
-
else
|
680
|
-
print_red_alert "Firewall rule group #{group_id} not found for router #{router['name']}"
|
671
|
+
if is_master_account
|
672
|
+
description_cols["Visibility"] = lambda {|it| it['visibility']}
|
673
|
+
description_cols["Tenants"] = lambda {|it| it['tenants'].collect {|tenant| tenant['name']}.join(', ')}
|
681
674
|
end
|
682
|
-
|
683
|
-
print_h1 "No Firewall Rule Groups"
|
675
|
+
print_description_list(description_cols, group)
|
684
676
|
end
|
685
|
-
|
686
|
-
|
687
|
-
print_rest_exception(e, options)
|
677
|
+
else
|
678
|
+
print_red_alert "Firewall rule groups not supported for #{router['type']['name']}"
|
688
679
|
return 1
|
689
680
|
end
|
681
|
+
println reset
|
690
682
|
end
|
691
683
|
|
692
684
|
def add_firewall_rule_group(args)
|
@@ -703,6 +695,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
703
695
|
opts.on('--priority VALUE', Integer, "Priority for this firewall rule group (not applicable to all firewall types)") do |val|
|
704
696
|
params['priority'] = val
|
705
697
|
end
|
698
|
+
add_perms_options(opts, options, ['plans', 'groups'])
|
706
699
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
707
700
|
opts.footer = "Create a network router firewall rule group."
|
708
701
|
end
|
@@ -742,7 +735,14 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
742
735
|
|
743
736
|
# prompt options
|
744
737
|
option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'group' => ''}}), @api_client, {}, nil, true)
|
745
|
-
|
738
|
+
|
739
|
+
rule_group = params.deep_merge(option_result)
|
740
|
+
|
741
|
+
# prompt perms
|
742
|
+
if is_master_account
|
743
|
+
rule_group.merge!(prompt_permissions_v2(options, ['plans', 'groups']))
|
744
|
+
end
|
745
|
+
payload = {'ruleGroup' => rule_group}
|
746
746
|
end
|
747
747
|
|
748
748
|
@network_routers_interface.setopts(options)
|
@@ -779,6 +779,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
779
779
|
opts.on('--priority VALUE', Integer, "Priority for this firewall rule group (not applicable to all firewall types)") do |val|
|
780
780
|
params['priority'] = val
|
781
781
|
end
|
782
|
+
add_perms_options(opts, options, ['plans', 'groups'])
|
782
783
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
783
784
|
opts.footer = "Update a network router firewall rule group.\n" +
|
784
785
|
"[router] is required. This is the name or id of an existing network router.\n" +
|
@@ -810,6 +811,11 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
810
811
|
exit 1
|
811
812
|
end
|
812
813
|
|
814
|
+
if is_master_account
|
815
|
+
params['visibility'] = options[:visibility] if !options[:visibility].nil?
|
816
|
+
params['tenants'] = options[:tenants].collect {|it| {'id' => it}} if !options[:tenants].nil?
|
817
|
+
end
|
818
|
+
|
813
819
|
payload = parse_payload(options) || {'ruleGroup' => params}
|
814
820
|
payload['ruleGroup'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
815
821
|
|
@@ -2564,8 +2570,53 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
2564
2570
|
end
|
2565
2571
|
end
|
2566
2572
|
else
|
2567
|
-
rule = router['firewall'] && router['firewall']['rules'] ? router['firewall']['rules'].find {|it| it['name'] ==
|
2573
|
+
rule = router['firewall'] && router['firewall']['rules'] ? router['firewall']['rules'].find {|it| it['name'] == rule_id || it['id'] == rule_id.to_i} : nil
|
2568
2574
|
end
|
2569
2575
|
rule
|
2570
2576
|
end
|
2577
|
+
|
2578
|
+
def find_firewall_rule_group(router_id, val)
|
2579
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
2580
|
+
return find_firewall_rule_group_by_id(router_id, val)
|
2581
|
+
else
|
2582
|
+
if group = find_firewall_rule_group_by_name(router_id, val)
|
2583
|
+
return find_firewall_rule_group_by_id(router_id, group['id'])
|
2584
|
+
end
|
2585
|
+
end
|
2586
|
+
end
|
2587
|
+
|
2588
|
+
def find_firewall_rule_group_by_id(router_id, group_id)
|
2589
|
+
begin
|
2590
|
+
json_response = @network_routers_interface.get_firewall_rule_group(router_id, group_id.to_i)
|
2591
|
+
return json_response['ruleGroup']
|
2592
|
+
rescue RestClient::Exception => e
|
2593
|
+
if e.response && e.response.code == 404
|
2594
|
+
print_red_alert "Network firewall rule group not found by id #{group_id}"
|
2595
|
+
return nil
|
2596
|
+
else
|
2597
|
+
raise e
|
2598
|
+
end
|
2599
|
+
end
|
2600
|
+
end
|
2601
|
+
|
2602
|
+
def find_firewall_rule_group_by_name(router_id, name)
|
2603
|
+
groups = search_firewall_rule_groups(router_id, name)
|
2604
|
+
if groups.empty?
|
2605
|
+
print_red_alert "Network firewall rule group not found by name #{name}"
|
2606
|
+
return nil
|
2607
|
+
elsif groups.size > 1
|
2608
|
+
print_red_alert "#{scopes.size} network firewall rule groups found by name #{name}"
|
2609
|
+
rows = groups.collect do |it|
|
2610
|
+
{id: it['id'], name: it['name']}
|
2611
|
+
end
|
2612
|
+
puts as_pretty_table(rows, [:id, :name], {color:red})
|
2613
|
+
return nil
|
2614
|
+
else
|
2615
|
+
return groups[0]
|
2616
|
+
end
|
2617
|
+
end
|
2618
|
+
|
2619
|
+
def search_firewall_rule_groups(router_id, phrase = nil)
|
2620
|
+
@network_routers_interface.list_firewall_rule_groups(router_id, phrase ? {phrase: phrase.to_s} : {})['ruleGroups']
|
2621
|
+
end
|
2571
2622
|
end
|