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)
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 )
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")
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))
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"})
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
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." )