Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Multitenancy]: Add NodeInfo crd #2113

Merged
merged 19 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/crdgen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ jobs:
run: make -C crd/nodenetworkconfig
- name: Regenerate MultitenantNetworkContainer CRD
run: make -C crd/multitenantnetworkcontainer
- name: Regenerate NodeInfo CRD
run: make -C crd/nodeinfo
- name: Fail if the tree is dirty
run: test -z "$(git status --porcelain)"
19 changes: 19 additions & 0 deletions crd/nodeinfo/Makefile
Original file line number Diff line number Diff line change
@@ -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)
5 changes: 5 additions & 0 deletions crd/nodeinfo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# NodeInfo CRDs

This CRD is added to enable VNET multitenancy – which will be watched and managed by the control plane.

NodeInfo objects are created by CNS as part of the node registration flow, and is used to pass any metadata from the VM needed by control plane. E.g.: vmUniqueID etc
23 changes: 23 additions & 0 deletions crd/nodeinfo/api/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build !ignore_uncovered
// +build !ignore_uncovered

// Package v1alpha1 contains API Schema definitions for the acn 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
)
43 changes: 43 additions & 0 deletions crd/nodeinfo/api/v1alpha1/nodeinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//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

// NodeInfo is the Schema for the NodeInfo API
// +kubebuilder:resource:scope=Namespaced
// +kubebuilder:resource:shortName=ni
// +kubebuilder:resource:path=nodeinfo
// +kubebuilder:printcolumn:name="VMUniqueID",type=string,priority=0,JSONPath=`.spec.vmUniqueID`
type NodeInfo struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec NodeInfoSpec `json:"spec,omitempty"`
}

// +kubebuilder:object:root=true

// NodeInfoList contains a list of NodeInfo
type NodeInfoList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []NodeInfo `json:"items"`
}

// NodeInfoSpec defines the desired state of NodeInfo
type NodeInfoSpec struct {
// +kubebuilder:validation:Optional
VMUniqueID string `json:"vmUniqueID,omitempty"`
}

func init() {
SchemeBuilder.Register(&NodeInfo{}, &NodeInfoList{})
}
83 changes: 83 additions & 0 deletions crd/nodeinfo/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 84 additions & 0 deletions crd/nodeinfo/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package nodeinfo

import (
"context"
"reflect"

"github.com/Azure/azure-container-networking/crd"
"github.com/Azure/azure-container-networking/crd/nodeinfo/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 NodeInfo scheme.
var Scheme = runtime.NewScheme()

func init() {
_ = scheme.AddToScheme(Scheme)
_ = v1alpha1.AddToScheme(Scheme)
}

// Installer provides methods to manage the lifecycle of the NodeInfo 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 nodeinfo crd")
}
return res, nil
}

// Install installs the embedded NodeInfo CRD definition in the cluster.
func (i *Installer) Install(ctx context.Context) (*v1.CustomResourceDefinition, error) {
nodeinfo, err := GetNodeInfo()
if err != nil {
return nil, errors.Wrap(err, "failed to get embedded nodeinfo crd")
}
return i.create(ctx, nodeinfo)
}

// InstallOrUpdate installs the embedded NodeInfo CRD definition in the cluster or updates it if present.
func (i *Installer) InstallOrUpdate(ctx context.Context) (*v1.CustomResourceDefinition, error) {
nodeinfo, err := GetNodeInfo()
if err != nil {
return nil, errors.Wrap(err, "failed to get embedded nodeinfo crd")
}
current, err := i.create(ctx, nodeinfo)
if !apierrors.IsAlreadyExists(err) {
return current, err
}
if current == nil {
current, err = i.cli.Get(ctx, nodeinfo.Name, metav1.GetOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to get existing nodeinfo crd")
}
}
if !reflect.DeepEqual(nodeinfo.Spec.Versions, current.Spec.Versions) {
nodeinfo.SetResourceVersion(current.GetResourceVersion())
previous := *current
current, err = i.cli.Update(ctx, nodeinfo, metav1.UpdateOptions{})
if err != nil {
return &previous, errors.Wrap(err, "failed to update existing nodeinfo crd")
}
}
return current, nil
}
24 changes: 24 additions & 0 deletions crd/nodeinfo/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package nodeinfo

import (
_ "embed"

"github.com/pkg/errors"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"sigs.k8s.io/yaml"
)

// NodeInfoYAML embeds the CRD YAML for downstream consumers.
//
//go:embed manifests/acn.azure.com_nodeinfo.yaml
var NodeInfoYAML []byte

// GetNodeInfo parses the raw []byte NodeInfo in
// to a CustomResourceDefinition and returns it or an unmarshalling error.
func GetNodeInfo() (*apiextensionsv1.CustomResourceDefinition, error) {
nodeInfo := &apiextensionsv1.CustomResourceDefinition{}
if err := yaml.Unmarshal(NodeInfoYAML, &nodeInfo); err != nil {
return nil, errors.Wrap(err, "error unmarshalling embedded nodeInfo")
}
return nodeInfo, nil
}
21 changes: 21 additions & 0 deletions crd/nodeinfo/embed_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package nodeinfo

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

const filename = "manifests/acn.azure.com_nodeinfo.yaml"

func TestEmbed(t *testing.T) {
b, err := os.ReadFile(filename)
assert.NoError(t, err)
assert.Equal(t, b, NodeInfoYAML)
}

func TestGetNodeInfo(t *testing.T) {
_, err := GetNodeInfo()
assert.NoError(t, err)
}
48 changes: 48 additions & 0 deletions crd/nodeinfo/manifests/acn.azure.com_nodeinfo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.0
name: nodeinfo.acn.azure.com
spec:
group: acn.azure.com
names:
kind: NodeInfo
listKind: NodeInfoList
plural: nodeinfo
singular: nodeinfo
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.vmUniqueID
name: VMUniqueID
priority: 1
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: NodeInfo is the Schema for the NodeInfo 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: NodeInfoSpec defines the desired state of NodeInfo
properties:
vmUniqueID:
type: string
type: object
type: object
served: true
storage: true
subresources: {}
3 changes: 3 additions & 0 deletions crd/nodeinfo/manifests/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package manifests exists to allow the rendered CRD manifests to be
// packaged in to dependent components.
package manifests