func()

in cni/network/network.go [725:868]


func (plugin *NetPlugin) createEpInfo(opt *createEpInfoOpt) (*network.EndpointInfo, error) { // you can modify to pass in whatever else you need
	// ensure we can find the master interface
	opt.ifInfo.HostSubnetPrefix.IP = opt.ifInfo.HostSubnetPrefix.IP.Mask(opt.ifInfo.HostSubnetPrefix.Mask)
	opt.ipamAddConfig.nwCfg.IPAM.Subnet = opt.ifInfo.HostSubnetPrefix.String()

	// populate endpoint info section
	masterIfName := plugin.findMasterInterface(opt)
	if masterIfName == "" {
		err := plugin.Errorf("Failed to find the master interface")
		return nil, err
	}

	networkPolicies := opt.policies // save network policies before we modify the slice pointer for ep policies

	// populate endpoint info
	epDNSInfo, err := getEndpointDNSSettings(opt.nwCfg, opt.ifInfo.DNS, opt.k8sNamespace) // Probably won't panic if given bad values
	if err != nil {
		err = plugin.Errorf("Failed to getEndpointDNSSettings: %v", err)
		return nil, err
	}

	vethName := fmt.Sprintf("%s.%s", opt.k8sNamespace, opt.k8sPodName)
	if opt.nwCfg.Mode != OpModeTransparent {
		// this mechanism of using only namespace and name is not unique for different incarnations of POD/container.
		// IT will result in unpredictable behavior if API server decides to
		// reorder DELETE and ADD call for new incarnation of same POD.
		vethName = fmt.Sprintf("%s%s%s", opt.networkID, opt.args.ContainerID, opt.args.IfName)
	}

	// for secondary (Populate addresses)
	// initially only for infra nic but now applied to all nic types
	addresses := make([]net.IPNet, len(opt.ifInfo.IPConfigs))
	for i, ipconfig := range opt.ifInfo.IPConfigs {
		addresses[i] = ipconfig.Address
	}

	// generate endpoint info
	var endpointID, ifName string

	if opt.ifInfo.NICType == cns.InfraNIC && !*opt.infraSeen {
		// so we do not break existing scenarios, only the first infra gets the original endpoint id generation
		ifName = opt.args.IfName
		endpointID = plugin.nm.GetEndpointID(opt.args.ContainerID, ifName)
		*opt.infraSeen = true
	} else {
		ifName = "eth" + strconv.Itoa(opt.endpointIndex)
		endpointID = plugin.nm.GetEndpointID(opt.args.ContainerID, ifName)
	}

	endpointInfo := network.EndpointInfo{
		NetworkID:                     opt.networkID,
		Mode:                          opt.ipamAddConfig.nwCfg.Mode,
		MasterIfName:                  masterIfName,
		AdapterName:                   opt.ipamAddConfig.nwCfg.AdapterName,
		BridgeName:                    opt.ipamAddConfig.nwCfg.Bridge,
		NetworkPolicies:               networkPolicies, // nw and ep policies separated to avoid possible conflicts
		NetNs:                         opt.ipamAddConfig.args.Netns,
		Options:                       opt.ipamAddConfig.shallowCopyIpamAddConfigOptions(),
		DisableHairpinOnHostInterface: opt.ipamAddConfig.nwCfg.DisableHairpinOnHostInterface,
		IsIPv6Enabled:                 opt.ipv6Enabled, // present infra only

		EndpointID:  endpointID,
		ContainerID: opt.args.ContainerID,
		NetNsPath:   opt.args.Netns, // probably same value as epInfo.NetNs
		IfName:      ifName,
		Data:        make(map[string]interface{}),
		EndpointDNS: epDNSInfo,
		// endpoint policies are populated later
		IPsToRouteViaHost:  opt.nwCfg.IPsToRouteViaHost,
		EnableSnatOnHost:   opt.nwCfg.EnableSnatOnHost,
		EnableMultiTenancy: opt.nwCfg.MultiTenancy,
		EnableInfraVnet:    opt.enableInfraVnet,
		EnableSnatForDns:   opt.enableSnatForDNS,
		PODName:            opt.k8sPodName,
		PODNameSpace:       opt.k8sNamespace,
		SkipHotAttachEp:    false, // Hot attach at the time of endpoint creation
		IPV6Mode:           opt.nwCfg.IPV6Mode,
		VnetCidrs:          opt.nwCfg.VnetCidrs,
		ServiceCidrs:       opt.nwCfg.ServiceCidrs,
		NATInfo:            opt.natInfo,
		NICType:            opt.ifInfo.NICType,
		SkipDefaultRoutes:  opt.ifInfo.SkipDefaultRoutes,
		Routes:             opt.ifInfo.Routes,
		// added the following for delegated vm nic
		IPAddresses: addresses,
		MacAddress:  opt.ifInfo.MacAddress,
		// the following is used for creating an external interface if we can't find an existing network
		HostSubnetPrefix: opt.ifInfo.HostSubnetPrefix.String(),
		PnPID:            opt.ifInfo.PnPID,
	}

	if err = addSubnetToEndpointInfo(*opt.ifInfo, &endpointInfo); err != nil {
		logger.Info("Failed to add subnets to endpointInfo", zap.Error(err))
		return nil, err
	}
	setNetworkOptions(opt.ifInfo.NCResponse, &endpointInfo)

	// update endpoint policies
	policyArgs := PolicyArgs{
		subnetInfos: endpointInfo.Subnets, // getEndpointPolicies requires nwInfo.Subnets only (checked)
		nwCfg:       opt.nwCfg,
		ipconfigs:   opt.ifInfo.IPConfigs,
	}
	endpointPolicies, err := getEndpointPolicies(policyArgs)
	if err != nil {
		logger.Error("Failed to get endpoint policies", zap.Error(err))
		return nil, err
	}
	// create endpoint policies by appending to network policies
	// the value passed into NetworkPolicies should be unaffected since we reassign here
	opt.policies = append(opt.policies, endpointPolicies...)

	// appends endpoint policies specific to this interface
	opt.policies = append(opt.policies, opt.ifInfo.EndpointPolicies...)

	endpointInfo.EndpointPolicies = opt.policies
	// add even more endpoint policies
	epPolicies, err := getPoliciesFromRuntimeCfg(opt.nwCfg, opt.ipamAddResult.ipv6Enabled) // not specific to delegated or infra
	if err != nil {
		logger.Error("failed to get policies from runtime configurations", zap.Error(err))
		return nil, plugin.Errorf(err.Error())
	}
	endpointInfo.EndpointPolicies = append(endpointInfo.EndpointPolicies, epPolicies...)

	if opt.ipamAddResult.ipv6Enabled { // not specific to this particular interface
		endpointInfo.IPV6Mode = string(util.IpamMode(opt.nwCfg.IPAM.Mode)) // TODO: check IPV6Mode field can be deprecated and can we add IsIPv6Enabled flag for generic working
	}

	if opt.azIpamResult != nil && opt.azIpamResult.IPs != nil {
		endpointInfo.InfraVnetIP = opt.azIpamResult.IPs[0].Address
	}

	if opt.nwCfg.MultiTenancy {
		// previously only infra nic was passed into this function but now all nics are passed in (possibly breaks swift v2)
		plugin.multitenancyClient.SetupRoutingForMultitenancy(opt.nwCfg, opt.cnsNetworkConfig, opt.azIpamResult, &endpointInfo, opt.ifInfo)
	}

	setEndpointOptions(opt.cnsNetworkConfig, &endpointInfo, vethName)

	logger.Info("Generated endpoint info from fields", zap.String("epInfo", endpointInfo.PrettyString()))

	// now our ep info should have the full combined information from both the network and endpoint structs
	return &endpointInfo, nil
}