def launch_instance(compute, compartment, test_id, availability_domain, subnet,
                    public_key):
    # print('Launching instance')

    request = oci.core.models.LaunchInstanceDetails()
    request.availability_domain = availability_domain
    request.compartment_id = compartment
    request.display_name = 'pythonsdk_tutorial_instance_' + test_id
    # Oracle-Linux-7.3-2017.03.03-0
    request.image_id = util.oracle_linux_image()
    request.shape = 'VM.Standard1.1'
    request.subnet_id = subnet.id
    request.metadata = {'ssh_authorized_keys': public_key}
    response = compute.launch_instance(request)

    assert response.status == 200
    assert 'PROVISIONING' == response.data.lifecycle_state

    response = compute.get_instance(response.data.id)
    instance = test_config_container.do_wait(compute,
                                             response,
                                             'lifecycle_state',
                                             'RUNNING',
                                             max_wait_seconds=300).data

    assert 'RUNNING' == instance.lifecycle_state
    return instance
def launch_instance(compute, compartment, test_id, availability_domain, subnet, public_key):
    print('Launching instance')

    request = oci.core.models.LaunchInstanceDetails()
    request.availability_domain = availability_domain
    request.compartment_id = compartment
    request.display_name = 'pythonsdk_tutorial_instance_' + test_id
    # Oracle-Linux-7.3-2017.03.03-0
    request.image_id = util.oracle_linux_image()
    request.shape = 'VM.Standard1.1'
    request.subnet_id = subnet.id
    request.metadata = {'ssh_authorized_keys': public_key}
    response = compute.launch_instance(request)

    assert response.status == 200
    assert 'PROVISIONING' == response.data.lifecycle_state

    response = compute.get_instance(response.data.id)
    instance = test_config_container.do_wait(
        compute,
        response,
        'lifecycle_state',
        'RUNNING',
        max_wait_seconds=300
    ).data

    assert 'RUNNING' == instance.lifecycle_state
    return instance
Ejemplo n.º 3
0
    def subtest_launch_instance_merges_user_data_file_param_with_metadata(
            self):
        instance_name = util.random_name('cli_test_instance_options')
        image_id = util.oracle_linux_image()
        shape = 'VM.Standard1.2'
        hostname_label = util.random_name('bminstance',
                                          insert_underscore=False)

        launch_instance_result = util.invoke_command([
            'compute', 'instance', 'launch', '--compartment-id',
            util.COMPARTMENT_ID, '--availability-domain',
            util.availability_domain(), '--display-name', instance_name,
            '--subnet-id', self.subnet_ocid, '--image-id', image_id, '--shape',
            shape, '--hostname-label', hostname_label + "4",
            '--user-data-file', USER_DATA_FILE, '--metadata',
            util.remove_outer_quotes(oci_cli_compute.compute_cli_extended.
                                     compute_instance_launch_metadata_example)
        ])

        util.validate_response(launch_instance_result, expect_etag=True)
        temp_instance_ocid = util.find_id_in_response(
            launch_instance_result.output)
        self.instance_ocids.append(temp_instance_ocid)

        response = json.loads(launch_instance_result.output)
        instance_metadata = response['data']['metadata']
        assert instance_metadata['user_data']
        assert instance_metadata['ssh_authorized_keys']

        self.delete_instance(temp_instance_ocid)
Ejemplo n.º 4
0
    def subtest_instance_operations(self):
        instance_name = util.random_name('cli_test_instance')
        fault_domain = 'FAULT-DOMAIN-1'
        image_id = util.oracle_linux_image()
        shape = 'VM.Standard1.1'

        result = self.invoke(
            ['compute', 'instance', 'launch',
             '--compartment-id', util.COMPARTMENT_ID,
             '--availability-domain', util.availability_domain(),
             '--display-name', instance_name,
             '--fault-domain', fault_domain,
             '--subnet-id', self.subnet_ocid,
             '--image-id', image_id,
             '--shape', shape,
             '--metadata', util.remove_outer_quotes(oci_cli_compute.compute_cli_extended.compute_instance_launch_metadata_example)])
        self.instance_ocid = util.find_id_in_response(result.output)
        util.validate_response(result, expect_etag=True)

        util.wait_until(['compute', 'instance', 'get', '--instance-id', self.instance_ocid], 'RUNNING',
                        max_wait_seconds=600)

        result = self.invoke(['compute', 'instance', 'list', '--compartment-id', util.COMPARTMENT_ID])
        util.validate_response(result)

        # list with compartment shortcut
        result = self.invoke(['compute', 'instance', 'list', '-c', util.COMPARTMENT_ID])
        util.validate_response(result)

        instance_name = instance_name + "_updated"
        result = self.invoke(['compute', 'instance', 'update', '--instance-id', self.instance_ocid, '--display-name', instance_name])
        util.validate_response(result, expect_etag=True)

        result = self.invoke(['compute', 'instance', 'get', '--instance-id', self.instance_ocid])
        util.validate_response(result, expect_etag=True)

        result = self.invoke(
            ['compute', 'instance', 'launch',
             '--compartment-id', util.COMPARTMENT_ID,
             '--availability-domain', util.availability_domain(),
             '--display-name', instance_name + "_2",
             '--fault-domain', fault_domain,
             '--subnet-id', self.subnet_ocid,
             '--image-id', image_id,
             '--shape', shape,
             '--metadata',
             util.remove_outer_quotes(oci_cli_compute.compute_cli_extended.compute_instance_launch_metadata_example),
             '--wait-for-state', 'RUNNING',
             '--max-wait-seconds', '20',
             '--wait-interval-seconds', '5'])
        self.instance_ocid_2 = util.find_id_in_response(result.output[result.output.index('{'):])
        assert result.exit_code != 0
