Skip to content

Commit

Permalink
feat: add new OverlayExtensionConfig CRD (#2892)
Browse files Browse the repository at this point in the history
  • Loading branch information
robogatikov authored Aug 20, 2024
1 parent 68ede66 commit 456ce7c
Show file tree
Hide file tree
Showing 10 changed files with 399 additions and 0 deletions.
19 changes: 19 additions & 0 deletions crd/overlayextensionconfig/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/overlayextensionconfig/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
List of included CRDs

# OverlayExtensionConfig CRD

OverlayExtensionConfig CRD defines an IP address range (usually an Azure subnet) from which it is possible to reach routing domain IPs (usually pods running in Azure CNI Overlay cluster).
23 changes: 23 additions & 0 deletions crd/overlayextensionconfig/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
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//go:build !ignore_uncovered
// +build !ignore_uncovered

package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// OverlayExtensionConfig is the Schema for the overlayextensionconfigs API
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Namespaced
// +kubebuilder:resource:shortName=oec
// +kubebuilder:printcolumn:name="OverlayExtensionConfig IP range",type=string,priority=1,JSONPath=`.spec.extensionIPRange`
type OverlayExtensionConfig struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec OverlayExtensionConfigSpec `json:"spec,omitempty"`
Status OverlayExtensionConfigStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

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

// OverlayExtensionConfigSpec defines the desired state of OverlayExtensionConfig.
type OverlayExtensionConfigSpec struct {
// ExtensionIPRange field defines a CIDR that should be able to reach routing domain ip addresses.
// +kubebuilder:validation:Optional
ExtensionIPRange string `json:"extensionIPRange,omitempty"`
}

type OECState string

const (
None OECState = "None"
Pending OECState = "Pending"
Succeeded OECState = "Succeeded"
Failed OECState = "Failed"
)

// OverlayExtensionConfigStatus defines the observed state of OverlayExtensionConfig
type OverlayExtensionConfigStatus struct {
// +kubebuilder:validation:Enum=None;Pending;Succeeded;Failed
// +kubebuilder:default="None"
State OECState `json:"state,omitempty"`
Message string `json:"message,omitempty"`
}

func init() {
SchemeBuilder.Register(&OverlayExtensionConfig{}, &OverlayExtensionConfigList{})
}
98 changes: 98 additions & 0 deletions crd/overlayextensionconfig/api/v1alpha1/zz_generated.deepcopy.go

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

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

import (
"context"
"reflect"

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

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

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

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

import (
_ "embed"

// import the manifests package so that caller of this package have the manifests compiled in as a side-effect.
_ "github.com/Azure/azure-container-networking/crd/nodenetworkconfig/manifests"
"github.com/pkg/errors"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"sigs.k8s.io/yaml"
)

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

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

import (
"os"
"testing"

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

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

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

func TestGetOverlayExtensionConfigs(t *testing.T) {
_, err := GetOverlayExtensionConfigs()
require.NoError(t, err)
}
Loading

0 comments on commit 456ce7c

Please sign in to comment.