Example #1
0
    def create_vcn(self, vcn_cidr, name=None, add_inet_gw=False):
        if not vcn_cidr:
            raise OciShellError("Failed to create VCN, no cidr provided")

        if not name:
            name = self._resource_config.reservation_id
        vcn = self.get_vcn(name)

        if not vcn:
            new_vcn = self.network_client_ops.create_vcn_and_wait_for_state(
                oci.core.models.CreateVcnDetails(
                    cidr_block=vcn_cidr,
                    display_name=name,
                    freeform_tags=self._resource_config.tags,
                    compartment_id=self._resource_config.compartment_ocid,
                ),
                [oci.core.models.Vcn.LIFECYCLE_STATE_AVAILABLE],
                operation_kwargs={"retry_strategy": RETRY_STRATEGY},
            )
            vcn = new_vcn.data

            if add_inet_gw:
                self.create_inet_gw(vcn.id)
        self.configure_default_security_rule(vcn)

        return vcn
def call_oci_command_with_waiter(
    network_client,
    cmd_to_call,
    cmd_to_check_status,
    ocid_to_check=None,
    state_to_check="lifecycle_state",
    wait_for_states=None,
    cmd_kwargs=None,
    waiter_kwargs=None,
):
    if not wait_for_states:
        wait_for_states = []
    if not cmd_kwargs:
        cmd_kwargs = {}
    if not waiter_kwargs:
        waiter_kwargs = {}

    if ocid_to_check:
        wait_for_resource_id = ocid_to_check
        current_object = cmd_to_check_status(wait_for_resource_id)
        if current_object.data and hasattr(current_object.data,
                                           state_to_check):
            current_state = getattr(current_object.data, state_to_check)
            if current_state in wait_for_states:
                return current_object.data

    operation_result = cmd_to_call(**cmd_kwargs)

    if not wait_for_states:
        return operation_result
    if operation_result.data:
        wait_for_resource_id = operation_result.data.id
    if not wait_for_resource_id:
        raise OciShellError("Unable to check for state: OCID not found")

    lowered_wait_for_states = [w.lower() for w in wait_for_states]
    evaluate_lambda = (
        lambda r: getattr(r.data, state_to_check) and getattr(
            r.data, state_to_check).lower()  # noqa #W503
        in lowered_wait_for_states  # noqa #W503
    )
    try:
        waiter_result = oci.wait_until(
            network_client,
            cmd_to_check_status(wait_for_resource_id),
            evaluate_response=evaluate_lambda,
            **waiter_kwargs)
        result_to_return = waiter_result

        return result_to_return
    except Exception as e:
        raise oci.exceptions.CompositeOperationError(
            partial_results=[operation_result], cause=e)
Example #3
0
    def set_as_routing_gw(self, instance_id=None):
        if not instance_id:
            instance_id = self.resource_config.remote_instance_id
            if not instance_id:
                raise OciShellError("Failed to retrieve instance ocid")
        vnic_attachments = self.compute_ops.get_vnic_attachments(instance_id)
        if len(vnic_attachments) < 2:
            raise OciShellError("Unable to setas routing gateway: Only 1 vnic attached")

        routes_to_create = {}
        for vnic_attachment in vnic_attachments:
            vnic = self.network_ops.network_client.get_vnic(vnic_attachment.vnic_id)
            subnet = self.network_ops.get_subnet(vnic.data.subnet_id)

            ip_id = self.network_ops.get_private_ip_object(
                subnet.id, vnic.data.private_ip
            )
            route_rule = oci.core.models.RouteRule(
                destination_type="CIDR_BLOCK", network_entity_id=ip_id.id
            )

            if not vnic.data.skip_source_dest_check:
                self.network_ops.network_client_ops.update_vnic_and_wait_for_state(
                    vnic.data.id,
                    oci.core.models.UpdateVnicDetails(skip_source_dest_check=True),
                    wait_for_states=[oci.core.models.Vnic.LIFECYCLE_STATE_AVAILABLE],
                )
            routes_to_create[subnet] = route_rule

        for subnet in routes_to_create:
            rule = routes_to_create.get(subnet)
            route_table = subnet.route_table_id
            for dst_subnet in routes_to_create:
                if subnet == dst_subnet:
                    continue
                rule.destination = dst_subnet.cidr_block
                self.network_ops.update_route_table(
                    route_table_id=route_table, route_rule=rule
                )
