Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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: 1 addition & 1 deletion cmd/operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func main() {

// local cluster import is only relevant if assisted installer can manage/scale the local cluster and this is only the case for OpenShift
if isOpenShift {
if err = (controllers.NewLocalClusterImportReconciler(mgr.GetClient(), "local-cluster", controllers.AgentServiceConfigName, log)).SetupWithManager(mgr); err != nil {
if err = (controllers.NewLocalClusterImportReconciler(mgr.GetClient(), controllers.AgentServiceConfigName, log)).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "LocalClusterImportReconciler")
os.Exit(1)
}
Expand Down
115 changes: 82 additions & 33 deletions internal/controller/controllers/local_cluster_import_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const (
hubPullSecretNamespace = "openshift-config" // #nosec G101
hubPullSecretName = "pull-secret" // #nosec G101
importLocalClusterEnabledAnnotation = "agent-install.openshift.io/enable-local-cluster-import"
localClusterLabel = "local-cluster"
clusterIDLabel = "clusterID"
)

type LocalClusterImportReconciler struct {
Expand All @@ -45,10 +47,9 @@ type LocalClusterImportReconciler struct {
agentServiceConfigName string
}

func NewLocalClusterImportReconciler(client client.Client, localClusterName string, agentServiceConfigName string, log *logrus.Logger) *LocalClusterImportReconciler {
func NewLocalClusterImportReconciler(client client.Client, agentServiceConfigName string, log *logrus.Logger) *LocalClusterImportReconciler {
return &LocalClusterImportReconciler{
client: client,
localClusterName: localClusterName,
log: log,
agentServiceConfigName: agentServiceConfigName,
}
Expand Down Expand Up @@ -137,16 +138,29 @@ func (r *LocalClusterImportReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}

hasManagedCluster, err := r.hasLocalManagedCluster(ctx)
clusterVersion := &configv1.ClusterVersion{}
namespacedName := types.NamespacedName{
Name: "version",
}
err := r.client.Get(ctx, namespacedName, clusterVersion)
if err != nil {
return ctrl.Result{}, errors.Wrap(err, "unable to fetch local cluster version")
}

err = r.getLocalManagedClusterName(ctx, clusterVersion)
if err != nil {
err = r.setReconciliationStatus(ctx, false, aiv1beta1.ReasonUnableToDetermineLocalClusterManagedStatus, err.Error())
if err != nil {
return ctrl.Result{}, errors.Wrap(err, "Unable to set reconciliation status of LocalClusterImport on AgentServiceConfig")
}
return ctrl.Result{}, errors.Wrap(err, "error while attempting to determine presence of managed cluster")
return ctrl.Result{}, errors.Wrap(err, "error while attempting to determine local cluster name")
}
hasLocalManagedCluster, err := r.hasLocalManagedCluster(ctx)
if err != nil {
return ctrl.Result{}, err
}
if hasManagedCluster {
if err = r.importLocalCluster(ctx, instance); err != nil {
if hasLocalManagedCluster {
if err = r.importLocalCluster(ctx, instance, clusterVersion); err != nil {
return ctrl.Result{}, errors.Wrap(err, "failed to create managed cluster CRs")
}
err = r.setReconciliationStatus(ctx, true, aiv1beta1.ReasonLocalClusterManaged, "")
Expand All @@ -169,8 +183,9 @@ func (r *LocalClusterImportReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, nil
}

func (r *LocalClusterImportReconciler) checkManagedClusterName(obj metav1.Object) bool {
return obj.GetName() == r.localClusterName
func checkIsLocalManagedCluster(obj metav1.Object) bool {
value, ok := obj.GetLabels()[localClusterLabel]
return strings.ToLower(value) == "true" && ok
}

func checkSecretName(obj metav1.Object) bool {
Expand All @@ -180,10 +195,10 @@ func checkSecretName(obj metav1.Object) bool {
// SetupWithManager sets up the controller with the Manager.
func (r *LocalClusterImportReconciler) SetupWithManager(mgr ctrl.Manager) error {
managedClusterPredicates := builder.WithPredicates(predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool { return r.checkManagedClusterName(e.Object) },
UpdateFunc: func(e event.UpdateEvent) bool { return r.checkManagedClusterName(e.ObjectNew) },
DeleteFunc: func(e event.DeleteEvent) bool { return r.checkManagedClusterName(e.Object) },
GenericFunc: func(e event.GenericEvent) bool { return r.checkManagedClusterName(e.Object) },
CreateFunc: func(e event.CreateEvent) bool { return checkIsLocalManagedCluster(e.Object) },
UpdateFunc: func(e event.UpdateEvent) bool { return checkIsLocalManagedCluster(e.ObjectNew) },
DeleteFunc: func(e event.DeleteEvent) bool { return checkIsLocalManagedCluster(e.Object) },
GenericFunc: func(e event.GenericEvent) bool { return checkIsLocalManagedCluster(e.Object) },
})
secretPredicates := builder.WithPredicates(predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool { return checkSecretName(e.Object) },
Expand Down Expand Up @@ -263,16 +278,49 @@ func (r *LocalClusterImportReconciler) deleteInfraEnv(ctx context.Context, names
return nil
}

func (r *LocalClusterImportReconciler) deleteSecret(ctx context.Context, namespace string, name string) error {
secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
if err := r.client.Delete(ctx, secret); err != nil && !k8serrors.IsNotFound(err) {
return errors.Wrapf(err, "failed to delete Secret %s in namespace %s", name, namespace)
}
return nil
}

func (r *LocalClusterImportReconciler) getLocalManagedClusterName(ctx context.Context, clusterVersion *configv1.ClusterVersion) error {
if r.localClusterName != "" {
return nil
}
managedClusters := &clusterv1.ManagedClusterList{}
// This should result in a single ManagedCluster that matches our clusterID
err := r.client.List(ctx, managedClusters, client.MatchingLabels{localClusterLabel: "true", clusterIDLabel: string(clusterVersion.Spec.ClusterID)})
if err != nil {
return err
}
Comment thread
paul-maidment marked this conversation as resolved.
Outdated
count := len(managedClusters.Items)
if count == 0 {
r.localClusterName = ""
}
if count > 1 {
return errors.Errorf("expectd a single matching local managed cluster and received %d instead", count)
}
if count == 1 {
r.localClusterName = managedClusters.Items[0].Name
}
return nil
}

func (r *LocalClusterImportReconciler) hasLocalManagedCluster(ctx context.Context) (bool, error) {
managedCluster := &clusterv1.ManagedCluster{}
namespacedName := types.NamespacedName{
Name: r.localClusterName,
err := r.client.Get(ctx, types.NamespacedName{Name: r.localClusterName}, managedCluster)
if k8serrors.IsNotFound(err) {
return false, nil
}
err := r.client.Get(ctx, namespacedName, managedCluster)
if err != nil {
if k8serrors.IsNotFound(err) {
return false, nil
}
Comment thread
carbonin marked this conversation as resolved.
Outdated
return false, err
}
return true, nil
Expand All @@ -284,17 +332,28 @@ func (r *LocalClusterImportReconciler) hasLocalManagedCluster(ctx context.Contex
func (r *LocalClusterImportReconciler) ensureLocalClusterCRsDeleted(ctx context.Context) error {
err := r.deleteClusterDeployment(ctx, r.localClusterName, r.localClusterName)
if err != nil && !k8serrors.IsNotFound(err) {
r.log.Errorf("could not delete local ClusterDeployment due to error %s", err.Error())
r.log.Errorf("could not delete local cluster ClusterDeployment due to error %s", err.Error())
return err
}
err = r.deleteAgentClusterInstall(ctx, r.localClusterName, r.localClusterName)
if err != nil && !k8serrors.IsNotFound(err) {
r.log.Errorf("could not delete local AgentClusterInstall due to error %s", err.Error())
r.log.Errorf("could not delete local cluster AgentClusterInstall due to error %s", err.Error())
return err
}
err = r.deleteInfraEnv(ctx, r.localClusterName, r.localClusterName)
if err != nil && !k8serrors.IsNotFound(err) {
r.log.Errorf("could not delete local InfraEnv due to error %s", err.Error())
r.log.Errorf("could not delete local cluster InfraEnv due to error %s", err.Error())
return err
}
adminKubeConfigSecretName := fmt.Sprintf(adminKubeConfigStringTemplate, r.localClusterName)
err = r.deleteSecret(ctx, r.localClusterName, adminKubeConfigSecretName)
Comment thread
paul-maidment marked this conversation as resolved.
Outdated
if err != nil && !k8serrors.IsNotFound(err) {
r.log.Errorf("could not delete local cluster Secret %s due to error %s", adminKubeConfigSecretName, err.Error())
return err
}
err = r.deleteSecret(ctx, r.localClusterName, hubPullSecretName)
if err != nil && !k8serrors.IsNotFound(err) {
r.log.Errorf("could not delete local cluster Secret %s due to error %s", hubPullSecretName, err.Error())
return err
}
return nil
Expand Down Expand Up @@ -481,17 +540,7 @@ func (r *LocalClusterImportReconciler) createOrUpdateClusterDeployment(ctx conte
return nil
}

func (r *LocalClusterImportReconciler) importLocalCluster(ctx context.Context, instance *aiv1beta1.AgentServiceConfig) error {

clusterVersion := &configv1.ClusterVersion{}
namespacedName := types.NamespacedName{
Name: "version",
}
err := r.client.Get(ctx, namespacedName, clusterVersion)
if err != nil {
return errors.Wrap(err, "unable to find cluster version")
}

func (r *LocalClusterImportReconciler) importLocalCluster(ctx context.Context, instance *aiv1beta1.AgentServiceConfig, clusterVersion *configv1.ClusterVersion) error {
kubeConfigSecret, err := r.getSecret(ctx, hubKubeConfigNamespace, hubKubeConfigName)
if err != nil {
return errors.Wrap(err, "unable to fetch local cluster kubeconfigs")
Expand All @@ -503,7 +552,7 @@ func (r *LocalClusterImportReconciler) importLocalCluster(ctx context.Context, i
}

dns := &configv1.DNS{}
namespacedName = types.NamespacedName{
namespacedName := types.NamespacedName{
Name: "cluster",
}
err = r.client.Get(ctx, namespacedName, dns)
Expand Down
Loading