diff --git a/src/horizondb/azext_horizondb/_client_factory.py b/src/horizondb/azext_horizondb/_client_factory.py index fe3ddcce26f..9fd760831f0 100644 --- a/src/horizondb/azext_horizondb/_client_factory.py +++ b/src/horizondb/azext_horizondb/_client_factory.py @@ -36,3 +36,7 @@ def resource_client_factory(cli_ctx, subscription_id=None): def cf_horizondb_clusters(cli_ctx, _): return get_horizondb_management_client(cli_ctx).horizon_db_clusters + + +def cf_horizondb_firewall_rules(cli_ctx, _): + return get_horizondb_management_client(cli_ctx).horizon_db_firewall_rules diff --git a/src/horizondb/azext_horizondb/_help.py b/src/horizondb/azext_horizondb/_help.py index 8b75c209e64..a217bc8b0a5 100644 --- a/src/horizondb/azext_horizondb/_help.py +++ b/src/horizondb/azext_horizondb/_help.py @@ -53,3 +53,58 @@ - name: List Azure HorizonDB clusters in a resource group. text: az horizondb list --resource-group exampleresourcegroup """ + + +helps['horizondb firewall-rule'] = """ +type: group +short-summary: Manage firewall rules for Azure HorizonDB clusters. +""" + + +helps['horizondb firewall-rule create'] = """ +type: command +short-summary: Create a new firewall rule for a HorizonDB cluster. +examples: + - name: Create a firewall rule. + text: az horizondb firewall-rule create --name examplecluster --resource-group exampleresourcegroup --rule-name allowall --start-ip-address 0.0.0.0 --end-ip-address 255.255.255.255 + - name: Create a firewall rule with a description. + text: az horizondb firewall-rule create --name examplecluster --resource-group exampleresourcegroup --rule-name office --start-ip-address 10.0.0.1 --end-ip-address 10.0.0.255 --rule-description "Office IP range" +""" + + +helps['horizondb firewall-rule delete'] = """ +type: command +short-summary: Delete an existing firewall rule. +examples: + - name: Delete a firewall rule. + text: az horizondb firewall-rule delete --name examplecluster --resource-group exampleresourcegroup --rule-name allowall + - name: Delete a firewall rule without confirmation. + text: az horizondb firewall-rule delete --name examplecluster --resource-group exampleresourcegroup --rule-name allowall --yes +""" + + +helps['horizondb firewall-rule show'] = """ +type: command +short-summary: Get the details of a specific firewall rule. +examples: + - name: Show a firewall rule. + text: az horizondb firewall-rule show --name examplecluster --resource-group exampleresourcegroup --rule-name allowall +""" + + +helps['horizondb firewall-rule update'] = """ +type: command +short-summary: Update an existing firewall rule. +examples: + - name: Update a firewall rule's IP range. + text: az horizondb firewall-rule update --name examplecluster --resource-group exampleresourcegroup --rule-name allowall --start-ip-address 10.0.0.0 --end-ip-address 10.0.0.255 +""" + + +helps['horizondb firewall-rule list'] = """ +type: command +short-summary: List firewall rules for a HorizonDB cluster. +examples: + - name: List all firewall rules. + text: az horizondb firewall-rule list --name examplecluster --resource-group exampleresourcegroup +""" diff --git a/src/horizondb/azext_horizondb/_params.py b/src/horizondb/azext_horizondb/_params.py index fedd6097eb6..c14faab3b56 100644 --- a/src/horizondb/azext_horizondb/_params.py +++ b/src/horizondb/azext_horizondb/_params.py @@ -81,4 +81,43 @@ def _horizondb_params(): with self.argument_context('horizondb delete') as c: c.argument('yes', arg_type=yes_arg_type) + # Firewall rule params + firewall_rule_name_arg_type = CLIArgumentType( + options_list=['--rule-name'], + help='Name of the firewall rule.') + + pool_name_arg_type = CLIArgumentType( + options_list=['--pool-name'], + default='default', + help='Name of the HorizonDB pool. Defaults to "default".') + + start_ip_address_arg_type = CLIArgumentType( + options_list=['--start-ip-address'], + help='The start IP address of the firewall rule (IPv4).') + + end_ip_address_arg_type = CLIArgumentType( + options_list=['--end-ip-address'], + help='The end IP address of the firewall rule (IPv4).') + + rule_description_arg_type = CLIArgumentType( + options_list=['--rule-description'], + help='The description of the firewall rule.') + + with self.argument_context('horizondb firewall-rule') as c: + c.argument('firewall_rule_name', arg_type=firewall_rule_name_arg_type) + c.argument('pool_name', arg_type=pool_name_arg_type) + + with self.argument_context('horizondb firewall-rule create') as c: + c.argument('start_ip_address', arg_type=start_ip_address_arg_type) + c.argument('end_ip_address', arg_type=end_ip_address_arg_type) + c.argument('rule_description', arg_type=rule_description_arg_type) + + with self.argument_context('horizondb firewall-rule update') as c: + c.argument('start_ip_address', arg_type=start_ip_address_arg_type) + c.argument('end_ip_address', arg_type=end_ip_address_arg_type) + c.argument('rule_description', arg_type=rule_description_arg_type) + + with self.argument_context('horizondb firewall-rule delete') as c: + c.argument('yes', arg_type=yes_arg_type) + _horizondb_params() diff --git a/src/horizondb/azext_horizondb/cluster_commands.py b/src/horizondb/azext_horizondb/cluster_commands.py index 9df2c7c1322..d95c1290b3e 100644 --- a/src/horizondb/azext_horizondb/cluster_commands.py +++ b/src/horizondb/azext_horizondb/cluster_commands.py @@ -5,7 +5,8 @@ from azure.cli.core.commands import CliCommandType from azext_horizondb._client_factory import ( - cf_horizondb_clusters) + cf_horizondb_clusters, + cf_horizondb_firewall_rules) from azext_horizondb.utils._transformers import ( table_transform_output) @@ -17,8 +18,15 @@ def load_command_table(self, _): client_factory=cf_horizondb_clusters ) + horizondb_firewall_rules_sdk = CliCommandType( + operations_tmpl='azext_horizondb.vendored_sdks.operations#HorizonDbFirewallRulesOperations.{}', + client_factory=cf_horizondb_firewall_rules + ) + custom_commands = CliCommandType( operations_tmpl='azext_horizondb.commands.custom_commands#{}') + firewall_custom_commands = CliCommandType( + operations_tmpl='azext_horizondb.commands.firewall_commands#{}') with self.command_group('horizondb', horizondb_clusters_sdk, custom_command_type=custom_commands, client_factory=cf_horizondb_clusters) as g: @@ -26,3 +34,12 @@ def load_command_table(self, _): g.custom_command('delete', 'horizondb_cluster_delete') g.custom_command('list', 'horizondb_cluster_list') g.show_command('show', 'get') + + with self.command_group('horizondb firewall-rule', horizondb_firewall_rules_sdk, + custom_command_type=firewall_custom_commands, + client_factory=cf_horizondb_firewall_rules) as g: + g.custom_command('create', 'horizondb_firewall_rule_create') + g.custom_command('delete', 'horizondb_firewall_rule_delete', confirmation=False) + g.custom_command('update', 'horizondb_firewall_rule_update') + g.custom_command('list', 'horizondb_firewall_rule_list') + g.show_command('show', 'get') diff --git a/src/horizondb/azext_horizondb/commands/firewall_commands.py b/src/horizondb/azext_horizondb/commands/firewall_commands.py new file mode 100644 index 00000000000..1fc2df5c77e --- /dev/null +++ b/src/horizondb/azext_horizondb/commands/firewall_commands.py @@ -0,0 +1,87 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# pylint: disable=line-too-long, too-many-locals + +from knack.log import get_logger +from azure.cli.core.util import sdk_no_wait, user_confirmation + +logger = get_logger(__name__) + + +def horizondb_firewall_rule_create(client, resource_group_name, cluster_name, + firewall_rule_name, start_ip_address, end_ip_address, + pool_name='default', + rule_description=None, no_wait=False): + from azext_horizondb.vendored_sdks.models import HorizonDbFirewallRule, HorizonDbFirewallRuleProperties + + properties = HorizonDbFirewallRuleProperties( + start_ip_address=start_ip_address, + end_ip_address=end_ip_address, + description=rule_description, + ) + + resource = HorizonDbFirewallRule( + properties=properties, + ) + + return sdk_no_wait(no_wait, client.begin_create_or_update, + resource_group_name=resource_group_name, + cluster_name=cluster_name, + pool_name=pool_name, + firewall_rule_name=firewall_rule_name, + resource=resource) + + +def horizondb_firewall_rule_update(client, resource_group_name, cluster_name, + firewall_rule_name, pool_name='default', + start_ip_address=None, end_ip_address=None, + rule_description=None, no_wait=False): + from azext_horizondb.vendored_sdks.models import HorizonDbFirewallRule, HorizonDbFirewallRuleProperties + + existing = client.get( + resource_group_name=resource_group_name, + cluster_name=cluster_name, + pool_name=pool_name, + firewall_rule_name=firewall_rule_name) + + props = existing.properties + properties = HorizonDbFirewallRuleProperties( + start_ip_address=start_ip_address if start_ip_address is not None else props.start_ip_address, + end_ip_address=end_ip_address if end_ip_address is not None else props.end_ip_address, + description=rule_description if rule_description is not None else props.description, + ) + + resource = HorizonDbFirewallRule( + properties=properties, + ) + + return sdk_no_wait(no_wait, client.begin_create_or_update, + resource_group_name=resource_group_name, + cluster_name=cluster_name, + pool_name=pool_name, + firewall_rule_name=firewall_rule_name, + resource=resource) + + +def horizondb_firewall_rule_delete(cmd, client, resource_group_name, cluster_name, + firewall_rule_name, pool_name='default', + no_wait=False, yes=False): + if not yes: + user_confirmation( + "Are you sure you want to delete the firewall rule '{0}' for cluster '{1}' in resource group '{2}'".format( + firewall_rule_name, cluster_name, resource_group_name), yes=yes) + return sdk_no_wait(no_wait, client.begin_delete, + resource_group_name=resource_group_name, + cluster_name=cluster_name, + pool_name=pool_name, + firewall_rule_name=firewall_rule_name) + + +def horizondb_firewall_rule_list(client, resource_group_name, cluster_name, pool_name='default'): + return client.list( + resource_group_name=resource_group_name, + cluster_name=cluster_name, + pool_name=pool_name)