Example #4
0
    def parse_request(self):
        subnet_dict = {}
        main_vcn = None
        does_vcn_act_as_subnet = False
        for action in self._actions:
            if action["type"] == "prepareCloudInfra":
                main_vcn = VcnRequest(action, True)
                self._vcn_list.append(main_vcn)
            elif action["type"] == "prepareSubnet":
                subnet = SubnetRequest(action)
                subnet_dict[subnet.subnet_action_id] = subnet
            elif action["type"] == "createKeys":
                self._keys_action_id = action.get("actionId")

        for subnet_id in subnet_dict:
            subnet = subnet_dict.get(subnet_id)
            if subnet.attributes.is_vcn:
                if not does_vcn_act_as_subnet:
                    does_vcn_act_as_subnet = True
                vcn = VcnRequest()
                vcn.vcn_cidr = subnet.cidr
                vcn.vcn_action_id = subnet.subnet_action_id
                vcn.subnet_list.append(subnet)
                self._vcn_list.append(vcn)
                cidr = subnet.cidr
                vcn_alias_match = re.search(r"(?P<name>^.*)\s+-\s+\d+\.",
                                            subnet.alias)
                if vcn_alias_match:
                    net = ipaddress.ip_network(cidr)
                    vcn_name = "{} - {}-{}".format(
                        vcn_alias_match.groupdict().get("name", "VCN"),
                        net.network_address,
                        net.num_addresses,
                    )
                else:
                    vcn_name = "VCN-{}".format(cidr.replace("/", "-"))
                if (subnet.alias != vcn_name
                        and subnet.attributes.request_cidr  # noqa #W503
                        and self._check_cidr_in_subnet_name(
                            subnet)  # noqa #W503
                    ):
                    self._vcn_names_dict[vcn_name] = subnet.alias
                    subnet.alias = vcn_name
            elif main_vcn:
                main_vcn.subnet_list.append(subnet)
        if does_vcn_act_as_subnet and any(
                x for x in subnet_dict.values() if not x.attributes.is_vcn):
            raise OciShellError(
                "Mixed connectivity mode is unsupported: "
                "please use only Subnet Services or only VCN Services")
Example #5
0
 def check_security_list_attached(self,
                                  subnet,
                                  security_list_id,
                                  max_retries=5,
                                  timeout=5):
     # ToDo replace this ugly one with proper solution
     current_subnet = self.get_subnet(subnet_id=subnet.id)
     i = 0
     while (security_list_id not in current_subnet.security_list_ids
            and i < max_retries):
         self.update_subnet_security_lists(current_subnet, security_list_id)
         time.sleep(timeout)
         current_subnet = self.get_subnet(subnet_id=subnet.id)
         i += 1
     else:
         if security_list_id not in current_subnet.security_list_ids:
             raise OciShellError(
                 "Unable to update subnet {} with {} security list".format(
                     current_subnet.display_name, security_list_id))
Example #6
0
 def add_inet_gw_route(self,
                       route_table_id,
                       inet_gw_id=None,
                       vcn_id=None,
                       cidr=DEFAULT_CIDR):
     if not inet_gw_id and vcn_id:
         inet_gw = next((x for x in self.get_inet_gateways(vcn_id)), None)
         if inet_gw:
             inet_gw_id = inet_gw.id
     if not inet_gw_id:
         raise OciShellError("Failed to identify VCN internet gateway")
     default_static_rule = oci.core.models.RouteRule(
         destination=cidr,
         destination_type="CIDR_BLOCK",
         network_entity_id=inet_gw_id,
     )
     self.update_route_table(route_table_id,
                             default_static_rule,
                             tag={"Target": "Internet"})
Example #7
0
 def _attach_secondary_vnic(
     self,
     name,
     subnet_id,
     instance_id,
     is_public,
     private_ip,
     src_dst_check,
     retries=3,
     timeout=5,
 ):
     attachments = self.get_vnic_attachments(instance_id)
     attached_vnic = next(
         (
             x
             for x in attachments  # noqa #W503
             if x.oci_vnic_attachment.display_name == name  # noqa #W503
             and x.oci_vnic_attachment.subnet_id == subnet_id  # noqa #W503
         ),
         None,
     )
     if attached_vnic:
         return attached_vnic
     secondary_vnic_details = oci.core.models.CreateVnicDetails(
         assign_public_ip=is_public,
         display_name=name,
         skip_source_dest_check=src_dst_check,
         subnet_id=subnet_id,
     )
     if private_ip:
         if private_ip.name:
             secondary_vnic_details.display_name = private_ip.name
         if private_ip.ip:
             secondary_vnic_details.private_ip = private_ip.ip
     secondary_vnic_attach_details = oci.core.models.AttachVnicDetails(
         create_vnic_details=secondary_vnic_details,
         display_name=name,
         instance_id=instance_id,
     )
     result = None
     try:
         result = self.compute_ops.compute_client_ops.attach_vnic_and_wait_for_state(
             secondary_vnic_attach_details,
             [oci.core.models.VnicAttachment.LIFECYCLE_STATE_ATTACHED],
         )
     except CompositeOperationError as e:
         for partial_result in e.partial_results:
             if partial_result and partial_result.data:
                 if (
                     partial_result.data.lifecycle
                     == oci.core.models.VnicAttachment.LIFECYCLE_STATE_ATTACHED  # noqa #W503
                 ):
                     result = partial_result
                     break
                 if (
                     partial_result.data.lifecycle
                     == oci.core.models.VnicAttachment.LIFECYCLE_STATE_ATTACHING  # noqa #W503
                 ):
                     vnic = self.compute_ops.compute_client.get_vnic_attachment(
                         partial_result.data.id
                     )
                     i = 0
                     while (
                         vnic.data.lifecycle
                         != oci.core.models.VnicAttachment.LIFECYCLE_STATE_ATTACHED  # noqa #W503
                         and i < retries  # noqa #W503
                     ):
                         time.sleep(timeout)
                         vnic = self.compute_ops.compute_client.get_vnic_attachment(
                             partial_result.data.id
                         )
                         i += 1
                     result = vnic
                     if (
                         vnic.data.lifecycle
                         != oci.core.models.VnicAttachment.LIFECYCLE_STATE_ATTACHED  # noqa #W503
                     ):
                         raise OciShellError(
                             "Failed to attach vnic {} to instance {}".format(
                                 name, instance_id
                             )
                         )
     if result:
         vnic = VNIC(oci_ops=self, logger=self._logger, vnic_attachment=result.data)
         attachments = self.get_vnic_attachments(instance_id)
         if any(
             vnic
             for vnic in attachments
             if vnic.oci_vnic_attachment.id == vnic.oci_vnic_attachment.id
         ):
             return vnic.oci_vnic