Ejemplo n.º 5
0
    def subtest_launch_instance_ssh_authorized_keys_in_param_and_in_metadata_throws_error(self):
        instance_name = util.random_name('cli_test_instance_options')
        image_id = util.oracle_linux_image()
        shape = 'VM.Standard1.2'
        hostname_label = util.random_name('bminstance', insert_underscore=False)

        launch_instance_result = util.invoke_command(
            ['compute', 'instance', 'launch',
             '--compartment-id', util.COMPARTMENT_ID,
             '--availability-domain', util.availability_domain(),
             '--display-name', instance_name,
             '--subnet-id', self.subnet_ocid,
             '--image-id', image_id,
             '--shape', shape,
             '--hostname-label', hostname_label + "2",
             '--ssh-authorized-keys-file', util.SSH_AUTHORIZED_KEYS_FILE,
             '--metadata', util.remove_outer_quotes(oci_cli_compute.compute_cli_extended.compute_instance_launch_metadata_example)])

        assert launch_instance_result.exit_code != 0
Ejemplo n.º 6
0
    def subtest_launch_instance_user_data_in_param_and_in_metadata_throws_error(
            self):
        instance_name = util.random_name('cli_test_instance_options')
        image_id = util.oracle_linux_image()
        shape = 'VM.Standard1.2'
        hostname_label = util.random_name('bminstance',
                                          insert_underscore=False)

        metadata = """{"user_data": "IyEvYmluL2Jhc2gKCm1rZGlyIC90bXAvbXlkaXIKdG91Y2ggL3RtcC9teWRpci9teXR4dC50eHQ="}"""

        launch_instance_result = util.invoke_command([
            'compute', 'instance', 'launch', '--compartment-id',
            util.COMPARTMENT_ID, '--availability-domain',
            util.availability_domain(), '--display-name', instance_name,
            '--subnet-id', self.subnet_ocid, '--image-id', image_id, '--shape',
            shape, '--hostname-label', hostname_label, '--user-data-file',
            USER_DATA_FILE, '--metadata', metadata
        ])

        assert launch_instance_result.exit_code != 0
