Skip to content

Commit

Permalink
Merge pull request #50 from vmware-samples/release-1.5.0
Browse files Browse the repository at this point in the history
Release 1.5.0
  • Loading branch information
XudongLiuHarold authored Jan 10, 2022
2 parents f155db1 + 7fcda58 commit 87458b7
Show file tree
Hide file tree
Showing 20 changed files with 585 additions and 391 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ PUBLISH?=publish
BUILD_VERSION ?= $(shell git describe --always --match "v*" | sed 's/v//')

# TKG Version
TKG_VERSION ?= v1.5.0+vmware.1
TKG_VERSION ?= v1.5.0+vmware.3

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
Expand Down Expand Up @@ -98,6 +98,7 @@ integration-test: $(GINKGO) $(ETCD)
$(GINKGO) -v controllers/akodeploymentconfig -- -enable-integration-tests -enable-unit-tests=false
$(GINKGO) -v controllers/machine -- -enable-integration-tests -enable-unit-tests=false
$(GINKGO) -v controllers/cluster -- -enable-integration-tests -enable-unit-tests=false
$(GINKGO) -v controllers/configmap -- -enable-integration-tests -enable-unit-tests=false

.PHONY: kind-e2e-test
kind-e2e-test: $(KUSTOMIZE) $(KIND) $(KUBECTL) $(JQ) $(YTT)
Expand Down
18 changes: 12 additions & 6 deletions api/v1alpha1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,24 @@ const (

ManagementClusterAkoDeploymentConfig = "install-ako-for-management-cluster"

AkoUserRoleName = "ako-essential-role"
ClusterFinalizer = "ako-operator.networking.tkg.tanzu.vmware.com"
AkoDeploymentConfigFinalizer = "ako-operator.networking.tkg.tanzu.vmware.com"
AkoDeploymentConfigKind = "AKODeploymentConfig"
AkoDeploymentConfigVersion = "networking.tanzu.vmware.com/v1alpha1"
AkoStatefulSetName = "ako"
AkoUserRoleName = "ako-essential-role"
ClusterFinalizer = "ako-operator.networking.tkg.tanzu.vmware.com"
AkoDeploymentConfigFinalizer = "ako-operator.networking.tkg.tanzu.vmware.com"
AkoDeploymentConfigKind = "AKODeploymentConfig"
AkoDeploymentConfigVersion = "networking.tanzu.vmware.com/v1alpha1"
AkoStatefulSetName = "ako"
AkoConfigMapName = "avi-k8s-config"
AkoConfigMapCloudNameKey = "cloudName"
AkoConfigMapControllerIPKey = "controllerIP"
AkoConfigMapVipNetworkListKey = "vipNetworkList"

AVI_VERSION = "20.1.3"
AviClusterLabel = "networking.tkg.tanzu.vmware.com/avi"
AviClusterSelectedLabel = "networking.tkg.tanzu.vmware.com/avi-skip-default-adc"
AviClusterSecretType = "avi.cluster.x-k8s.io/secret"
AviNamespace = "avi-system"
AviCredentialName = "avi-controller-credentials"
AviCAName = "avi-controller-ca"
AviCertificateKey = "certificateAuthorityData"
AviResourceCleanupReason = "AviResourceCleanup"
AviResourceCleanupSucceededCondition clusterv1.ConditionType = "AviResourceCleanupSucceeded"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package akodeploymentconfig

import (
"context"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/pkg/netprovider"

"github.com/vmware-samples/load-balancer-operator-for-kubernetes/controllers/akodeploymentconfig/cluster"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/controllers/akodeploymentconfig/phases"
Expand Down Expand Up @@ -48,6 +49,7 @@ type AKODeploymentConfigReconciler struct {
Scheme *runtime.Scheme
userReconciler *user.AkoUserReconciler
ClusterReconciler *cluster.ClusterReconciler
netprovider.UsableNetworkProvider
}

func (r *AKODeploymentConfigReconciler) SetAviClient(client aviclient.Client) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,25 @@ package akodeploymentconfig
import (
"bytes"
"context"

"net"
"sort"
"time"

"github.com/pkg/errors"

"github.com/vmware-samples/load-balancer-operator-for-kubernetes/controllers/akodeploymentconfig/phases"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/controllers/akodeploymentconfig/user"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/pkg/haprovider"

"github.com/avinetworks/sdk/go/models"
"github.com/go-logr/logr"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

akoov1alpha1 "github.com/vmware-samples/load-balancer-operator-for-kubernetes/api/v1alpha1"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/controllers/akodeploymentconfig/phases"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/controllers/akodeploymentconfig/user"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/pkg/aviclient"
akov1alpha1 "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/pkg/apis/ako/v1alpha1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/pkg/haprovider"

ako_operator "github.com/vmware-samples/load-balancer-operator-for-kubernetes/pkg/ako-operator"
akoov1alpha1 "github.com/vmware-samples/load-balancer-operator-for-kubernetes/api/v1alpha1"
akov1alpha1 "github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/pkg/apis/ako/v1alpha1"
)

func (r *AKODeploymentConfigReconciler) initAVI(
Expand All @@ -41,43 +36,15 @@ func (r *AKODeploymentConfigReconciler) initAVI(

// Lazily initialize aviClient so we don't skip other reconciliations
if r.aviClient == nil {
adminCredential := &corev1.Secret{}
if err := r.Client.Get(ctx, client.ObjectKey{
Name: obj.Spec.AdminCredentialRef.Name,
Namespace: obj.Spec.AdminCredentialRef.Namespace,
}, adminCredential); err != nil {
if apierrors.IsNotFound(err) {
log.Info("Cannot find referenced AdminCredential Secret, requeue the request")
} else {
log.Error(err, "Failed to find referenced AdminCredential Secret")
}
return res, err
}
var err error
r.aviClient, err = aviclient.NewAviClientFromSecrets(r.Client, ctx, log, obj.Spec.Controller,
obj.Spec.AdminCredentialRef.Name, obj.Spec.AdminCredentialRef.Namespace,
obj.Spec.CertificateAuthorityRef.Name, obj.Spec.CertificateAuthorityRef.Namespace)

aviControllerCA := &corev1.Secret{}
if err := r.Client.Get(ctx, client.ObjectKey{
Name: obj.Spec.CertificateAuthorityRef.Name,
Namespace: obj.Spec.CertificateAuthorityRef.Namespace,
}, aviControllerCA); err != nil {
if apierrors.IsNotFound(err) {
log.Info("Cannot find referenced CertificateAuthorityRef Secret, requeue the request")
} else {
log.Error(err, "Failed to find referenced CertificateAuthorityRef Secret")
}
return res, err
}
aviClient, err := aviclient.NewAviClient(&aviclient.AviClientConfig{
ServerIP: obj.Spec.Controller,
Username: string(adminCredential.Data["username"][:]),
Password: string(adminCredential.Data["password"][:]),
CA: string(aviControllerCA.Data["certificateAuthorityData"][:]),
}, ako_operator.GetAVIControllerVersion())
if err != nil {
log.Error(err, "Failed to initialize AVI Controller Client, requeue the request")
log.Error(err, "Cannot init AVI clients from secrets")
return res, err
}

r.aviClient = aviClient
log.Info("AVI Client initialized successfully")
}

Expand Down Expand Up @@ -204,67 +171,20 @@ func (r *AKODeploymentConfigReconciler) reconcileCloudUsableNetwork(
log logr.Logger,
obj *akoov1alpha1.AKODeploymentConfig,
) (ctrl.Result, error) {
res := ctrl.Result{}

log = log.WithValues("cloud", obj.Spec.CloudName)
log.Info("Start reconciling AVI cloud usable networks")

requeueAfter := ctrl.Result{
Requeue: true,
RequeueAfter: time.Second * 60,
}
log.Info("Start reconciling AVI cloud usable network")

network, err := r.aviClient.NetworkGetByName(obj.Spec.DataNetwork.Name)
added, err := r.AddUsableNetwork(r.aviClient, obj.Spec.CloudName, obj.Spec.DataNetwork.Name)
if err != nil {
log.Error(errors.Errorf("[WARN]Failed to get the Data Network %s from AVI Controller", obj.Spec.DataNetwork.Name), "")
return requeueAfter, nil
log.Error(err, "Failed to add usable network", obj.Spec.DataNetwork.Name)
return ctrl.Result{}, err
}

cloud, err := r.aviClient.CloudGetByName(obj.Spec.CloudName)
if err != nil {
log.Error(err, "Faild to find cloud, requeue the request")
// Cannot find the configured cloud, requeue the request but
// leave enough time for operators to resolve this issue
return requeueAfter, nil
}
if cloud.IPAMProviderRef == nil {
log.Info("No IPAM Provider is registered for the cloud, requeue the request")
// Cannot find any configured IPAM Provider, requeue the request but
// leave enough time for operators to resolve this issue
return requeueAfter, nil
}

ipamProviderUUID := aviclient.GetUUIDFromRef(*(cloud.IPAMProviderRef))

log = log.WithValues("ipam-profile", *(cloud.IPAMProviderRef))

ipam, err := r.aviClient.IPAMDNSProviderProfileGet(ipamProviderUUID)
if err != nil {
log.Error(err, "Failed to find ipam profile")
return requeueAfter, nil
}

// Ensure network is added to the cloud's IPAM Profile as one of its
// usable Networks
var foundUsableNetwork bool
for _, net := range ipam.InternalProfile.UsableNetworks {
if *net.NwRef == *(network.URL) {
foundUsableNetwork = true
break
}
}
if !foundUsableNetwork {
ipam.InternalProfile.UsableNetworks = append(ipam.InternalProfile.UsableNetworks, &models.IPAMUsableNetwork{NwRef: network.URL})
_, err := r.aviClient.IPAMDNSProviderProfileUpdate(ipam)
if err != nil {
log.Error(err, "Failed to add usable network", "network", network.Name)
return res, nil
}
if added {
log.Info("Added Usable Network", obj.Spec.DataNetwork.Name)
} else {
log.Info("Network is already one of the cloud's usable network")
log.Info("Network is already one of the cloud's usable network", obj.Spec.DataNetwork.Name)
}

return res, nil
return ctrl.Result{}, nil
}

func (r *AKODeploymentConfigReconciler) reconcileAviInfraSetting(
Expand Down
134 changes: 134 additions & 0 deletions controllers/configmap/configmap_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright 2021 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

package configmap

import (
"context"
"encoding/json"
"fmt"
"github.com/go-logr/logr"
"github.com/pkg/errors"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/api/v1alpha1"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/pkg/aviclient"
"github.com/vmware-samples/load-balancer-operator-for-kubernetes/pkg/netprovider"
"k8s.io/apimachinery/pkg/runtime"

corev1 "k8s.io/api/core/v1"

apierrors "k8s.io/apimachinery/pkg/api/errors"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// SetupWithManager adds this reconciler to a new controller then to the
// provided manager.
func (r *ConfigMapReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
// Watch ConfigMap resources.
For(&corev1.ConfigMap{}).
Complete(r)
}

// ConfigMapReconciler reads the data network from avi-k8s-config ConfigMap and
// accordingly adds it as a usable network via the AVI Controller client.
type ConfigMapReconciler struct {
client.Client
aviClient aviclient.Client
Log logr.Logger
Scheme *runtime.Scheme
netprovider.UsableNetworkProvider
}

// initAVI initializes the AVI client with hardcoded name of secrets
// @TODO(fhan): do not use hardcoded secret names, modify the t-f to pass in the secret name to this controller
func (r *ConfigMapReconciler) initAVI(ctx context.Context,
log logr.Logger, controllerIP string) (ctrl.Result, error) {
res := ctrl.Result{}

if r.aviClient == nil {
var err error
r.aviClient, err = aviclient.NewAviClientFromSecrets(r.Client, ctx, log, controllerIP,
v1alpha1.AviCredentialName, v1alpha1.TKGSystemNamespace,
v1alpha1.AviCAName, v1alpha1.TKGSystemNamespace)
if err != nil {
log.Error(err, "Cannot init AVI clients from secrets")
return res, err
}
log.Info("AVI Client initialized successfully")
}
return res, nil
}

func (r *ConfigMapReconciler) SetAviClient(client aviclient.Client) {
r.aviClient = client
}

var InvalidAKOConfigMapErr = errors.New("Invalid format of AKO ConfigMap")

func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {

log := r.Log.WithValues("ConfigMap", req.NamespacedName)

// Get the resource for this request.
cm := &corev1.ConfigMap{}
if err := r.Client.Get(ctx, req.NamespacedName, cm); err != nil {
if apierrors.IsNotFound(err) {
log.Info("ConfigMap not found, will not reconcile")
return ctrl.Result{}, nil
}
return ctrl.Result{}, err
}

if cm.Name != v1alpha1.AkoConfigMapName || cm.Namespace != v1alpha1.TKGSystemNamespace {
return ctrl.Result{}, nil
}

log.Info("Start reconciling AVI cloud usable network in bootstrap cluster")

cloudName, exist := cm.Data[v1alpha1.AkoConfigMapCloudNameKey]
if !exist {
log.Info("Key not found in ConfigMap: cloudName")
return ctrl.Result{}, InvalidAKOConfigMapErr
}
vipNetworkListRaw, exist := cm.Data[v1alpha1.AkoConfigMapVipNetworkListKey]
if !exist {
log.Info("Key not found in ConfigMap: vipNetworkList")
return ctrl.Result{}, InvalidAKOConfigMapErr
}
var vipNetworkList netprovider.UsableNetworks
if err := json.Unmarshal([]byte(vipNetworkListRaw), &vipNetworkList); err != nil {
log.Error(err, "Failed to unmarshal VIPNetworkList")
return ctrl.Result{}, err
}
controllerIP, exist := cm.Data[v1alpha1.AkoConfigMapControllerIPKey]
if !exist {
log.Info("Key not found in ConfigMap: controllerIP")
return ctrl.Result{}, InvalidAKOConfigMapErr
}
if controllerIP == "" {
log.Info("Controller IP is empty")
return ctrl.Result{}, InvalidAKOConfigMapErr
}

log.V(5).Info(fmt.Sprintf("ConfigMap %s found in %s, initializing AVI related clients", v1alpha1.AkoConfigMapName, v1alpha1.TKGSystemNamespace))

if res, err := r.initAVI(ctx, log, controllerIP); err != nil {
log.Error(err, "Failed to initialize avi related clients")
return res, err
}

for _, vipNetwork := range vipNetworkList {
added, err := r.AddUsableNetwork(r.aviClient, cloudName, vipNetwork.NetworkName)
if err != nil {
log.Error(err, "Failed to add usable network", vipNetwork.NetworkName)
return ctrl.Result{}, err
}
if added {
log.Info("Added Usable Network", vipNetwork.NetworkName)
} else {
log.Info("Network is already one of the cloud's usable network", vipNetwork.NetworkName)
}
}
return ctrl.Result{}, nil
}
Loading

0 comments on commit 87458b7

Please sign in to comment.