Example #8
0
    def remove_vcn(self, subnet_retires=6):
        vcns = self.network_ops.get_vcn_by_tag(self.resource_config.reservation_id)
        error_list = []
        for vcn in vcns:
            subnets = self.network_ops.get_subnets(vcn_id=vcn.id) or []
            service_gateways = (
                self.network_ops.get_service_gateways(vcn_id=vcn.id) or []
            )
            internet_gateways = self.network_ops.get_inet_gateways(vcn_id=vcn.id) or []
            lpgs = self.network_ops.get_local_peering_gws(vcn_id=vcn.id)
            for subnet in subnets:
                i = 0
                while i < subnet_retires:
                    try:
                        self.network_ops.remove_subnet(subnet)
                        break
                    except ServiceError as e:
                        self._logger.exception(
                            "Unable to remove subnet {}".format(subnet.display_name)
                        )
                        vnic_id_match = self.VNIC_PATTERN.search(e.message)
                        if vnic_id_match:
                            vnic_id = vnic_id_match.group().rstrip(".,")
                            self.compute_ops.remove_vnic(vnic_id)
                    except Exception:
                        self._logger.exception(
                            "Unable to remove subnet {}".format(subnet.display_name)
                        )
                        error_list.append(subnet.display_name)
                        break
                else:
                    error_list.append(subnet.display_name)
            for route_table in self.network_ops.get_routing_tables(vcn.id):
                if route_table.id != vcn.default_route_table_id:
                    self.network_ops.network_client_ops.delete_route_table_and_wait_for_state(  # noqa #501
                        route_table.id,
                        [oci.core.models.RouteTable.LIFECYCLE_STATE_TERMINATED],
                    )
            for local_peering_gw in lpgs:
                self.network_ops.network_client_ops.delete_local_peering_gateway_and_wait_for_state(  # noqa #501
                    local_peering_gw.id,
                    wait_for_states=[
                        oci.core.models.LocalPeeringGateway.LIFECYCLE_STATE_TERMINATED
                    ],
                )
            for service_gw in service_gateways:
                self.network_ops.network_client_ops.delete_service_gateway_and_wait_for_state(  # noqa #501
                    service_gw.id,
                    [oci.core.models.ServiceGateway.LIFECYCLE_STATE_TERMINATED],
                )
            security_lists = self.network_ops.network_client.list_security_lists(
                self.resource_config.compartment_ocid, vcn_id=vcn.id
            )
            for security_list in security_lists.data:
                if vcn.default_security_list_id == security_list.id:
                    continue
                self.network_ops.network_client_ops.delete_security_list_and_wait_for_state(  # noqa #501
                    security_list.id,
                    [oci.core.models.SecurityList.LIFECYCLE_STATE_TERMINATED],
                )
            for internet_gw in internet_gateways:
                self.network_ops.network_client_ops.delete_internet_gateway_and_wait_for_state(  # noqa #501
                    internet_gw.id,
                    wait_for_states=[
                        oci.core.models.InternetGateway.LIFECYCLE_STATE_TERMINATED
                    ],
                )
            try:
                self.network_ops.network_client_ops.delete_vcn_and_wait_for_state(
                    vcn.id, [oci.core.models.Vcn.LIFECYCLE_STATE_TERMINATED]
                )
            except ServiceError:
                self._logger.exception(
                    "Failed to delete VCN {}".format(vcn.display_name)
                )
                error_list.append(vcn.display_name)

            if error_list:
                self._logger.error(
                    "The following items were not removed {}".format(error_list)
                )
                raise OciShellError(
                    "Unable to cleanup sandbox. Please see logs for details."
                )