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

changes to support brownfield onboarding to ANK8s #588

Merged
merged 23 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 18 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
9 changes: 9 additions & 0 deletions controllers/acc_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ const (

// AccInitContainerImage - tag for init container image
AccInitContainerImage string = "<ACC_INIT_CONTAINER_IMAGE>"

// BrownfieldManifest - manifest for brownfield role/rolebinding creation
BrownfieldManifest string = "brownfield-onboard.yaml"
)

// ApexConnectivityClientReconciler reconciles a ApexConnectivityClient object
Expand Down Expand Up @@ -438,6 +441,8 @@ func applyAccConfigVersionAnnotations(ctx context.Context, instance *csmv1.ApexC

// DeployApexConnectivityClient - perform deployment
func DeployApexConnectivityClient(ctx context.Context, isDeleting bool, operatorConfig utils.OperatorConfig, cr csmv1.ApexConnectivityClient, ctrlClient crclient.Client) error {
log := logger.GetLogger(ctx)

YamlString := ""
ModifiedYamlString := ""
deploymentPath := fmt.Sprintf("%s/clientconfig/%s/%s/%s", operatorConfig.ConfigDirectory, csmv1.DreadnoughtClient, cr.Spec.Client.ConfigVersion, AccManifest)
Expand Down Expand Up @@ -465,6 +470,10 @@ func DeployApexConnectivityClient(ctx context.Context, isDeleting bool, operator
}
}

if err = utils.CreateBrownfieldRbac(ctx, operatorConfig, cr, ctrlClient); err != nil {
log.Error(err, "error creating role/rolebindings")
}

return nil
}

Expand Down
6 changes: 6 additions & 0 deletions controllers/acc_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ func (suite *AccControllerTestSuite) TestReconcileAcc() {
suite.runFakeAccManager("", true)
}

func (suite *AccControllerTestSuite) TestAccConnectivityClient() {
csm := shared.MakeAcc(accName, suite.namespace, accConfigVersion)
csm.Spec.Client.CSMClientType = csmv1.DreadnoughtClient
csm.Spec.Client.Common.Image = "image"
}

func (suite *AccControllerTestSuite) TestAccConnectivityClientConnectionTarget() {
csm := shared.MakeAcc(accName, suite.namespace, accConfigVersion)
csm.Spec.Client.CSMClientType = csmv1.DreadnoughtClient
Expand Down
5 changes: 5 additions & 0 deletions controllers/csm_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,11 @@ func (r *ContainerStorageModuleReconciler) SyncCSM(ctx context.Context, cr csmv1
}

}
// If dell connectivity client is deployed, create role/rolebindings in the csm namespaces
if err = utils.CheckAccAndCreateRbac(ctx, operatorConfig, ctrlClient); err != nil {
return err
}

return nil
}

Expand Down
110 changes: 109 additions & 1 deletion pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
t1 "k8s.io/apimachinery/pkg/types"
confv1 "k8s.io/client-go/applyconfigurations/apps/v1"
acorev1 "k8s.io/client-go/applyconfigurations/core/v1"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/yaml"

Expand Down Expand Up @@ -139,6 +140,12 @@ const (
PodmonNodeComponent = "podmon-node"
// ApplicationMobilityNamespace - application-mobility
ApplicationMobilityNamespace = "application-mobility"
// ExistingNamespace - existing namespace
ExistingNamespace = "<ExistingNameSpace>"
// ClientNamespace - client namespace
ClientNamespace = "<ClientNameSpace>"
// BrownfieldManifest - brownfield-onboard.yaml
BrownfieldManifest = "brownfield-onboard.yaml"
)

// SplitYaml divides a big bytes of yaml files in individual yaml files.
Expand Down Expand Up @@ -1202,7 +1209,39 @@ func getUpgradeInfo[T csmv1.CSMComponentType](ctx context.Context, operatorConfi
return upgradePath.MinUpgradePath, nil
}