Ejemplo n.º 7
0
def test_boot_volume_clone_backup(network_resources):
    with test_config_container.create_vcr(cassette_library_dir=CASSETTE_LIBRARY_DIR).use_cassette('boot_volume_test_boot_volume_clone_backup.yml'):
        boot_volume_id = None
        instance_ocid = None
        backup_boot_volume_id = None
        cloned_boot_volume_id = None
        backup_id = None
        try:
            instance_name = util.random_name('boot_vol_instance')
            image_id = util.oracle_linux_image()
            shape = 'VM.Standard1.1'
            hostname_label = util.random_name('bootvolinst', insert_underscore=False)
            boot_volume_size_in_gbs = '51'

            result = invoke([
                'compute', 'instance', 'launch',
                '--compartment-id', util.COMPARTMENT_ID,
                '--availability-domain', util.availability_domain(),
                '--display-name', instance_name,
                '--subnet-id', network_resources[1],
                '--image-id', image_id,
                '--shape', shape,
                '--hostname-label', hostname_label,
                '--boot-volume-size-in-gbs', boot_volume_size_in_gbs,
                '--wait-for-state', 'RUNNING',
                '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS
            ])
            util.validate_response(result, json_response_expected=False)
            instance_data = util.get_json_from_mixed_string(result.output)['data']
            instance_ocid = instance_data['id']
            assert 'image' == instance_data['source-details']['source-type']
            assert image_id == instance_data['source-details']['image-id']

            result = invoke([
                'compute', 'boot-volume-attachment', 'list',
                '-c', util.COMPARTMENT_ID,
                '--availability-domain', util.availability_domain(),
                '--instance-id', instance_data['id']
            ])
            util.validate_response(result)
            parsed_result = json.loads(result.output)
            assert len(parsed_result['data']) == 1
            boot_volume_id = parsed_result['data'][0]['boot-volume-id']

            result = invoke([
                'bv', 'boot-volume', 'get',
                '--boot-volume-id', boot_volume_id
            ])
            util.validate_response(result)
            parsed_result = json.loads(result.output)
            boot_volume_size_in_gbs = parsed_result['data']['size-in-gbs']
            assert boot_volume_size_in_gbs == int(boot_volume_size_in_gbs)

            result = invoke([
                'compute', 'instance', 'terminate',
                '--instance-id', instance_ocid,
                '--wait-for-state', 'TERMINATED',
                '--preserve-boot-volume', 'true',
                '--force'
            ])
            util.validate_response(result, json_response_expected=False)
            instance_ocid = None

            # Since we preserved the volume it should still be available
            result = invoke(['bv', 'boot-volume', 'get', '--boot-volume-id', boot_volume_id])
            util.validate_response(result)
            parsed_result = json.loads(result.output)
            assert util.availability_domain() == parsed_result['data']['availability-domain']
            assert 'AVAILABLE' == parsed_result['data']['lifecycle-state']
            assert image_id == parsed_result['data']['image-id']
            size_in_gbs = int(parsed_result['data']['size-in-gbs'])

            new_size_in_gbs = size_in_gbs + 10

            # Resize boot volume to new_size_in_gbs
            result = invoke(['bv', 'boot-volume', 'update', '--boot-volume-id', boot_volume_id,
                             '--size-in-gbs', str(new_size_in_gbs),
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            util.validate_response(result, json_response_expected=False)

            # Since we preserved the volume it should still be available
            result = invoke(['bv', 'boot-volume', 'get', '--boot-volume-id', boot_volume_id])
            util.validate_response(result)
            parsed_result = json.loads(result.output)
            assert 'AVAILABLE' == parsed_result['data']['lifecycle-state']
            assert new_size_in_gbs == int(parsed_result['data']['size-in-gbs'])

            # Take a backup
            result = invoke(['bv', 'boot-volume-backup', 'create', '--boot-volume-id', boot_volume_id,
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            util.validate_response(result, json_response_expected=False)
            parsed_result = util.get_json_from_mixed_string(result.output)
            assert boot_volume_id == parsed_result['data']['boot-volume-id']
            assert image_id == parsed_result['data']['image-id']
            assert 'AVAILABLE' == parsed_result['data']['lifecycle-state']
            backup_id = parsed_result['data']['id']

            # Boot Volume Create Error cases

            # Error 1: No option specified
            result = invoke(['bv', 'boot-volume', 'create',
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            assert "An empty boot volume cannot be created. Please specify either --boot-volume-backup-id, --source-boot-volume-id or --source-volume-replica-id" in result.output

            # Error 2: Both options specified
            result = invoke(['bv', 'boot-volume', 'create',
                             '--source-boot-volume-id', boot_volume_id[0],
                             '--boot-volume-backup-id', boot_volume_id[0],
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            assert "You can only specify one of either --source-boot-volume-id, --boot-volume-backup-id or --source-volume-replica-id option" in result.output

            # Clone the boot volume (Error 1: Invalid Boot Volume ID)
            result = invoke(['bv', 'boot-volume', 'create',
                             '--source-boot-volume-id', boot_volume_id[0],
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            util.validate_service_error(result, error_message="InvalidParameter")

            backup_policy_ids = get_backup_policy_ids()
            create_new_size_in_gbs = new_size_in_gbs + 10

            # Clone the boot volume with bronze backup policy and larger size
            result = invoke(['bv', 'boot-volume', 'create',
                             '--source-boot-volume-id', boot_volume_id,
                             '--backup-policy-id', backup_policy_ids["bronze"],
                             '--wait-for-state', 'AVAILABLE',
                             '--size-in-gbs', str(create_new_size_in_gbs),
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            util.validate_response(result, json_response_expected=False)
            parsed_result = util.get_json_from_mixed_string(result.output)
            assert util.availability_domain() == parsed_result['data']['availability-domain']
            assert 'AVAILABLE' == parsed_result['data']['lifecycle-state']
            assert image_id == parsed_result['data']['image-id']
            assert create_new_size_in_gbs == int(parsed_result['data']['size-in-gbs'])
            cloned_boot_volume_id = parsed_result['data']['id']

            # Verify the backup policy
            result = invoke(['bv', 'volume-backup-policy-assignment',
                             'get-volume-backup-policy-asset-assignment',
                             '--asset-id', cloned_boot_volume_id])
            util.validate_response(result)
            parsed_result = json.loads(result.output)
            backup_policy_assignment_id = parsed_result["data"][0]["id"]
            assert parsed_result["data"][0]["policy-id"] == backup_policy_ids["bronze"]

            # Remove backup policy
            result = invoke(['bv', 'volume-backup-policy-assignment',
                             'delete', '--policy-assignment-id', backup_policy_assignment_id, '--force'])
            util.validate_response(result)

            # Change backup policy to silver
            result = invoke(['bv', 'volume-backup-policy-assignment', 'create',
                             '--asset-id', cloned_boot_volume_id,
                             '--policy-id', backup_policy_ids['silver']])
            util.validate_response(result)
            parsed_result = json.loads(result.output)
            backup_policy_assignment_id = parsed_result["data"]["id"]
            assert parsed_result["data"]["policy-id"] == backup_policy_ids["silver"]

            # Remove the backup policy
            result = invoke(['bv', 'volume-backup-policy-assignment',
                             'delete', '--policy-assignment-id', backup_policy_assignment_id, '--force'])
            util.validate_response(result)

            # We can now launch an instance using that boot volume
            result = invoke([
                'compute', 'instance', 'launch',
                '--compartment-id', util.COMPARTMENT_ID,
                '--availability-domain', util.availability_domain(),
                '--display-name', instance_name,
                '--subnet-id', network_resources[1],
                '--shape', shape,
                '--hostname-label', hostname_label,
                '--source-boot-volume-id', cloned_boot_volume_id,
                '--wait-for-state', 'RUNNING',
                '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS
            ])
            util.validate_response(result, json_response_expected=False)
            instance_data = util.get_json_from_mixed_string(result.output)['data']
            instance_ocid = instance_data['id']
            assert 'bootVolume' == instance_data['source-details']['source-type']
            assert cloned_boot_volume_id == instance_data['source-details']['boot-volume-id']

            clean_up_instances(instance_ocid)
            cloned_boot_volume_id = None
            instance_ocid = None

            # Delete existing boot volume
            clean_up_boot_volume(boot_volume_id)
            boot_volume_id = None

            # Create boot volume from backup (Error 1: Invalid Backup Volume ID)
            result = invoke(['bv', 'boot-volume', 'create',
                             '--boot-volume-backup-id', backup_id[0],
                             '--availability-domain', util.availability_domain(),
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            util.validate_service_error(result, error_message="InvalidParameter")

            # Create boot volume from backup (Error 2: Availability domain not specified)
            result = invoke(['bv', 'boot-volume', 'create',
                             '--boot-volume-backup-id', backup_id,
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            assert "An availability domain must be specified when restoring a boot volume from backup" in result.output

            # Create boot volume from backup
            result = invoke(['bv', 'boot-volume', 'create',
                             '--boot-volume-backup-id', backup_id,
                             '--availability-domain', util.availability_domain(),
                             '--wait-for-state', 'AVAILABLE',
                             '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS])
            util.validate_response(result, json_response_expected=False)
            parsed_result = util.get_json_from_mixed_string(result.output)
            assert util.availability_domain() == parsed_result['data']['availability-domain']
            assert 'AVAILABLE' == parsed_result['data']['lifecycle-state']
            assert image_id == parsed_result['data']['image-id']
            backup_boot_volume_id = parsed_result['data']['id']

            # We can now launch an instance using that boot volume
            result = invoke([
                'compute', 'instance', 'launch',
                '--compartment-id', util.COMPARTMENT_ID,
                '--availability-domain', util.availability_domain(),
                '--display-name', instance_name,
                '--subnet-id', network_resources[1],
                '--shape', shape,
                '--hostname-label', hostname_label,
                '--source-boot-volume-id', backup_boot_volume_id,
                '--wait-for-state', 'RUNNING',
                '--wait-interval-seconds', util.WAIT_INTERVAL_SECONDS
            ])
            util.validate_response(result, json_response_expected=False)
            instance_data = util.get_json_from_mixed_string(result.output)['data']
            instance_ocid = instance_data['id']
            assert 'bootVolume' == instance_data['source-details']['source-type']
            assert backup_boot_volume_id == instance_data['source-details']['boot-volume-id']

            clean_up_instances(instance_ocid)
            backup_boot_volume_id = None
            instance_ocid = None

        finally:
            clean_up_instances(instance_ocid)
            clean_up_boot_volume(boot_volume_id)
            clean_up_boot_volume(cloned_boot_volume_id)
            clean_up_boot_volume(backup_boot_volume_id)
            clean_up_boot_volume_backup(backup_id)
Ejemplo n.º 8
0
    def subtest_subnet_secondary_ip_operations(self):
        self.set_up_vcn_and_subnet("10.0.0.0/16")
        available_ip_addresses = self.get_ip_addresses_from_cidr("10.0.0.0/16")

        # First we need to launch two instances and get their VNICs. We get two instances
        # so that we can move the secondary private IP around. The instances need to be
        # in the same subnet for the secondary private IP address moves to be valid
        image_id = util.oracle_linux_image()
        shape = 'VM.Standard1.1'

        first_instance_name = util.random_name('cli_test_instance')
        result = self.invoke([
            'compute', 'instance', 'launch', '--compartment-id',
            util.COMPARTMENT_ID, '--availability-domain',
            util.availability_domain(), '--display-name', first_instance_name,
            '--subnet-id', self.subnet_ocid, '--image-id', image_id, '--shape',
            shape
        ])
        self.first_instance_id = util.find_id_in_response(result.output)

        second_instance_name = util.random_name('cli_test_instance')
        result = self.invoke([
            'compute', 'instance', 'launch', '--compartment-id',
            util.COMPARTMENT_ID, '--availability-domain',
            util.availability_domain(), '--display-name', second_instance_name,
            '--subnet-id', self.subnet_ocid, '--image-id', image_id, '--shape',
            shape
        ])
        self.second_instance_id = util.find_id_in_response(result.output)

        util.wait_until([
            'compute', 'instance', 'get', '--instance-id',
            self.first_instance_id
        ],
                        'RUNNING',
                        max_wait_seconds=600)
        util.wait_until([
            'compute', 'instance', 'get', '--instance-id',
            self.second_instance_id
        ],
                        'RUNNING',
                        max_wait_seconds=600)

        vnics_on_instance_result = self.invoke([
            'compute', 'instance', 'list-vnics', '--instance-id',
            self.first_instance_id
        ])
        vnics = json.loads(vnics_on_instance_result.output)
        first_vnic_id = vnics['data'][0]['id']
        first_vnic_primary_private_ip = vnics['data'][0]['private-ip']

        # So we don't try and re-use the IP address unintentionally
        available_ip_addresses.remove(first_vnic_primary_private_ip)

        vnics_on_instance_result = self.invoke([
            'compute', 'instance', 'list-vnics', '--instance-id',
            self.second_instance_id
        ])
        vnics = json.loads(vnics_on_instance_result.output)
        second_vnic_id = vnics['data'][0]['id']
        second_vnic_primary_private_ip = vnics['data'][0]['private-ip']
        available_ip_addresses.remove(second_vnic_primary_private_ip)

        # Running the assign command against a non-existent VNIC fails
        fudged_vnic_id = self.fudge_ocid(first_vnic_id)
        result = self.invoke([
            'network', 'vnic', 'assign-private-ip', '--vnic-id', fudged_vnic_id
        ])
        self.assertNotEqual(0, result.exit_code)
        assert 'Either VNIC with ID {} does not exist or you are not authorized to access it.'.format(
            fudged_vnic_id) in result.output

        # Most basic call with VNIC only - in this case we assign the IP automatically
        result = self.invoke([
            'network', 'vnic', 'assign-private-ip', '--vnic-id', first_vnic_id
        ])
        first_secondary_private_ip_data = json.loads(result.output)['data']
        first_secondary_private_ip_id = first_secondary_private_ip_data['id']
        first_secondary_private_ip_address = first_secondary_private_ip_data[
            'ip-address']
        available_ip_addresses.remove(first_secondary_private_ip_address)

        # Assign a new secondary IP with all parameters given
        second_secondary_private_ip_address = available_ip_addresses.pop()
        result = self.invoke([
            'network',
            'vnic',
            'assign-private-ip',
            '--vnic-id',
            first_vnic_id,
            '--ip-address',
            second_secondary_private_ip_address,
            '--display-name',
            'My second secondary',
            '--hostname-label',
            'secondary-1',

            # The --unassign-if-already-assigned should not have an impact as the IP address doesn't exist
            '--unassign-if-already-assigned'
        ])
        second_secondary_private_ip_data = json.loads(result.output)['data']
        second_secondary_private_ip_id = second_secondary_private_ip_data['id']
        self.assertEqual(second_secondary_private_ip_address,
                         second_secondary_private_ip_data['ip-address'])

        # Checkpoint by listing the private IPs. Our created secondaries should be there
        result = self.invoke(
            ['network', 'private-ip', 'list', '--vnic-id', first_vnic_id])
        private_ips = json.loads(result.output)['data']

        self.assertEqual(3, len(private_ips))
        self.find_private_ip_and_do_assertions(
            private_ips, first_secondary_private_ip_id,
            first_secondary_private_ip_address, None, None)
        self.find_private_ip_and_do_assertions(
            private_ips, second_secondary_private_ip_id,
            second_secondary_private_ip_address, 'My second secondary',
            'secondary-1')

        # Trying to assign the same private IP to the same VNIC is a no-op
        result = self.invoke([
            'network', 'vnic', 'assign-private-ip', '--vnic-id', first_vnic_id,
            '--ip-address', first_secondary_private_ip_address
        ])
        assert 'Taking no action as IP address {} is already assigned to VNIC {}'.format(
            first_secondary_private_ip_address, first_vnic_id) in result.output

        # Trying to move a primary IP fails
        result = self.invoke([
            'network', 'vnic', 'assign-private-ip', '--vnic-id', first_vnic_id,
            '--ip-address', second_vnic_primary_private_ip,
            '--unassign-if-already-assigned'
        ])
        self.assertNotEqual(0, result.exit_code)

        result = self.invoke([
            'network', 'vnic', 'assign-private-ip', '--vnic-id',
            second_vnic_id, '--ip-address', first_vnic_primary_private_ip,
            '--unassign-if-already-assigned'
        ])
        self.assertNotEqual(0, result.exit_code)

        # Trying to move an existing IP address without saying "unassign" fails
        result = self.invoke([
            'network', 'vnic', 'assign-private-ip', '--vnic-id',
            second_vnic_id, '--ip-address', first_secondary_private_ip_address
        ])
        target_message = 'IP address {} is already assigned to a different VNIC: {}. To reassign it, re-run this command with the --unassign-if-already-assigned option'.format(
            first_secondary_private_ip_address, first_vnic_id)
        assert target_message in result.output
        self.assertNotEqual(0, result.exit_code)

        # Move the secondary IP and also update some information
        result = self.invoke([
            'network', 'vnic', 'assign-private-ip', '--vnic-id',
            second_vnic_id, '--ip-address', first_secondary_private_ip_address,
            '--display-name', 'My first secondary', '--hostname-label',
            'moved-first-secondary-1', '--unassign-if-already-assigned'
        ])
        private_ip_data_after_move = json.loads(result.output)['data']
        self.assertEqual(first_secondary_private_ip_id,
                         private_ip_data_after_move['id'])
        self.assertEqual(first_secondary_private_ip_address,
                         private_ip_data_after_move['ip-address'])
        self.assertEqual('My first secondary',
                         private_ip_data_after_move['display-name'])
        self.assertEqual('moved-first-secondary-1',
                         private_ip_data_after_move['hostname-label'])

        # List each VNIC - we expect 2 results per list call (1 x primary private and 1 x secondary private per VNIC) after moving stuff around
        result = self.invoke(
            ['network', 'private-ip', 'list', '--vnic-id', first_vnic_id])
        private_ips = json.loads(result.output)['data']
        self.assertEqual(2, len(private_ips))
        self.ensure_private_ip_record_not_present(
            private_ips, first_secondary_private_ip_id)
        self.find_private_ip_and_do_assertions(
            private_ips, second_secondary_private_ip_id,
            second_secondary_private_ip_address, 'My second secondary',
            'secondary-1')

        result = self.invoke(
            ['network', 'private-ip', 'list', '--vnic-id', second_vnic_id])
        private_ips = json.loads(result.output)['data']
        self.assertEqual(2, len(private_ips))
        self.ensure_private_ip_record_not_present(
            private_ips, second_secondary_private_ip_id)
        self.find_private_ip_and_do_assertions(
            private_ips, first_secondary_private_ip_id,
            first_secondary_private_ip_address, 'My first secondary',
            'moved-first-secondary-1')

        # Listing by subnet should give us 4 records (2 x primary private and 2 x secondary private) as it queries across all VNICs in the subnet
        result = self.invoke(
            ['network', 'private-ip', 'list', '--subnet-id', self.subnet_ocid])
        private_ips = json.loads(result.output)['data']
        self.assertEqual(4, len(private_ips))
        self.find_private_ip_and_do_assertions(
            private_ips, first_secondary_private_ip_id,
            first_secondary_private_ip_address, 'My first secondary',
            'moved-first-secondary-1')
        self.find_private_ip_and_do_assertions(
            private_ips, second_secondary_private_ip_id,
            second_secondary_private_ip_address, 'My second secondary',
            'secondary-1')

        # Update the display name and hostname
        result = self.invoke([
            'network', 'private-ip', 'update', '--private-ip-id',
            second_secondary_private_ip_id, '--display-name',
            'batman display name', '--hostname-label', 'batman-secondary-1'
        ])
        updated_private_ip_info = json.loads(result.output)['data']
        self.assertEqual(second_secondary_private_ip_id,
                         updated_private_ip_info['id'])
        self.assertEqual(second_secondary_private_ip_address,
                         updated_private_ip_info['ip-address'])
        self.assertEqual(first_vnic_id, updated_private_ip_info['vnic-id'])
        self.assertEqual('batman display name',
                         updated_private_ip_info['display-name'])
        self.assertEqual('batman-secondary-1',
                         updated_private_ip_info['hostname-label'])

        # Do a get and confirm the information which we receive
        result = self.invoke([
            'network', 'private-ip', 'get', '--private-ip-id',
            second_secondary_private_ip_id
        ])
        private_ip_info_from_get = json.loads(result.output)['data']
        self.assertEqual(second_secondary_private_ip_id,
                         private_ip_info_from_get['id'])
        self.assertEqual(second_secondary_private_ip_address,
                         private_ip_info_from_get['ip-address'])
        self.assertEqual(first_vnic_id, private_ip_info_from_get['vnic-id'])
        self.assertEqual('batman display name',
                         private_ip_info_from_get['display-name'])
        self.assertEqual('batman-secondary-1',
                         private_ip_info_from_get['hostname-label'])

        # Running the unassign command against a non-existent VNIC fails
        # Listing by VNIC should give us one record (the primary private IP) per call
        result = self.invoke([
            'network', 'vnic', 'unassign-private-ip', '--vnic-id',
            fudged_vnic_id, '--ip-address', second_secondary_private_ip_address
        ])
        self.assertNotEqual(0, result.exit_code)
        # The error message from the service is not being sent correctly to the CLI. The Error code is correct.
        # This needs to be investigated
        # assert 'Either VNIC with ID {} does not exist or you are not authorized to access it.'.format(fudged_vnic_id) in result.output

        # Unassigning an IP address not in the VNIC fails
        result = self.invoke([
            'network', 'vnic', 'unassign-private-ip', '--vnic-id',
            second_vnic_id, '--ip-address', second_secondary_private_ip_address
        ])
        assert 'IP address {} was not found on VNIC {}'.format(
            second_secondary_private_ip_address,
            second_vnic_id) in result.output
        self.assertNotEqual(0, result.exit_code)

        # Unassigning a primary private IP address is not supported
        result = self.invoke([
            'network', 'vnic', 'unassign-private-ip', '--vnic-id',
            second_vnic_id, '--ip-address', second_vnic_primary_private_ip
        ])
        assert 'Taking no action as {} is the primary private IP on VNIC {}'.format(
            second_vnic_primary_private_ip, second_vnic_id) in result.output
        self.assertNotEqual(0, result.exit_code)

        # Unassign a secondary private IP
        result = self.invoke([
            'network', 'vnic', 'unassign-private-ip', '--vnic-id',
            second_vnic_id, '--ip-address', first_secondary_private_ip_address
        ])
        assert 'Unassigned IP address {} from VNIC {}'.format(
            first_secondary_private_ip_address,
            second_vnic_id) in result.output

        # Delete a secondary private IP (by its OCID)
        result = self.invoke([
            'network', 'private-ip', 'delete', '--private-ip-id',
            second_secondary_private_ip_id, '--force'
        ])
        self.assertEqual(0, result.exit_code)

        # Listing by VNIC should give us one record (the primary private IP) per call
        result = self.invoke(
            ['network', 'private-ip', 'list', '--vnic-id', first_vnic_id])
        private_ips = json.loads(result.output)['data']
        self.assertEqual(1, len(private_ips))
        self.assertTrue(private_ips[0]['is-primary'])

        result = self.invoke(
            ['network', 'private-ip', 'list', '--vnic-id', second_vnic_id])
        private_ips = json.loads(result.output)['data']
        self.assertEqual(1, len(private_ips))
        self.assertTrue(private_ips[0]['is-primary'])

        # Listing by subnet should give us two records (the primary private IP for each VNIC)
        result = self.invoke(
            ['network', 'private-ip', 'list', '--subnet-id', self.subnet_ocid])
        private_ips = json.loads(result.output)['data']
        self.assertEqual(2, len(private_ips))
        self.assertTrue(private_ips[0]['is-primary'])
        self.assertTrue(private_ips[1]['is-primary'])
Ejemplo n.º 9
0
    def subtest_launch_instance_ipxe_script_file_and_extended_metadata(self):
        instance_name = util.random_name('cli_test_instance_options')
        image_id = util.oracle_linux_image()
        shape = 'VM.Standard1.2'
        hostname_label = util.random_name('bminstance',
                                          insert_underscore=False)
        vnic_display_name = 'vnic_display_name'
        private_ip = '10.0.0.15'
        assign_public_ip = 'true'

        extended_metadata = '{"a": "1", "b": {"c": "3", "d": {}}}'

        launch_instance_result = util.invoke_command([
            'compute', 'instance', 'launch', '--compartment-id',
            util.COMPARTMENT_ID, '--availability-domain',
            util.availability_domain(), '--display-name', instance_name,
            '--subnet-id', self.subnet_ocid, '--image-id', image_id, '--shape',
            shape, '--ipxe-script-file', IPXE_SCRIPT_FILE, '--hostname-label',
            hostname_label + "1", '--private-ip', private_ip,
            '--assign-public-ip', assign_public_ip, '--vnic-display-name',
            vnic_display_name, '--extended-metadata', extended_metadata
        ])

        temp_instance_ocid = util.find_id_in_response(
            launch_instance_result.output)
        self.instance_ocids.append(temp_instance_ocid)
        util.validate_response(launch_instance_result, expect_etag=True)

        extended_metadata_result = json.loads(
            launch_instance_result.output)['data']['extended-metadata']
        assert extended_metadata_result['a'] == '1'
        assert extended_metadata_result['b']['c'] == '3'

        # This can be in ATTACHING state for some time
        try:
            util.wait_until([
                'compute', 'vnic-attachment', 'list', '--compartment-id',
                util.COMPARTMENT_ID, '--instance-id', temp_instance_ocid
            ],
                            'ATTACHED',
                            max_wait_seconds=60,
                            item_index_in_list_response=0)
        except Exception:
            try:
                # If it is ATTACHING we will consider it good enough
                util.wait_until([
                    'compute', 'vnic-attachment', 'list', '--compartment-id',
                    util.COMPARTMENT_ID, '--instance-id', temp_instance_ocid
                ],
                                'ATTACHING',
                                max_wait_seconds=30,
                                item_index_in_list_response=0)
            except Exception:
                # If it is not ATTACHING, double check that it didn't go to ATTACHED
                util.wait_until([
                    'compute', 'vnic-attachment', 'list', '--compartment-id',
                    util.COMPARTMENT_ID, '--instance-id', temp_instance_ocid
                ],
                                'ATTACHED',
                                max_wait_seconds=30,
                                item_index_in_list_response=0)

        # get vnic attachments for given instance
        list_vnics_result = util.invoke_command([
            'compute', 'vnic-attachment', 'list', '--compartment-id',
            util.COMPARTMENT_ID, '--instance-id', temp_instance_ocid
        ])

        vnic_id = json.loads(list_vnics_result.output)['data'][0]['vnic-id']

        # get full data for vnic attached to new instance (which includes hostname-label)
        get_vnic_result = util.invoke_command(
            ['network', 'vnic', 'get', '--vnic-id', vnic_id])

        vnic = json.loads(get_vnic_result.output)['data']

        assert vnic['hostname-label'] == hostname_label + "1"
        assert vnic['display-name'] == vnic_display_name
        assert vnic['public-ip']

        content = None
        with open(IPXE_SCRIPT_FILE, mode='r') as file:
            content = file.read()

        assert 'ipxe-script' in launch_instance_result.output
        # Just look at the first few characters. Once we hit a line break the formatting will differ.
        assert content[:5] in launch_instance_result.output

        self.delete_instance(temp_instance_ocid)
Ejemplo n.º 10
0
    def set_up_resources(self):
        # Grab the Object Storage namespace
        result = self.invoke(['os', 'ns', 'get'])
        self.object_storage_namespace = json.loads(result.output)['data']

        # Create a bucket
        print("Creating bucket")
        self.bucket_name = util.random_name('CliImageImportExport')
        result = self.invoke(
            ['os', 'bucket', 'create',
                '--compartment-id', util.COMPARTMENT_ID,
                '--namespace', self.object_storage_namespace,
                '--name', self.bucket_name])
        util.validate_response(result, expect_etag=True)

        # Create a VCN
        print("Creating VCN")
        vcn_name = util.random_name('cli_test_compute_vcn')
        result = self.invoke(
            ['network', 'vcn', 'create',
             '--compartment-id', util.COMPARTMENT_ID,
             '--display-name', vcn_name,
             '--dns-label', 'clivcn',
             '--cidr-block', '10.0.0.0/16'])
        util.validate_response(result, expect_etag=True)
        self.vcn_ocid = util.find_id_in_response(result.output)
        util.wait_until(['network', 'vcn', 'get', '--vcn-id', self.vcn_ocid], 'AVAILABLE', max_wait_seconds=300)

        # Create a subnet
        print("Creating subnet")
        subnet_name = util.random_name('cli_test_compute_subnet')
        result = self.invoke(
            ['network', 'subnet', 'create',
             '--compartment-id', util.COMPARTMENT_ID,
             '--availability-domain', util.availability_domain(),
             '--display-name', subnet_name,
             '--dns-label', 'clisubnet',
             '--vcn-id', self.vcn_ocid,
             '--cidr-block', '10.0.0.0/16',
             ])
        util.validate_response(result, expect_etag=True)
        self.subnet_ocid = util.find_id_in_response(result.output)
        util.wait_until(['network', 'subnet', 'get', '--subnet-id', self.subnet_ocid], 'AVAILABLE', max_wait_seconds=300)

        # Create an instance
        image_id = util.oracle_linux_image()
        shape = 'VM.Standard1.1'
        instance_name = util.random_name('cli_test_instance')
        print("Creating instance " + instance_name)
        result = self.invoke(
            ['compute', 'instance', 'launch',
             '--compartment-id', util.COMPARTMENT_ID,
             '--availability-domain', util.availability_domain(),
             '--display-name', instance_name,
             '--subnet-id', self.subnet_ocid,
             '--image-id', image_id,
             '--shape', shape])
        util.validate_response(result, expect_etag=True)
        self.instance_id = util.find_id_in_response(result.output)
        util.wait_until(['compute', 'instance', 'get', '--instance-id', self.instance_id], 'RUNNING', max_wait_seconds=600)

        # Export an image from the instance to use in tests
        print("Exporting image")
        result = self.invoke(
            ['compute', 'image', 'create',
             '--compartment-id', util.COMPARTMENT_ID,
             '--instance-id', self.instance_id])
        util.validate_response(result, expect_etag=True)
        self.custom_image_id = util.find_id_in_response(result.output)
        util.wait_until(['compute', 'image', 'get', '--image-id', self.custom_image_id], 'AVAILABLE', max_wait_seconds=3600)