func()

in plugins/vpc-eni/network/network_windows.go [154:243]


func (nb *NetBuilder) FindOrCreateEndpoint(nw *Network, ep *Endpoint) error {
	// Query the namespace identifier.
	nsType, namespaceIdentifier := nb.getNamespaceIdentifier(ep)

	// Check if the endpoint already exists.
	endpointName := nb.generateHNSEndpointName(nw.Name, namespaceIdentifier)
	hnsEndpoint, err := hcsshim.GetHNSEndpointByName(endpointName)
	if err == nil {
		log.Infof("Found existing HNS endpoint %s.", endpointName)
		if nsType == infraContainerNS || nsType == hcsNamespace {
			// This is a benign duplicate create call for an existing endpoint.
			// The endpoint was already attached in a previous call. Ignore and return success.
			log.Infof("HNS endpoint %s is already attached to container ID %s.",
				endpointName, ep.ContainerID)
		} else {
			// Attach the existing endpoint to the container's network namespace.
			// Attachment of endpoint to each container would occur only when using HNS V1 APIs.
			err = nb.attachEndpointV1(hnsEndpoint, ep.ContainerID)
		}

		ep.MACAddress, ep.IPAddresses, nw.GatewayIPAddresses =
			nb.parseEndpointFieldsFromResponse(hnsEndpoint)
		return err
	} else {
		if nsType != infraContainerNS && nsType != hcsNamespace {
			// The endpoint referenced in the container netns does not exist.
			log.Errorf("Failed to find endpoint %s for container %s.", endpointName, ep.ContainerID)
			return fmt.Errorf("failed to find endpoint %s: %v", endpointName, err)
		}
	}

	// Initialize the HNS endpoint.
	hnsEndpoint = &hcsshim.HNSEndpoint{
		Name:               endpointName,
		VirtualNetworkName: nw.Name,
		DNSSuffix:          strings.Join(nw.DNSSuffixSearchList, ","),
		DNSServerList:      strings.Join(nw.DNSServers, ","),
	}

	if ep.MACAddress != nil {
		hnsEndpoint.MacAddress = ep.MACAddress.String()
	}
	if len(ep.IPAddresses) != 0 {
		hnsEndpoint.IPAddress = ep.IPAddresses[0].IP
		pl, _ := ep.IPAddresses[0].Mask.Size()
		hnsEndpoint.PrefixLength = uint8(pl)
	}

	// Add ACL policies for blocking IMDS access through the endpoint.
	if ep.BlockIMDS {
		err = imds.BlockInstanceMetadataEndpoint(hnsEndpoint)
		if err != nil {
			log.Errorf("Failed to block instance metadata endpoint: %v.", err)
			return err
		}
	}

	// Create the HNS endpoint.
	log.Infof("Creating HNS endpoint: %+v", hnsEndpoint)
	hnsResponse, err := hnsEndpoint.Create()
	if err != nil {
		log.Errorf("Failed to create HNS endpoint: %v.", err)
		return err
	}

	log.Infof("Received HNS endpoint response: %+v.", hnsResponse)

	// Attach the HNS endpoint to the container's network namespace.
	if nsType == infraContainerNS {
		err = nb.attachEndpointV1(hnsResponse, ep.ContainerID)
	}
	if nsType == hcsNamespace {
		err = nb.attachEndpointV2(hnsResponse, namespaceIdentifier)
	}
	if err != nil {
		// Cleanup the failed endpoint.
		log.Infof("Deleting the failed HNS endpoint %s.", hnsResponse.Id)
		_, delErr := hnsResponse.Delete()
		if delErr != nil {
			log.Errorf("Failed to delete HNS endpoint: %v.", delErr)
		}

		return err
	}

	// Return network interface MAC address, IP Address and Gateway.
	ep.MACAddress, ep.IPAddresses, nw.GatewayIPAddresses =
		nb.parseEndpointFieldsFromResponse(hnsResponse)
	return nil
}