|
9 | 9 | from .generated import blockstorage_cli |
10 | 10 | from .generated import compute_cli |
11 | 11 | from .generated import virtualnetwork_cli |
| 12 | + |
| 13 | +from oraclebmc import wait_until |
12 | 14 | from oraclebmc.exceptions import ServiceError |
| 15 | +from oraclebmc.exceptions import MaximumWaitTimeExceeded |
13 | 16 | from . import cli_util |
14 | 17 |
|
15 | 18 | blockstorage_cli.blockstorage_group.add_command(blockstorage_cli.volume_group) |
|
23 | 26 | compute_cli.compute_group.add_command(compute_cli.console_history_group) |
24 | 27 | compute_cli.instance_group.add_command(compute_cli.get_windows_instance_initial_credentials) |
25 | 28 | compute_cli.volume_attachment_group.add_command(compute_cli.detach_volume) |
| 29 | +compute_cli.vnic_attachment_group.commands.pop(compute_cli.attach_vnic.name) |
| 30 | +compute_cli.vnic_attachment_group.commands.pop(compute_cli.detach_vnic.name) |
26 | 31 |
|
27 | 32 | virtualnetwork_cli.virtual_network_group.add_command(virtualnetwork_cli.vcn_group) |
28 | 33 | virtualnetwork_cli.virtual_network_group.add_command(virtualnetwork_cli.subnet_group) |
|
55 | 60 | cli_util.update_param_help(compute_cli.launch_instance, 'subnet_id', compute_instance_launch_subnet_id_help) |
56 | 61 | cli_util.update_param_help(compute_cli.launch_instance, 'hostname_label', compute_instance_launch_hostname_label_help, example='`bminstance-1`') |
57 | 62 |
|
| 63 | + |
| 64 | +image_source_details_example = """'{ "objectName": "image-to-import.qcow2", "bucketName": "MyBucket", "namespaceName": "MyNamespace", "sourceType": "objectStorageTuple" }' |
| 65 | +
|
| 66 | +or |
| 67 | +
|
| 68 | +'{ "sourceUri": "https://objectstorage.us-phoenix-1.oraclecloud.com/n/MyNamespace/b/MyBucket/o/image-to-import.qcow2", "sourceType": "objectStorageUri" }'""" |
| 69 | +cli_util.update_param_help(compute_cli.create_image, 'image_source_details', "", append=True, example=image_source_details_example) |
| 70 | + |
| 71 | +destination_type_example = """'{ "objectName": "image-to-import.qcow2", "bucketName": "MyBucket", "namespaceName": "MyNamespace", "sourceType": "objectStorageTuple" }' |
| 72 | +
|
| 73 | +or |
| 74 | +
|
| 75 | +'{ "destinationUri": "https://objectstorage.us-phoenix-1.oraclecloud.com/n/MyNamespace/b/MyBucket/o/exported-image.qcow2", "destinationType": "objectStorageUri" }'""" |
| 76 | +cli_util.update_param_help(compute_cli.export_image, 'destination_type', "", append=True, example=destination_type_example) |
| 77 | + |
58 | 78 | # help for bmcs network ip-sec-connection create --static-routes |
59 | 79 | network_create_ip_sec_connection_static_routes_example = """'["10.0.0.0/16"]'""" |
60 | 80 | network_create_ip_sec_connection_static_routes_help = """Static routes to the CPE. At least one route must be included. The CIDR must not be a multicast address or class E address. This must be provided in JSON format.""" |
@@ -201,3 +221,72 @@ def launch_instance_extended(ctx, **kwargs): |
201 | 221 | del kwargs['vnic_display_name'] |
202 | 222 |
|
203 | 223 | ctx.invoke(compute_cli.launch_instance, **kwargs) |
| 224 | + |
| 225 | + |
| 226 | +@compute_cli.instance_group.command(name='attach-vnic', help="""Creates a secondary VNIC and attaches it to the specified instance. For more information about secondary VNICs, see [Managing Virtual Network Interface Cards (VNICs)].""") |
| 227 | +@click.option('--instance-id', required=True, help="""The OCID of the instance.""") |
| 228 | +@click.option('--subnet-id', required=True, help="""The OCID of the subnet to create the VNIC in.""") |
| 229 | +@click.option('--vnic-display-name', required=False, help="""A user-friendly name for the VNIC. Does not have to be unique.""") |
| 230 | +@click.option('--assign-public-ip', required=False, type=click.BOOL, help="""Whether the VNIC should be assigned a public IP address. Defaults to whether the subnet is public or private. If not set and the VNIC is being created in a private subnet (i.e., where prohibitPublicIpOnVnic=true in the Subnet), then no public IP address is assigned. If not set and the subnet is public (prohibitPublicIpOnVnic=false), then a public IP address is assigned. If set to true and prohibitPublicIpOnVnic=true, an error is returned.""") |
| 231 | +@click.option('--private-ip', required=False, help="""A private IP address of your choice to assign to the VNIC. Must be an available IP address within the subnet's CIDR. If no value is specified, a private IP address from the subnet will be automatically assigned.""") |
| 232 | +@click.option('--hostname-label', help="""The hostname for the VNIC. Used for DNS. The value is the hostname portion of the VNIC's fully qualified domain name (FQDN) (e.g., `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). Must be unique across all VNICs in the subnet and comply with [RFC 952](https://tools.ietf.org/html/rfc952) and [RFC 1123](https://tools.ietf.org/html/rfc1123). The value can be retrieved from the [Vnic](#/en/iaas/20160918/Vnic/).""") |
| 233 | +@click.option('--wait', is_flag=True, default=False, help="""If set, then wait for the attachment to complete and return the newly attached VNIC. If not set, then the command will not wait and will return nothing on success.""") |
| 234 | +@cli_util.help_option |
| 235 | +@click.pass_context |
| 236 | +@cli_util.wrap_exceptions |
| 237 | +def attach_vnic(ctx, instance_id, subnet_id, vnic_display_name, assign_public_ip, private_ip, hostname_label, wait): |
| 238 | + kwargs = {} |
| 239 | + |
| 240 | + vnic_details = {} |
| 241 | + vnic_details['subnetId'] = subnet_id |
| 242 | + vnic_details['displayName'] = vnic_display_name |
| 243 | + vnic_details['assignPublicIp'] = assign_public_ip |
| 244 | + vnic_details['privateIp'] = private_ip |
| 245 | + vnic_details['hostnameLabel'] = hostname_label |
| 246 | + |
| 247 | + attachment_details = {} |
| 248 | + attachment_details['createVnicDetails'] = vnic_details |
| 249 | + attachment_details['instanceId'] = instance_id |
| 250 | + |
| 251 | + compute_client = cli_util.build_client('compute', ctx) |
| 252 | + response = compute_client.attach_vnic( |
| 253 | + attach_vnic_details=attachment_details, |
| 254 | + **kwargs |
| 255 | + ) |
| 256 | + |
| 257 | + if not wait: |
| 258 | + return |
| 259 | + |
| 260 | + response = compute_client.get_vnic_attachment(response.data.id) |
| 261 | + |
| 262 | + try: |
| 263 | + response = wait_until(compute_client, response, 'lifecycle_state', 'ATTACHED', max_wait_seconds=180) |
| 264 | + except MaximumWaitTimeExceeded: |
| 265 | + sys.exit('Timed out while waiting for the VNIC attachment to reach the ATTACHED state.') |
| 266 | + |
| 267 | + if not response.data.vnic_id: |
| 268 | + sys.exit('The VNIC ID is not set on the VNIC attachment.') |
| 269 | + |
| 270 | + network_client = cli_util.build_client('virtual_network', ctx) |
| 271 | + response = network_client.get_vnic(vnic_id=response.data.vnic_id) |
| 272 | + cli_util.render_response(response) |
| 273 | + |
| 274 | + |
| 275 | +@compute_cli.instance_group.command(name='detach-vnic', help="""Detaches and deletes the specified secondary VNIC. This operation cannot be used on the instance's primary VNIC. When you terminate an instance, all attached VNICs (primary and secondary) are automatically detached and deleted.""") |
| 276 | +@click.option('--vnic-id', required=True, help="""The OCID of the VNIC.""") |
| 277 | +@click.option('--compartment-id', required=True, help="""The OCID of the instance's compartment.""") |
| 278 | +@cli_util.confirm_delete_option |
| 279 | +@cli_util.help_option |
| 280 | +@click.pass_context |
| 281 | +@cli_util.wrap_exceptions |
| 282 | +def detach_vnic(ctx, vnic_id, compartment_id): |
| 283 | + compute_client = cli_util.build_client('compute', ctx) |
| 284 | + result = compute_client.list_vnic_attachments(compartment_id=compartment_id, vnic_id=vnic_id) |
| 285 | + |
| 286 | + if result.data is None or len(result.data) == 0: |
| 287 | + sys.exit('A VNIC attachment could not be found for the given VNIC ID.') |
| 288 | + |
| 289 | + vnic_attachment_id = result.data[0].id |
| 290 | + result = compute_client.detach_vnic(vnic_attachment_id=vnic_attachment_id) |
| 291 | + |
| 292 | + cli_util.render_response(result) |
0 commit comments