[Multitenancy]: Add PNI CRD (#2134)
* ADD CNI PRD * update manifest * add doc.go * ADD CNI PRD * updatepodnetwork ffiel as required * update manifest * fix crdgen --------- Signed-off-by: aggarwal0009 <127549148+aggarwal0009@users.noreply.github.com>
This commit is contained in:
Родитель
9612960758
Коммит
906313d49f
|
@ -26,6 +26,8 @@ jobs:
|
|||
run: make -C crd/nodenetworkconfig
|
||||
- name: Regenerate MultitenantNetworkContainer CRD
|
||||
run: make -C crd/multitenantnetworkcontainer
|
||||
- name: Regenerate PodNetworkInstance CRD
|
||||
run: make -C crd/external/podnetworkinstance
|
||||
- name: Regenerate PodNetwork CRD
|
||||
run: make -C crd/external/podnetwork
|
||||
- name: Regenerate NodeInfo CRD
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
.DEFAULT_GOAL: all
|
||||
|
||||
REPO_ROOT = $(shell git rev-parse --show-toplevel)
|
||||
TOOLS_DIR = $(REPO_ROOT)/build/tools
|
||||
TOOLS_BIN_DIR = $(REPO_ROOT)/build/tools/bin
|
||||
CONTROLLER_GEN = $(TOOLS_BIN_DIR)/controller-gen
|
||||
|
||||
all: generate manifests
|
||||
|
||||
generate: $(CONTROLLER_GEN)
|
||||
$(CONTROLLER_GEN) object paths="./..."
|
||||
|
||||
.PHONY: manifests
|
||||
manifests: $(CONTROLLER_GEN)
|
||||
mkdir -p manifests
|
||||
$(CONTROLLER_GEN) crd paths="./..." output:crd:artifacts:config=manifests/
|
||||
|
||||
$(CONTROLLER_GEN):
|
||||
@make -C $(REPO_ROOT) $(CONTROLLER_GEN)
|
|
@ -0,0 +1,5 @@
|
|||
Pod Network Instance (PNI)
|
||||
|
||||
PNIs represent optional requirements, or behavior configurations for how we setup the pod networking. They should map 1:1 and follow the lifetime of a customer workload.
|
||||
|
||||
The object points to the PodNetwork for the delegated subnet to use and defines allocation requirements (e.g.: for IPs to reserve for pod endpoints). Orchestrator can map the deployments with these requirements to the PNI object through labels on the pod spec pointing to this object identifier.
|
|
@ -0,0 +1,23 @@
|
|||
//go:build !ignore_uncovered
|
||||
// +build !ignore_uncovered
|
||||
|
||||
// Package v1alpha1 contains API Schema definitions for the networking v1alpha1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=acn.azure.com
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "acn.azure.com", Version: "v1alpha1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
|
@ -0,0 +1,56 @@
|
|||
//go:build !ignore_uncovered
|
||||
// +build !ignore_uncovered
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// PodNetworkInstance is the Schema for the PodNetworkInstances API
|
||||
// +kubebuilder:resource:scope=Namespaced
|
||||
// +kubebuilder:resource:shortName=pni
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:metadata:labels=managed=
|
||||
// +kubebuilder:metadata:labels=owner=
|
||||
// +kubebuilder:printcolumn:name="Pod IPs",type=string,priority=1,JSONPath=`.status.podIPAddresses`
|
||||
// +kubebuilder:printcolumn:name="PodNetwork",type=string,priority=1,JSONPath=`.spec.podNetwork`
|
||||
// +kubebuilder:printcolumn:name="PodIPReservationSize",type=string,priority=1,JSONPath=`.spec.podIPReservationSize`
|
||||
type PodNetworkInstance struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec PodNetworkInstanceSpec `json:"spec,omitempty"`
|
||||
Status PodNetworkInstanceStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// PodNetworkInstanceList contains a list of PodNetworkInstance
|
||||
type PodNetworkInstanceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []PodNetworkInstance `json:"items"`
|
||||
}
|
||||
|
||||
// PodNetworkInstanceSpec defines the desired state of PodNetworkInstance
|
||||
type PodNetworkInstanceSpec struct {
|
||||
// pod network resource object name
|
||||
PodNetwork string `json:"podnetwork"`
|
||||
// number of backend IP address to reserve for running pods
|
||||
// +kubebuilder:default=0
|
||||
PodIPReservationSize int `json:"podIPReservationSize"`
|
||||
}
|
||||
|
||||
// PodNetworkInstanceStatus defines the observed state of PodNetworkInstance
|
||||
type PodNetworkInstanceStatus struct {
|
||||
PodIPAddresses []string `json:"podIPAddresses,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&PodNetworkInstance{}, &PodNetworkInstanceList{})
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodNetworkInstance) DeepCopyInto(out *PodNetworkInstance) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodNetworkInstance.
|
||||
func (in *PodNetworkInstance) DeepCopy() *PodNetworkInstance {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodNetworkInstance)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PodNetworkInstance) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodNetworkInstanceList) DeepCopyInto(out *PodNetworkInstanceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]PodNetworkInstance, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodNetworkInstanceList.
|
||||
func (in *PodNetworkInstanceList) DeepCopy() *PodNetworkInstanceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodNetworkInstanceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PodNetworkInstanceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodNetworkInstanceSpec) DeepCopyInto(out *PodNetworkInstanceSpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodNetworkInstanceSpec.
|
||||
func (in *PodNetworkInstanceSpec) DeepCopy() *PodNetworkInstanceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodNetworkInstanceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodNetworkInstanceStatus) DeepCopyInto(out *PodNetworkInstanceStatus) {
|
||||
*out = *in
|
||||
if in.PodIPAddresses != nil {
|
||||
in, out := &in.PodIPAddresses, &out.PodIPAddresses
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodNetworkInstanceStatus.
|
||||
func (in *PodNetworkInstanceStatus) DeepCopy() *PodNetworkInstanceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodNetworkInstanceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package podnetworkinstance
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/Azure/azure-container-networking/crd"
|
||||
"github.com/Azure/azure-container-networking/crd/external/podnetworkinstance/api/v1alpha1"
|
||||
"github.com/pkg/errors"
|
||||
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
typedv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// Scheme is a runtime scheme containing the client-go scheme and the PodNetworkInstance scheme.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
func init() {
|
||||
_ = scheme.AddToScheme(Scheme)
|
||||
_ = v1alpha1.AddToScheme(Scheme)
|
||||
}
|
||||
|
||||
// Installer provides methods to manage the lifecycle of the PodNetworkInstance resource definition.
|
||||
type Installer struct {
|
||||
cli typedv1.CustomResourceDefinitionInterface
|
||||
}
|
||||
|
||||
func NewInstaller(c *rest.Config) (*Installer, error) {
|
||||
cli, err := crd.NewCRDClientFromConfig(c)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to init crd client")
|
||||
}
|
||||
return &Installer{
|
||||
cli: cli,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i *Installer) create(ctx context.Context, res *v1.CustomResourceDefinition) (*v1.CustomResourceDefinition, error) {
|
||||
res, err := i.cli.Create(ctx, res, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create podnetworkinstance crd")
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Install installs the embedded PodNetworkInstance CRD definition in the cluster.
|
||||
func (i *Installer) Install(ctx context.Context) (*v1.CustomResourceDefinition, error) {
|
||||
podnetworkinstance, err := GetPodNetworkInstances()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get embedded podnetworkinstance crd")
|
||||
}
|
||||
return i.create(ctx, podnetworkinstance)
|
||||
}
|
||||
|
||||
// InstallOrUpdate installs the embedded PodNetworkInstance CRD definition in the cluster or updates it if present.
|
||||
func (i *Installer) InstallOrUpdate(ctx context.Context) (*v1.CustomResourceDefinition, error) {
|
||||
podnetworkinstance, err := GetPodNetworkInstances()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get embedded podnetworkinstance crd")
|
||||
}
|
||||
current, err := i.create(ctx, podnetworkinstance)
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return current, err
|
||||
}
|
||||
if current == nil {
|
||||
current, err = i.cli.Get(ctx, podnetworkinstance.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get existing podnetworkinstance crd")
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(podnetworkinstance.Spec.Versions, current.Spec.Versions) {
|
||||
podnetworkinstance.SetResourceVersion(current.GetResourceVersion())
|
||||
previous := *current
|
||||
current, err = i.cli.Update(ctx, podnetworkinstance, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return &previous, errors.Wrap(err, "failed to update existing podnetworkinstance crd")
|
||||
}
|
||||
}
|
||||
return current, nil
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package podnetworkinstance
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// PodNetworkInstanceYAML embeds the CRD YAML for downstream consumers.
|
||||
//
|
||||
//go:embed manifests/acn.azure.com_podnetworkinstances.yaml
|
||||
var PodNetworkInstanceYAML []byte
|
||||
|
||||
// GetPodNetworkInstances parses the raw []byte PodNetworkInstance in
|
||||
// to a CustomResourceDefinition and returns it or an unmarshalling error.
|
||||
func GetPodNetworkInstances() (*apiextensionsv1.CustomResourceDefinition, error) {
|
||||
podNetworkInstances := &apiextensionsv1.CustomResourceDefinition{}
|
||||
if err := yaml.Unmarshal(PodNetworkInstanceYAML, &podNetworkInstances); err != nil {
|
||||
return nil, errors.Wrap(err, "error unmarshalling embedded podNetworkInstance")
|
||||
}
|
||||
return podNetworkInstances, nil
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package podnetworkinstance
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const filename = "manifests/acn.azure.com_podnetworkinstances.yaml"
|
||||
|
||||
func TestEmbed(t *testing.T) {
|
||||
b, err := os.ReadFile(filename)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, b, PodNetworkInstanceYAML)
|
||||
}
|
||||
|
||||
func TestGetPodNetworkInstances(t *testing.T) {
|
||||
_, err := GetPodNetworkInstances()
|
||||
assert.NoError(t, err)
|
||||
}
|
79
crd/external/podnetworkinstance/manifests/acn.azure.com_podnetworkinstances.yaml
поставляемый
Normal file
79
crd/external/podnetworkinstance/manifests/acn.azure.com_podnetworkinstances.yaml
поставляемый
Normal file
|
@ -0,0 +1,79 @@
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.12.0
|
||||
labels:
|
||||
managed: ""
|
||||
owner: ""
|
||||
name: podnetworkinstances.acn.azure.com
|
||||
spec:
|
||||
group: acn.azure.com
|
||||
names:
|
||||
kind: PodNetworkInstance
|
||||
listKind: PodNetworkInstanceList
|
||||
plural: podnetworkinstances
|
||||
shortNames:
|
||||
- pni
|
||||
singular: podnetworkinstance
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.podIPAddresses
|
||||
name: Pod IPs
|
||||
priority: 1
|
||||
type: string
|
||||
- jsonPath: .spec.podNetwork
|
||||
name: PodNetwork
|
||||
priority: 1
|
||||
type: string
|
||||
- jsonPath: .spec.podIPReservationSize
|
||||
name: PodIPReservationSize
|
||||
priority: 1
|
||||
type: string
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: PodNetworkInstance is the Schema for the PodNetworkInstances
|
||||
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: PodNetworkInstanceSpec defines the desired state of PodNetworkInstance
|
||||
properties:
|
||||
podIPReservationSize:
|
||||
default: 0
|
||||
description: number of backend IP address to reserve for running pods
|
||||
type: integer
|
||||
podnetwork:
|
||||
description: pod network resource object name
|
||||
type: string
|
||||
required:
|
||||
- podIPReservationSize
|
||||
- podnetwork
|
||||
type: object
|
||||
status:
|
||||
description: PodNetworkInstanceStatus defines the observed state of PodNetworkInstance
|
||||
properties:
|
||||
podIPAddresses:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
|
@ -0,0 +1,3 @@
|
|||
// Package manifests exists to allow the rendered CRD manifests to be
|
||||
// packaged in to dependent components.
|
||||
package manifests
|
Загрузка…
Ссылка в новой задаче