From 5b9a1ffa0798037f2863433838ed6a02e9cb178a Mon Sep 17 00:00:00 2001 From: jkhelil Date: Thu, 12 Aug 2021 16:08:56 +0200 Subject: [PATCH] add shipwright build status --- api/v1alpha1/shipwrightbuild_types.go | 7 +- api/v1alpha1/zz_generated.deepcopy.go | 10 ++- ...erator.shipwright.io_shipwrightbuilds.yaml | 74 ++++++++++++++++++- controllers/shipwrightbuild_controller.go | 35 +++++++++ go.sum | 4 - 5 files changed, 122 insertions(+), 8 deletions(-) diff --git a/api/v1alpha1/shipwrightbuild_types.go b/api/v1alpha1/shipwrightbuild_types.go index 8c7eb62e..a64b9fef 100644 --- a/api/v1alpha1/shipwrightbuild_types.go +++ b/api/v1alpha1/shipwrightbuild_types.go @@ -14,8 +14,11 @@ type ShipwrightBuildSpec struct { TargetNamespace string `json:"targetNamespace,omitempty"` } -// ShipwrightBuildStatus defines the observed state of Shipwright-Build -type ShipwrightBuildStatus struct{} +// ShipwrightBuildStatus defines the observed state of ShipwrightBuild +type ShipwrightBuildStatus struct { + // Conditions holds the latest available observations of a resource's current state. + Conditions []metav1.Condition `json:"conditions,omitempty"` +} // +kubebuilder:object:root=true // +kubebuilder:resource:scope=Cluster diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index d41abef5..612c48eb 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -9,6 +9,7 @@ package v1alpha1 import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -18,7 +19,7 @@ func (in *ShipwrightBuild) DeepCopyInto(out *ShipwrightBuild) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) out.Spec = in.Spec - out.Status = in.Status + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShipwrightBuild. @@ -89,6 +90,13 @@ func (in *ShipwrightBuildSpec) DeepCopy() *ShipwrightBuildSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ShipwrightBuildStatus) DeepCopyInto(out *ShipwrightBuildStatus) { *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShipwrightBuildStatus. diff --git a/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml b/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml index 781c5f61..262c0841 100644 --- a/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml +++ b/config/crd/bases/operator.shipwright.io_shipwrightbuilds.yaml @@ -44,7 +44,79 @@ spec: type: string type: object status: - description: ShipwrightBuildStatus defines the observed state of Shipwright-Build + description: ShipwrightBuildStatus defines the observed state of ShipwrightBuild + properties: + conditions: + description: Conditions holds the latest available observations of + a resource's current state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: + \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // +listMapKey=type + \ Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array type: object type: object served: true diff --git a/controllers/shipwrightbuild_controller.go b/controllers/shipwrightbuild_controller.go index a787700b..705145f3 100644 --- a/controllers/shipwrightbuild_controller.go +++ b/controllers/shipwrightbuild_controller.go @@ -13,6 +13,8 @@ import ( mfc "github.com/manifestival/controller-runtime-client" "github.com/manifestival/manifestival" "k8s.io/apimachinery/pkg/api/errors" + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -28,6 +30,9 @@ const ( FinalizerAnnotation = "finalizer.operator.shipwright.io" // defaultTargetNamespace fallback namespace when `.spec.namepace` is not informed. defaultTargetNamespace = "shipwright-build" + + // Ready object is providing service. + ConditionReady = "Ready" ) // ShipwrightBuildReconciler reconciles a ShipwrightBuild object @@ -79,6 +84,19 @@ func (r *ShipwrightBuildReconciler) Reconcile(ctx context.Context, req ctrl.Requ logger.Error(err, "Retrieving ShipwrightBuild object from cache") return RequeueOnError(err) } + init := b.Status.Conditions == nil + if init { + b.Status.Conditions = make([]metav1.Condition, 0) + apimeta.SetStatusCondition(&b.Status.Conditions, metav1.Condition{ + Type: ConditionReady, + Status: metav1.ConditionUnknown, // we just started trying to reconcile + Reason: "Init", + Message: "Initializing Shipwright Operator", + }) + if err := r.Client.Status().Update(ctx, b); err != nil { + return RequeueWithError(err) + } + } // selecting the target namespace based on the CRD information, when not informed using the // default namespace instead @@ -131,6 +149,13 @@ func (r *ShipwrightBuildReconciler) Reconcile(ctx context.Context, req ctrl.Requ logger.Info("Applying manifest's resources...") if err := manifest.Apply(); err != nil { logger.Error(err, "Rolling out manifest's resources") + apimeta.SetStatusCondition(&b.Status.Conditions, metav1.Condition{ + Type: ConditionReady, + Status: metav1.ConditionFalse, + Reason: "Failed", + Message: fmt.Sprintf("Reconciling ShipwrightBuild failed: %v", err), + }) + r.Client.Status().Update(ctx, b) return RequeueWithError(err) } if err := r.setFinalizer(ctx, b); err != nil { @@ -138,6 +163,16 @@ func (r *ShipwrightBuildReconciler) Reconcile(ctx context.Context, req ctrl.Requ logger.Error(err, "Setting the finalizer") return RequeueWithError(err) } + apimeta.SetStatusCondition(&b.Status.Conditions, metav1.Condition{ + Type: ConditionReady, + Status: metav1.ConditionTrue, + Reason: "Success", + Message: "Reconciled ShipwrightBuild successfully", + }) + if err := r.Client.Status().Update(ctx, b); err != nil { + logger.Error(err, "Updating ShipwrightBuild status") + RequeueWithError(err) + } logger.Info("All done!") return NoRequeue() } diff --git a/go.sum b/go.sum index 18564d9e..ef95f90c 100644 --- a/go.sum +++ b/go.sum @@ -98,7 +98,6 @@ github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6 github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.0.0 h1:dKTrUeykyQwKb/kx7Z+4ukDs6l+4L41HqG1XHnhX7WE= github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/evanphx/json-patch/v5 v5.2.0 h1:8ozOH5xxoMYDt5/u+yMTsVXydVCbTORFnOOoq2lumco= github.com/evanphx/json-patch/v5 v5.2.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= @@ -117,7 +116,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.3.0 h1:q4c+kbcR0d5rSurhBR8dIgieOaYpXtsdTYfx22Cu6rs= github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= @@ -274,7 +272,6 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/manifestival/controller-runtime-client v0.4.0 h1:AK+nTZ1rhPTfAc3upnSe3TiOvAWuRmxi1vjEr55dSUM= github.com/manifestival/controller-runtime-client v0.4.0/go.mod h1:DrsviSegfdlpVsynTUZonKE5gFkMQupenlzVmDbC6S0= -github.com/manifestival/manifestival v0.6.0 h1:eA5ZR+ce4u74oBjtR9x5QWc9qQZdQgUmq8gfVxYtwq4= github.com/manifestival/manifestival v0.6.0/go.mod h1:3Qq9cnPy7sv7FVhg2Kvw0ebb35R4OdctS4UjTjHlHm4= github.com/manifestival/manifestival v0.7.0 h1:8JC8CUCmjCst9mQUivrhW+TWu4JsptNrXK99ee23acA= github.com/manifestival/manifestival v0.7.0/go.mod h1:yn71DeI/zZKgYZmbu6mvliEWo4175gmz3ihK8ZmXfhI= @@ -641,7 +638,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/api v0.15.7/go.mod h1:a/tUxscL+UxvYyA7Tj5DRc8ivYqJIO1Y5KDdlI6wSvo= -k8s.io/api v0.19.2 h1:q+/krnHWKsL7OBZg/rxnycsl9569Pud76UJ77MvKXms= k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= k8s.io/api v0.19.7 h1:MpHhls03C2pyzoYcpbe4QqYiiZjdvW+tuWq6TbjV14Y= k8s.io/api v0.19.7/go.mod h1:KTryDUT3l6Mtv7K2J2486PNL9DBns3wOYTkGR+iz63Y=