-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add NetworkAttachmentDefinition support to netwatcher
In an effort to expand the existing netwatcher to be a more generic "Network Management Operator", this commit enhances it to be able to "speak" NAD, besides the 3 DANM APIs. The idea is pretty simple: the Controller components can interpret the CNI config inside NAD.Spec.Config same way as the CNI config in Spec.Options inside any DANM network, then call the existing VLAN, and VxLAN management functionalities regardless which API triggered the Operator. As a result, MACVLAN and IPVLAN type NADs can also enjoy the dynamic VLAN, and VxLAN host interface management functionalities previously exclusive to DANM API users. Netwatcher also takes care of patching the name of the parent interface in Spec.Config, so the upstream CNIs connect the Pods to the right host interface.
- Loading branch information
Showing
35 changed files
with
2,083 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package k8scnicncfio | ||
|
||
const ( | ||
GroupName = "k8s.cni.cncf.io" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
//go:generate bash -c "cg(){ go list -m -f {{.Dir}} k8s.io/code-generator;}; crd(){ cat<<<'github.com/nokia/danm/crd';}; GOFLAGS='' bash $(cg)/generate-groups.sh all $(crd)/client/nad $(crd)/apis k8s.cni.cncf.io:v1 --go-header-file $(cg)/hack/boilerplate.go.txt" | ||
// +k8s:deepcopy-gen=package | ||
// +groupName=k8s.cni.cncf.io | ||
// +groupGoName=K8sCniCncfIo | ||
|
||
package v1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package v1 | ||
|
||
import ( | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
|
||
k8scnicncfio "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io" | ||
) | ||
|
||
// SchemeGroupVersion is group version used to register these objects | ||
var SchemeGroupVersion = schema.GroupVersion{Group: k8scnicncfio.GroupName, Version: "v1"} | ||
|
||
// Resource takes an unqualified resource and returns a Group qualified GroupResource | ||
func Resource(resource string) schema.GroupResource { | ||
return SchemeGroupVersion.WithResource(resource).GroupResource() | ||
} | ||
|
||
var ( | ||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. | ||
SchemeBuilder runtime.SchemeBuilder | ||
localSchemeBuilder = &SchemeBuilder | ||
AddToScheme = localSchemeBuilder.AddToScheme | ||
) | ||
|
||
func init() { | ||
// We only register manually written functions here. The registration of the | ||
// generated functions takes place in the generated files. The separation | ||
// makes the code compile even when the generated files are missing. | ||
localSchemeBuilder.Register(addKnownTypes) | ||
} | ||
|
||
// Adds the list of known types to api.Scheme. | ||
func addKnownTypes(scheme *runtime.Scheme) error { | ||
scheme.AddKnownTypes(SchemeGroupVersion, | ||
&NetworkAttachmentDefinition{}, | ||
&NetworkAttachmentDefinitionList{}, | ||
) | ||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
package v1 | ||
|
||
import ( | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"net" | ||
) | ||
|
||
// +genclient | ||
// +genclient:noStatus | ||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
// +resourceName=network-attachment-definitions | ||
|
||
type NetworkAttachmentDefinition struct { | ||
metav1.TypeMeta `json:",inline"` | ||
metav1.ObjectMeta `json:"metadata,omitempty"` | ||
|
||
Spec NetworkAttachmentDefinitionSpec `json:"spec"` | ||
} | ||
|
||
type NetworkAttachmentDefinitionSpec struct { | ||
Config string `json:"config"` | ||
} | ||
|
||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
type NetworkAttachmentDefinitionList struct { | ||
metav1.TypeMeta `json:",inline"` | ||
metav1.ListMeta `json:"metadata"` | ||
|
||
Items []NetworkAttachmentDefinition `json:"items"` | ||
} | ||
|
||
// DNS contains values interesting for DNS resolvers | ||
// +k8s:deepcopy-gen=false | ||
type DNS struct { | ||
Nameservers []string `json:"nameservers,omitempty"` | ||
Domain string `json:"domain,omitempty"` | ||
Search []string `json:"search,omitempty"` | ||
Options []string `json:"options,omitempty"` | ||
} | ||
|
||
const ( | ||
DeviceInfoTypePCI = "pci" | ||
DeviceInfoTypeVHostUser = "vhost-user" | ||
DeviceInfoTypeMemif = "memif" | ||
DeviceInfoTypeVDPA = "vdpa" | ||
DeviceInfoVersion = "1.0.0" | ||
) | ||
|
||
// DeviceInfo contains the information of the device associated | ||
// with this network (if any) | ||
type DeviceInfo struct { | ||
Type string `json:"type,omitempty"` | ||
Version string `json:"version,omitempty"` | ||
Pci *PciDevice `json:"pci,omitempty"` | ||
Vdpa *VdpaDevice `json:"vdpa,omitempty"` | ||
VhostUser *VhostDevice `json:"vhost-user,omitempty"` | ||
Memif *MemifDevice `json:"memif,omitempty"` | ||
} | ||
|
||
type PciDevice struct { | ||
PciAddress string `json:"pci-address,omitempty"` | ||
Vhostnet string `json:"vhost-net,omitempty"` | ||
RdmaDevice string `json:"rdma-device,omitempty"` | ||
PfPciAddress string `json:"pf-pci-address,omitempty"` | ||
} | ||
|
||
type VdpaDevice struct { | ||
ParentDevice string `json:"parent-device,omitempty"` | ||
Driver string `json:"driver,omitempty"` | ||
Path string `json:"path,omitempty"` | ||
PciAddress string `json:"pci-address,omitempty"` | ||
PfPciAddress string `json:"pf-pci-address,omitempty"` | ||
} | ||
|
||
const ( | ||
VhostDeviceModeClient = "client" | ||
VhostDeviceModeServer = "server" | ||
) | ||
|
||
type VhostDevice struct { | ||
Mode string `json:"mode,omitempty"` | ||
Path string `json:"path,omitempty"` | ||
} | ||
|
||
const ( | ||
MemifDeviceRoleMaster = "master" | ||
MemitDeviceRoleSlave = "slave" | ||
MemifDeviceModeEthernet = "ethernet" | ||
MemitDeviceModeIP = "ip" | ||
MemitDeviceModePunt = "punt" | ||
) | ||
|
||
type MemifDevice struct { | ||
Role string `json:"role,omitempty"` | ||
Path string `json:"path,omitempty"` | ||
Mode string `json:"mode,omitempty"` | ||
} | ||
|
||
// NetworkStatus is for network status annotation for pod | ||
// +k8s:deepcopy-gen=false | ||
type NetworkStatus struct { | ||
Name string `json:"name"` | ||
Interface string `json:"interface,omitempty"` | ||
IPs []string `json:"ips,omitempty"` | ||
Mac string `json:"mac,omitempty"` | ||
Default bool `json:"default,omitempty"` | ||
DNS DNS `json:"dns,omitempty"` | ||
DeviceInfo *DeviceInfo `json:"device-info,omitempty"` | ||
} | ||
|
||
// PortMapEntry for CNI PortMapEntry | ||
// +k8s:deepcopy-gen=false | ||
type PortMapEntry struct { | ||
HostPort int `json:"hostPort"` | ||
ContainerPort int `json:"containerPort"` | ||
Protocol string `json:"protocol,omitempty"` | ||
HostIP string `json:"hostIP,omitempty"` | ||
} | ||
|
||
// BandwidthEntry for CNI BandwidthEntry | ||
// +k8s:deepcopy-gen=false | ||
type BandwidthEntry struct { | ||
IngressRate int `json:"ingressRate"` | ||
IngressBurst int `json:"ingressBurst"` | ||
|
||
EgressRate int `json:"egressRate"` | ||
EgressBurst int `json:"egressBurst"` | ||
} | ||
|
||
// NetworkSelectionElement represents one element of the JSON format | ||
// Network Attachment Selection Annotation as described in section 4.1.2 | ||
// of the CRD specification. | ||
// +k8s:deepcopy-gen=false | ||
type NetworkSelectionElement struct { | ||
// Name contains the name of the Network object this element selects | ||
Name string `json:"name"` | ||
// Namespace contains the optional namespace that the network referenced | ||
// by Name exists in | ||
Namespace string `json:"namespace,omitempty"` | ||
// IPRequest contains an optional requested IP addresses for this network | ||
// attachment | ||
IPRequest []string `json:"ips,omitempty"` | ||
// MacRequest contains an optional requested MAC address for this | ||
// network attachment | ||
MacRequest string `json:"mac,omitempty"` | ||
// InfinibandGUIDRequest contains an optional requested Infiniband GUID | ||
// address for this network attachment | ||
InfinibandGUIDRequest string `json:"infiniband-guid,omitempty"` | ||
// InterfaceRequest contains an optional requested name for the | ||
// network interface this attachment will create in the container | ||
InterfaceRequest string `json:"interface,omitempty"` | ||
// PortMappingsRequest contains an optional requested port mapping | ||
// for the network | ||
PortMappingsRequest []*PortMapEntry `json:"portMappings,omitempty"` | ||
// BandwidthRequest contains an optional requested bandwidth for | ||
// the network | ||
BandwidthRequest *BandwidthEntry `json:"bandwidth,omitempty"` | ||
// CNIArgs contains additional CNI arguments for the network interface | ||
CNIArgs *map[string]interface{} `json:"cni-args"` | ||
// GatewayRequest contains default route IP address for the pod | ||
GatewayRequest []net.IP `json:"default-route,omitempty"` | ||
} | ||
|
||
const ( | ||
// Pod annotation for network-attachment-definition | ||
NetworkAttachmentAnnot = "k8s.v1.cni.cncf.io/networks" | ||
// Pod annotation for network status | ||
NetworkStatusAnnot = "k8s.v1.cni.cncf.io/network-status" | ||
// Old Pod annotation for network status (which is used before but it will be obsolated) | ||
OldNetworkStatusAnnot = "k8s.v1.cni.cncf.io/networks-status" | ||
) | ||
|
||
// NoK8sNetworkError indicates error, no network in kubernetes | ||
// +k8s:deepcopy-gen=false | ||
type NoK8sNetworkError struct { | ||
Message string | ||
} | ||
|
||
func (e *NoK8sNetworkError) Error() string { return string(e.Message) } |
Oops, something went wrong.