diff --git a/cni/plugins/main/multi-nic/multi-nic.go b/cni/plugins/main/multi-nic/multi-nic.go index 8897b038..a36707e4 100644 --- a/cni/plugins/main/multi-nic/multi-nic.go +++ b/cni/plugins/main/multi-nic/multi-nic.go @@ -396,6 +396,10 @@ func loadConf(args *skel.CmdArgs) (*NetConf, string, error) { } selectResponse, err := selectNICs(n.DaemonIP, n.DaemonPort, podName, podNamespace, hostName, n.Name, nicSet, n.MasterNetAddrs) if err != nil { + if n.IPAM.Type == MultiConfigIPAMType { + // allow to have empty Masters + err = nil + } return n, deviceType, err } n.Masters = selectResponse.Masters diff --git a/daemon/example/crd/multinic.fms.io_cidrs.yaml b/daemon/example/crd/multinic.fms.io_cidrs.yaml new file mode 100644 index 00000000..11a3b8e1 --- /dev/null +++ b/daemon/example/crd/multinic.fms.io_cidrs.yaml @@ -0,0 +1,127 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: cidrs.multinic.fms.io +spec: + group: multinic.fms.io + names: + kind: CIDR + listKind: CIDRList + plural: cidrs + singular: cidr + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: CIDR is the Schema for the cidrs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CIDRSpec defines the desired state of CIDR + properties: + cidr: + items: + properties: + hosts: + items: + properties: + hostIP: + type: string + hostIndex: + type: integer + hostName: + type: string + interfaceName: + type: string + ippool: + type: string + podCIDR: + type: string + required: + - hostIP + - hostIndex + - hostName + - interfaceName + - podCIDR + type: object + type: array + interfaceIndex: + type: integer + netAddress: + type: string + vlanCIDR: + type: string + required: + - hosts + - interfaceIndex + - netAddress + - vlanCIDR + type: object + type: array + config: + description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + Important: Run "make" to regenerate code after modifying this file' + properties: + excludeCIDRs: + items: + type: string + type: array + hostBlock: + type: integer + interfaceBlock: + type: integer + masterNets: + items: + type: string + type: array + name: + type: string + subnet: + type: string + type: + type: string + vlanMode: + type: string + required: + - hostBlock + - interfaceBlock + - masterNets + - name + - subnet + - type + type: object + required: + - cidr + - config + type: object + status: + description: CIDRStatus defines the observed state of CIDR + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/daemon/example/crd/multinic.fms.io_configs.yaml b/daemon/example/crd/multinic.fms.io_configs.yaml new file mode 100644 index 00000000..07ebbea4 --- /dev/null +++ b/daemon/example/crd/multinic.fms.io_configs.yaml @@ -0,0 +1,496 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: configs.multinic.fms.io +spec: + group: multinic.fms.io + names: + kind: Config + listKind: ConfigList + plural: configs + singular: config + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Config is the Schema for the configs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConfigSpec defines the desired state of Config + properties: + addRoutePath: + type: string + cniType: + description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + Important: Run "make" to regenerate code after modifying this file' + type: string + contextTimeoutMinutes: + type: integer + daemon: + properties: + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + description: EnvFromSource represents the source of a set of + ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key + in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + imagePullSecretName: + type: string + mounts: + items: + properties: + hostpath: + type: string + name: + type: string + podpath: + type: string + required: + - hostpath + - name + - podpath + type: object + type: array + nodeSelector: + additionalProperties: + type: string + type: object + port: + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components that + enable the WindowsHostProcessContainers feature flag. + Setting this field without the feature flag will result + in errors when validating the Pod. All of a Pod's containers + must have the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - image + - port + type: object + deleteRoutePath: + type: string + getInterfacePath: + type: string + ipamType: + type: string + joinPath: + type: string + logLevel: + type: integer + longReconcileMinutes: + type: integer + normalReconcileMinutes: + type: integer + urgentReconcileSeconds: + type: integer + required: + - cniType + - daemon + - getInterfacePath + - ipamType + - joinPath + type: object + status: + description: ConfigStatus defines the observed state of Config + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/daemon/example/crd/net.cogadvisor.io_deviceclasses.yaml b/daemon/example/crd/multinic.fms.io_deviceclasses.yaml similarity index 100% rename from daemon/example/crd/net.cogadvisor.io_deviceclasses.yaml rename to daemon/example/crd/multinic.fms.io_deviceclasses.yaml diff --git a/daemon/example/crd/multinic.fms.io_hostinterfaces.yaml b/daemon/example/crd/multinic.fms.io_hostinterfaces.yaml new file mode 100644 index 00000000..0ea01fae --- /dev/null +++ b/daemon/example/crd/multinic.fms.io_hostinterfaces.yaml @@ -0,0 +1,123 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: hostinterfaces.multinic.fms.io +spec: + group: multinic.fms.io + names: + kind: HostInterface + listKind: HostInterfaceList + plural: hostinterfaces + singular: hostinterface + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: HostInterface is the Schema for the hostinterfaces API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: HostInterfaceSpec defines the desired state of HostInterface + properties: + hostName: + type: string + interfaces: + items: + properties: + hostIP: + type: string + interfaceName: + type: string + netAddress: + type: string + pciAddress: + type: string + product: + type: string + vendor: + type: string + required: + - hostIP + - interfaceName + - netAddress + - pciAddress + - product + - vendor + type: object + type: array + required: + - hostName + - interfaces + type: object + status: + description: HostInterfaceStatus defines the observed state of HostInterface + properties: + stat: + properties: + count: + type: integer + interfaceName: + type: string + lastRx: + type: integer + lastRxDrop: + type: integer + lastTimestamp: + format: int64 + type: integer + lastTx: + type: integer + lastTxDrop: + type: integer + rxDropRate: + type: integer + rxRate: + type: integer + txDropRate: + type: integer + txRate: + type: integer + required: + - count + - interfaceName + - lastRx + - lastRxDrop + - lastTimestamp + - lastTx + - lastTxDrop + - rxDropRate + - rxRate + - txDropRate + - txRate + type: object + required: + - stat + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/daemon/example/crd/net.cogadvisor.io_ippools.yaml b/daemon/example/crd/multinic.fms.io_ippools.yaml similarity index 100% rename from daemon/example/crd/net.cogadvisor.io_ippools.yaml rename to daemon/example/crd/multinic.fms.io_ippools.yaml diff --git a/daemon/example/crd/net.cogadvisor.io_multinicnetworks.yaml b/daemon/example/crd/multinic.fms.io_multinicnetworks.yaml similarity index 78% rename from daemon/example/crd/net.cogadvisor.io_multinicnetworks.yaml rename to daemon/example/crd/multinic.fms.io_multinicnetworks.yaml index cf00b57b..7c2cec40 100644 --- a/daemon/example/crd/net.cogadvisor.io_multinicnetworks.yaml +++ b/daemon/example/crd/multinic.fms.io_multinicnetworks.yaml @@ -14,7 +14,7 @@ spec: listKind: MultiNicNetworkList plural: multinicnetworks singular: multinicnetwork - scope: Namespaced + scope: Cluster versions: - name: v1 schema: @@ -60,6 +60,10 @@ spec: type: array multiNICIPAM: type: boolean + namespaces: + items: + type: string + type: array plugin: description: 'reference: github.com/containernetworking/cni/pkg/types' properties: @@ -106,14 +110,47 @@ spec: status: description: MultiNicNetworkStatus defines the observed state of MultiNicNetwork properties: - defs: - description: Definitions lists NetworkAttachmentDefinition created - by the MultiNicNetwork + computeResults: items: - type: string + properties: + netAddress: + type: string + numOfHosts: + type: integer + required: + - netAddress + - numOfHosts + type: object type: array + configStatus: + type: string + discovery: + properties: + cidrProcessed: + type: integer + existDaemon: + type: integer + infoAvailable: + type: integer + required: + - cidrProcessed + - existDaemon + - infoAvailable + type: object + lastSyncTime: + format: date-time + type: string + message: + type: string + routeStatus: + type: string required: - - defs + - computeResults + - configStatus + - discovery + - lastSyncTime + - message + - routeStatus type: object type: object served: true diff --git a/daemon/example/resource/example-multinicnet-devclass.yaml b/daemon/example/resource/example-multinicnet-devclass.yaml index c44656f9..49886a32 100644 --- a/daemon/example/resource/example-multinicnet-devclass.yaml +++ b/daemon/example/resource/example-multinicnet-devclass.yaml @@ -2,7 +2,6 @@ apiVersion: multinic.fms.io/v1 kind: MultiNicNetwork metadata: name: multi-nic-dev - namespace: default spec: subnet: "192.168.0.0/16" ipam: | diff --git a/daemon/example/resource/example-multinicnet-topology.yaml b/daemon/example/resource/example-multinicnet-topology.yaml index 4e06e4c7..e096034c 100644 --- a/daemon/example/resource/example-multinicnet-topology.yaml +++ b/daemon/example/resource/example-multinicnet-topology.yaml @@ -2,7 +2,6 @@ apiVersion: multinic.fms.io/v1 kind: MultiNicNetwork metadata: name: multi-nic-topology - namespace: default spec: subnet: "192.168.0.0/16" ipam: | diff --git a/daemon/example/resource/example-multinicnet.yaml b/daemon/example/resource/example-multinicnet.yaml index 582f5c3f..916c0cde 100644 --- a/daemon/example/resource/example-multinicnet.yaml +++ b/daemon/example/resource/example-multinicnet.yaml @@ -2,7 +2,6 @@ apiVersion: multinic.fms.io/v1 kind: MultiNicNetwork metadata: name: multi-nic-sample - namespace: default spec: subnet: "192.168.0.0/16" ipam: | diff --git a/daemon/src/selector/none.go b/daemon/src/selector/none.go index e86ff8ae..b78ad15c 100644 --- a/daemon/src/selector/none.go +++ b/daemon/src/selector/none.go @@ -54,6 +54,10 @@ func (DefaultSelector) Select(req NICSelectRequest, interfaceNameMap map[string] for _, devName := range fixedSet { if netAddress, exists := nameNetMap[devName]; exists { selectedMaster = append(selectedMaster, netAddress) + } else { + // replaced with empty network address + interfaceNameMap[devName] = devName + selectedMaster = append(selectedMaster, devName) } } } else { @@ -65,7 +69,11 @@ func (DefaultSelector) Select(req NICSelectRequest, interfaceNameMap map[string] } if len(selectedMaster) == 0 { // apply all network addresses - for netAddress, _ := range interfaceNameMap { + for netAddress, devName := range interfaceNameMap { + if netAddress == devName { + // skip device without network address + continue + } log.Printf("select %s", netAddress) selectedMaster = append(selectedMaster, netAddress) } diff --git a/daemon/src/selector/selector.go b/daemon/src/selector/selector.go index e5016044..ec214b6e 100644 --- a/daemon/src/selector/selector.go +++ b/daemon/src/selector/selector.go @@ -57,6 +57,7 @@ func getDefaultResponse(req NICSelectRequest, masterNameMap map[string]string, n selectedMasterNetAddrs := selector.Select(req, masterNameMap, nameNetMap, resourceMap) selectedMasters := []string{} selectedDeviceIDs := []string{} + log.Printf("masterNets %v, %v, %v\n", selectedMasterNetAddrs, masterNameMap, nameNetMap) for _, netAddress := range selectedMasterNetAddrs { deviceID := deviceMap[netAddress] master := masterNameMap[netAddress] @@ -93,11 +94,7 @@ func Select(req NICSelectRequest) NICSelectResponse { masterNameMap := iface.GetInterfaceNameMap() nameNetMap := iface.GetNameNetMap() - netSpec, err := MultinicnetHandler.Get(req.NetAttachDefName, req.PodNamespace) - if err != nil { - return getDefaultResponse(req, masterNameMap, nameNetMap, deviceMap, resourceMap) - } - policy := netSpec.Policy + netSpec, err := MultinicnetHandler.Get(req.NetAttachDefName, metav1.NamespaceAll) var filteredMasterNameMap map[string]string if len(deviceMap) > 0 { @@ -110,6 +107,12 @@ func Select(req NICSelectRequest) NICSelectResponse { filteredMasterNameMap = masterNameMap } + if err != nil { + log.Printf("Failed to get MultiNicNetwork (%s), use default response\n", err.Error()) + return getDefaultResponse(req, filteredMasterNameMap, nameNetMap, deviceMap, resourceMap) + } + policy := netSpec.Policy + var selector Selector strategy := Strategy(policy.Strategy) switch strategy {