diff --git a/Makefile b/Makefile index c53e5231..190daada 100644 --- a/Makefile +++ b/Makefile @@ -129,6 +129,19 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - +.PHONY: k3d-import-img +k3d-import-img: + k3d image import $(IMG) -c $(K3D_CLUSTER_NAME) + +.PHONY: apply-sample-cr +apply-sample-cr: + kubectl apply -f config/samples/infrastructuremanager_v1_gardenercluster.yaml + +.PHONE: local-build-and-deploy +local-build-and-deploy: docker-build k3d-import-img deploy gardener-secret-deploy apply-sample-cr + +.PHONY: local-rebuild-and-redeploy +local-rebuild-and-redeploy: undeploy local-build-and-deploy ##@ Build Dependencies ## Location to install dependencies to diff --git a/README.md b/README.md index bd52147a..c7f5df69 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,9 @@ make docker-build k3d + ```bash + k3d cluster create $K3D_CLUSTER_NAME k3d image import $IMG -c $K3D_CLUSTER_NAME ``` diff --git a/api/v1/gardenercluster_types.go b/api/v1/gardenercluster_types.go index a982c145..cd66c895 100644 --- a/api/v1/gardenercluster_types.go +++ b/api/v1/gardenercluster_types.go @@ -17,6 +17,7 @@ limitations under the License. package v1 import ( + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -73,6 +74,21 @@ const ( DeletingState State = "Deleting" ) +type ConditionReason string + +const ( + ConditionReasonSecretCreated State = "SecretCreated" + ConditionReasonSecretNotFound State = "SecretNotFound" + ConditionReasonGardenClusterNotRetrieved State = "GardenClusterNotRetrieved" + ConditionReasonGardenClusterNotFound State = "GardenClusterNotFound" +) + +type ConditionType string + +const ( + ConditionTypeUnknown State = "Unknown" +) + // GardenerClusterStatus defines the observed state of GardenerCluster type GardenerClusterStatus struct { // State signifies current state of Gardener Cluster. @@ -86,6 +102,18 @@ type GardenerClusterStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` } +func (cluster *GardenerCluster) UpdateState(r State, s State, msg string) { + cluster.Status.State = s + condition := metav1.Condition{ + Type: string(ConditionTypeUnknown), + Status: "True", + LastTransitionTime: metav1.Now(), + Reason: string(r), + Message: msg, + } + meta.SetStatusCondition(&cluster.Status.Conditions, condition) +} + func init() { SchemeBuilder.Register(&GardenerCluster{}, &GardenerClusterList{}) } diff --git a/config/default/manager_gardener_secret_patch.yaml b/config/default/manager_gardener_secret_patch.yaml index 4afb921f..f7c43419 100644 --- a/config/default/manager_gardener_secret_patch.yaml +++ b/config/default/manager_gardener_secret_patch.yaml @@ -17,10 +17,11 @@ spec: - name: manager command: - /manager + imagePullPolicy: Always args: - --gardener-kubeconfig-path=/gardener/credentials/kubeconfig - - --gardener-project-name=kyma-dev - - --kubeconfig-expiration-time=24h + - --gardener-project-name=frog-dev + - --kubeconfig-expiration-time=10m volumeMounts: - name: gardener-kubeconfig mountPath: /gardener/credentials diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 8af8ea33..59955890 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -4,5 +4,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: infrastructure-manager - newTag: 0.0.1 + newName: europe-docker.pkg.dev/kyma-project/dev/infrastructure-manager + newTag: PR-49 diff --git a/config/samples/clusterinventory_v1_gardenercluster.yaml b/config/samples/infrastructuremanager_v1_gardenercluster.yaml similarity index 68% rename from config/samples/clusterinventory_v1_gardenercluster.yaml rename to config/samples/infrastructuremanager_v1_gardenercluster.yaml index a699ef82..b1aa8592 100644 --- a/config/samples/clusterinventory_v1_gardenercluster.yaml +++ b/config/samples/infrastructuremanager_v1_gardenercluster.yaml @@ -3,21 +3,21 @@ kind: GardenerCluster metadata: labels: kyma-project.io/instance-id: instance-id - kyma-project.io/runtime-id: runtime-id + kyma-project.io/runtime-id: md-id kyma-project.io/broker-plan-id: plan-id kyma-project.io/broker-plan-name: plan-name - kyma-project.io/global-account-id: global-account-id + kyma-project.io/global-account-id: global-account-i kyma-project.io/subaccount-id: subAccount-id - kyma-project.io/shoot-name: shoot-name + kyma-project.io/shoot-name: md-im kyma-project.io/region: region operator.kyma-project.io/kyma-name: kymaName - name: runtime-id + name: md-id namespace: kcp-system spec: shoot: - name: shoot-name + name: md-im kubeconfig: secret: - name: kubeconfig-runtime-id + name: kubeconfig-md-im namespace: kcp-system key: "config" diff --git a/internal/controller/gardener_cluster_controller.go b/internal/controller/gardener_cluster_controller.go index e9b8c96f..1ed42bb7 100644 --- a/internal/controller/gardener_cluster_controller.go +++ b/internal/controller/gardener_cluster_controller.go @@ -80,7 +80,10 @@ func (r *GardenerClusterController) Reconcile(ctx context.Context, req ctrl.Requ err := r.Client.Get(ctx, req.NamespacedName, &cluster) if err != nil { + cluster.UpdateState(infrastructuremanagerv1.ErrorState, infrastructuremanagerv1.ConditionReasonGardenClusterNotRetrieved, "Couldn't retrieve the Garden Cluster CR") + if k8serrors.IsNotFound(err) { + cluster.UpdateState(infrastructuremanagerv1.DeletingState, infrastructuremanagerv1.ConditionReasonGardenClusterNotFound, "CR not found, secret will be deleted") err = r.deleteSecret(req.NamespacedName.Name) if err != nil { r.log.Error(err, "failed to delete secret") @@ -95,7 +98,10 @@ func (r *GardenerClusterController) Reconcile(ctx context.Context, req ctrl.Requ secret, err := r.getSecret(cluster.Spec.Shoot.Name) if err != nil { + r.log.Error(err, "could not get the Secret for "+cluster.Spec.Shoot.Name) + cluster.UpdateState(infrastructuremanagerv1.ErrorState, infrastructuremanagerv1.ConditionReasonSecretNotFound, "Secret not found, and will be created") if !k8serrors.IsNotFound(err) { + return ctrl.Result{ Requeue: true, RequeueAfter: defaultRequeuInSeconds, @@ -104,12 +110,16 @@ func (r *GardenerClusterController) Reconcile(ctx context.Context, req ctrl.Requ } if secret == nil { + r.log.Error(err, "Secret not found, and will be created") + cluster.UpdateState(infrastructuremanagerv1.ErrorState, infrastructuremanagerv1.ConditionReasonSecretNotFound, "Secret not found, and will be created") err = r.createSecret(ctx, cluster) if err != nil { return r.ResultWithoutRequeue(), err } + } + cluster.UpdateState(infrastructuremanagerv1.ConditionReasonSecretCreated, infrastructuremanagerv1.ReadyState, "GardenCluster is ready") return ctrl.Result{}, nil }