func getNamespaces(ctx context.Context, ctrlClient crclient.Client) ([]string, error) {
// BrownfieldOnboard will onboard the brownfield cluster
func BrownfieldOnboard(ctx context.Context, path string, cr csmv1.ApexConnectivityClient, ctrlClient crclient.Client) error {
logInstance := logger.GetLogger(ctx)

namespaces, err := GetNamespaces(ctx, ctrlClient)
if err != nil {
logInstance.Error(err, "Failed to get namespaces")
return err
}

manifestFile, err := os.ReadFile(filepath.Clean(path))
if err != nil {
logInstance.Error(err, "Failed to read manifest file")
return err
}

yamlFile := string(manifestFile)

for _, ns := range namespaces {

yamlFile := strings.ReplaceAll(yamlFile, ExistingNamespace, ns)
yamlFile = strings.ReplaceAll(yamlFile, ClientNamespace, cr.Namespace)

err := CreateObjects(ctx, yamlFile, ctrlClient)
if err != nil {
return err
}
}
return nil
}

// GetNamespaces returns the list of namespaces in the cluster
func GetNamespaces(ctx context.Context, ctrlClient crclient.Client) ([]string, error) {
// Set to store unique namespaces
namespaceMap := make(map[string]struct{})

Expand All @@ -1223,3 +1262,72 @@ func getNamespaces(ctx context.Context, ctrlClient crclient.Client) ([]string, e

return namespaces, nil
}

// CreateObjects creates the objects in the cluster
func CreateObjects(ctx context.Context, yamlFile string, ctrlClient crclient.Client) error {
deployObjects, err := GetModuleComponentObj([]byte(yamlFile))
if err != nil {
return err
}
for _, obj := range deployObjects {
log.FromContext(ctx).Info("namespace of parsed object is", "object", obj.GetNamespace())

found := obj.DeepCopyObject().(crclient.Object)
err := ctrlClient.Get(ctx, crclient.ObjectKey{Namespace: obj.GetNamespace(), Name: obj.GetName()}, found)
if err != nil && k8serror.IsNotFound(err) {
log.FromContext(ctx).Info("Creating a new object", "object", obj.GetObjectKind().GroupVersionKind().String())
err := ctrlClient.Create(ctx, obj)
if err != nil {
return err
}
} else if err != nil {
log.FromContext(ctx).Info("Unknown error trying to retrieve the object.", "Error", err.Error())
return err
} else {
log.FromContext(ctx).Info("Updating Object", "object", obj.GetObjectKind().GroupVersionKind().String())
err = ctrlClient.Update(ctx, obj)
if err != nil {
return err
}
}
}
return nil
}

// CheckAccAndCreateRbac checks if the dell connectivity client exists and creates the role and rolebindings
func CheckAccAndCreateRbac(ctx context.Context, operatorConfig OperatorConfig, ctrlClient crclient.Client) error {
logInstance := logger.GetLogger(ctx)
accList := &csmv1.ApexConnectivityClientList{}
if err := ctrlClient.List(ctx, accList); err != nil {
logInstance.Info("dell connectivity client not found")
} else if len(accList.Items) <= 0 {
logInstance.Info("dell connectivity client not found")
} else {
logInstance.Info("dell connectivity client found")
cr := new(csmv1.ApexConnectivityClient)
accConfigVersion := accList.Items[0].Spec.Client.ConfigVersion
brownfieldManifestFilePath := fmt.Sprintf("%s/clientconfig/%s/%s/%s", operatorConfig.ConfigDirectory,
csmv1.DreadnoughtClient, accConfigVersion, BrownfieldManifest)
if err = BrownfieldOnboard(ctx, brownfieldManifestFilePath, *cr, ctrlClient); err != nil {
logInstance.Error(err, "error creating role/rolebindings")
return err
}
}
return nil
}

// CreateBrownfieldRbac creates the role and rolebindings
func CreateBrownfieldRbac(ctx context.Context, operatorConfig OperatorConfig, cr csmv1.ApexConnectivityClient, ctrlClient crclient.Client) error {
logInstance := logger.GetLogger(ctx)
csmList := &csmv1.ContainerStorageModuleList{}
err := ctrlClient.List(ctx, csmList)
if err == nil && len(csmList.Items) > 0 {
logInstance.Info("Found existing csm installations. Proceeding to create role/rolebindings")
brownfieldManifestFilePath := fmt.Sprintf("%s/clientconfig/%s/%s/%s", operatorConfig.ConfigDirectory, csmv1.DreadnoughtClient, cr.Spec.Client.ConfigVersion, BrownfieldManifest)
if err = BrownfieldOnboard(ctx, brownfieldManifestFilePath, cr, ctrlClient); err != nil {
logInstance.Error(err, "error creating role/rolebindings")
return err
}
}
return nil
}
Loading