Skip to content

Commit 8857d1c

Browse files
committed
Add .status.phase to RootShards
On-behalf-of: SAP <[email protected]> Signed-off-by: Marvin Beckers <[email protected]>
1 parent 49432da commit 8857d1c

File tree

7 files changed

+148
-76
lines changed

7 files changed

+148
-76
lines changed

api/v1alpha1/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ type ImageSpec struct {
4949

5050
type RootShardConfig struct {
5151
// Reference references a local RootShard object.
52-
Reference *corev1.ObjectReference `json:"ref,omitempty"`
52+
Reference *corev1.LocalObjectReference `json:"ref,omitempty"`
5353
}
5454

5555
type EtcdConfig struct {

api/v1alpha1/rootshard_types.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,29 @@ type OIDCConfiguration struct {
8484

8585
// RootShardStatus defines the observed state of RootShard
8686
type RootShardStatus struct {
87-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
88-
// Important: Run "make" to regenerate code after modifying this file
87+
Phase RootShardPhase `json:"phase,omitempty"`
88+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
8989
}
9090

91+
type RootShardPhase string
92+
93+
const (
94+
RootShardPhaseProvisioning RootShardPhase = "Provisioning"
95+
RootShardPhaseRunning RootShardPhase = "Running"
96+
RootShardPhaseDeleting RootShardPhase = "Deleting"
97+
)
98+
99+
type RootShardConditionType string
100+
101+
const (
102+
RootShardConditionTypeAvailable RootShardConditionType = "Available"
103+
)
104+
91105
// +kubebuilder:object:root=true
92106
// +kubebuilder:subresource:status
107+
// +kubebuilder:printcolumn:JSONPath=".spec.external.hostname",name="Hostname",type="string"
108+
// +kubebuilder:printcolumn:JSONPath=".status.phase",name="Phase",type="string"
109+
// +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",name="Age",type="date"
93110

94111
// RootShard is the Schema for the kcpinstances API
95112
type RootShard struct {

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/operator.kcp.io_frontproxies.yaml

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -98,44 +98,15 @@ spec:
9898
ref:
9999
description: Reference references a local RootShard object.
100100
properties:
101-
apiVersion:
102-
description: API version of the referent.
103-
type: string
104-
fieldPath:
105-
description: |-
106-
If referring to a piece of an object instead of an entire object, this string
107-
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
108-
For example, if the object reference is to a container within a pod, this would take on a value like:
109-
"spec.containers{name}" (where "name" refers to the name of the container that triggered
110-
the event) or if no container name is specified "spec.containers[2]" (container with
111-
index 2 in this pod). This syntax is chosen only to have some well-defined way of
112-
referencing a part of an object.
113-
type: string
114-
kind:
115-
description: |-
116-
Kind of the referent.
117-
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
118-
type: string
119101
name:
102+
default: ""
120103
description: |-
121104
Name of the referent.
105+
This field is effectively required, but due to backwards compatibility is
106+
allowed to be empty. Instances of this type with an empty value here are
107+
almost certainly wrong.
122108
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
123109
type: string
124-
namespace:
125-
description: |-
126-
Namespace of the referent.
127-
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
128-
type: string
129-
resourceVersion:
130-
description: |-
131-
Specific resourceVersion to which this reference is made, if any.
132-
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
133-
type: string
134-
uid:
135-
description: |-
136-
UID of the referent.
137-
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
138-
type: string
139110
type: object
140111
x-kubernetes-map-type: atomic
141112
type: object

config/crd/bases/operator.kcp.io_rootshards.yaml

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,17 @@ spec:
1414
singular: rootshard
1515
scope: Namespaced
1616
versions:
17-
- name: v1alpha1
17+
- additionalPrinterColumns:
18+
- jsonPath: .spec.external.hostname
19+
name: Hostname
20+
type: string
21+
- jsonPath: .status.phase
22+
name: Phase
23+
type: string
24+
- jsonPath: .metadata.creationTimestamp
25+
name: Age
26+
type: date
27+
name: v1alpha1
1828
schema:
1929
openAPIV3Schema:
2030
description: RootShard is the Schema for the kcpinstances API
@@ -188,6 +198,65 @@ spec:
188198
type: object
189199
status:
190200
description: RootShardStatus defines the observed state of RootShard
201+
properties:
202+
conditions:
203+
items:
204+
description: Condition contains details for one aspect of the current
205+
state of this API Resource.
206+
properties:
207+
lastTransitionTime:
208+
description: |-
209+
lastTransitionTime is the last time the condition transitioned from one status to another.
210+
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
211+
format: date-time
212+
type: string
213+
message:
214+
description: |-
215+
message is a human readable message indicating details about the transition.
216+
This may be an empty string.
217+
maxLength: 32768
218+
type: string
219+
observedGeneration:
220+
description: |-
221+
observedGeneration represents the .metadata.generation that the condition was set based upon.
222+
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
223+
with respect to the current state of the instance.
224+
format: int64
225+
minimum: 0
226+
type: integer
227+
reason:
228+
description: |-
229+
reason contains a programmatic identifier indicating the reason for the condition's last transition.
230+
Producers of specific condition types may define expected values and meanings for this field,
231+
and whether the values are considered a guaranteed API.
232+
The value should be a CamelCase string.
233+
This field may not be empty.
234+
maxLength: 1024
235+
minLength: 1
236+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
237+
type: string
238+
status:
239+
description: status of the condition, one of True, False, Unknown.
240+
enum:
241+
- "True"
242+
- "False"
243+
- Unknown
244+
type: string
245+
type:
246+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
247+
maxLength: 316
248+
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])$
249+
type: string
250+
required:
251+
- lastTransitionTime
252+
- message
253+
- reason
254+
- status
255+
- type
256+
type: object
257+
type: array
258+
phase:
259+
type: string
191260
type: object
192261
type: object
193262
served: true

config/crd/bases/operator.kcp.io_shards.yaml

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -120,44 +120,15 @@ spec:
120120
ref:
121121
description: Reference references a local RootShard object.
122122
properties:
123-
apiVersion:
124-
description: API version of the referent.
125-
type: string
126-
fieldPath:
127-
description: |-
128-
If referring to a piece of an object instead of an entire object, this string
129-
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
130-
For example, if the object reference is to a container within a pod, this would take on a value like:
131-
"spec.containers{name}" (where "name" refers to the name of the container that triggered
132-
the event) or if no container name is specified "spec.containers[2]" (container with
133-
index 2 in this pod). This syntax is chosen only to have some well-defined way of
134-
referencing a part of an object.
135-
type: string
136-
kind:
137-
description: |-
138-
Kind of the referent.
139-
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
140-
type: string
141123
name:
124+
default: ""
142125
description: |-
143126
Name of the referent.
127+
This field is effectively required, but due to backwards compatibility is
128+
allowed to be empty. Instances of this type with an empty value here are
129+
almost certainly wrong.
144130
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
145131
type: string
146-
namespace:
147-
description: |-
148-
Namespace of the referent.
149-
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
150-
type: string
151-
resourceVersion:
152-
description: |-
153-
Specific resourceVersion to which this reference is made, if any.
154-
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
155-
type: string
156-
uid:
157-
description: |-
158-
UID of the referent.
159-
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
160-
type: string
161132
type: object
162133
x-kubernetes-map-type: atomic
163134
type: object

internal/controller/rootshard_controller.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ import (
2222

2323
k8creconciling "k8c.io/reconciler/pkg/reconciling"
2424

25+
appsv1 "k8s.io/api/apps/v1"
26+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2527
"k8s.io/apimachinery/pkg/runtime"
28+
"k8s.io/apimachinery/pkg/types"
29+
"k8s.io/utils/ptr"
2630
ctrl "sigs.k8s.io/controller-runtime"
2731
"sigs.k8s.io/controller-runtime/pkg/client"
2832
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -65,6 +69,22 @@ func (r *RootShardReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
6569
return ctrl.Result{}, fmt.Errorf("failed to find %s/%s: %w", req.Namespace, req.Name, err)
6670
}
6771

72+
if rootShard.DeletionTimestamp != nil {
73+
rootShard.Status.Phase = operatorkcpiov1alpha1.RootShardPhaseDeleting
74+
if err := r.Client.Status().Update(ctx, &rootShard); err != nil {
75+
return ctrl.Result{}, err
76+
}
77+
}
78+
79+
if rootShard.Status.Phase == "" {
80+
rootShard.Status.Phase = operatorkcpiov1alpha1.RootShardPhaseProvisioning
81+
if err := r.Client.Status().Update(ctx, &rootShard); err != nil {
82+
return ctrl.Result{}, err
83+
}
84+
}
85+
86+
ownerRefWrapper := k8creconciling.OwnerRefWrapper(*metav1.NewControllerRef(&rootShard, operatorkcpiov1alpha1.GroupVersion.WithKind(rootShard.Kind)))
87+
6888
// Intermediate CAs that we need to generate a certificate and an issuer for.
6989
intermediateCAs := []v1alpha1.CA{
7090
v1alpha1.ServerCA,
@@ -91,32 +111,48 @@ func (r *RootShardReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
91111
certReconcilers = append(certReconcilers, rootshard.RootCACertificateReconciler(&rootShard))
92112
}
93113

94-
if err := reconciling.ReconcileCertificates(ctx, certReconcilers, req.Namespace, r.Client); err != nil {
114+
if err := reconciling.ReconcileCertificates(ctx, certReconcilers, req.Namespace, r.Client, ownerRefWrapper); err != nil {
95115
return ctrl.Result{}, err
96116
}
97117

98-
if err := reconciling.ReconcileIssuers(ctx, issuerReconcilers, req.Namespace, r.Client); err != nil {
118+
if err := reconciling.ReconcileIssuers(ctx, issuerReconcilers, req.Namespace, r.Client, ownerRefWrapper); err != nil {
99119
return ctrl.Result{}, err
100120
}
101121

102122
if err := k8creconciling.ReconcileDeployments(ctx, []k8creconciling.NamedDeploymentReconcilerFactory{
103123
rootshard.DeploymentReconciler(&rootShard),
104-
}, req.Namespace, r.Client); err != nil {
124+
}, req.Namespace, r.Client, ownerRefWrapper); err != nil {
105125
return ctrl.Result{}, err
106126
}
107127

108128
if err := k8creconciling.ReconcileServices(ctx, []k8creconciling.NamedServiceReconcilerFactory{
109129
rootshard.ServiceReconciler(&rootShard),
110-
}, req.Namespace, r.Client); err != nil {
130+
}, req.Namespace, r.Client, ownerRefWrapper); err != nil {
111131
return ctrl.Result{}, err
112132
}
113133

134+
// check for Deployment health and update the rootShard phase if necessary.
135+
var dep appsv1.Deployment
136+
err := r.Client.Get(ctx, types.NamespacedName{Namespace: req.Namespace, Name: fmt.Sprintf("%s-kcp", rootShard.Name)}, &dep)
137+
if client.IgnoreNotFound(err) != nil {
138+
return ctrl.Result{}, err
139+
}
140+
if err == nil {
141+
if rootShard.Status.Phase == operatorkcpiov1alpha1.RootShardPhaseProvisioning && dep.Status.ReadyReplicas == ptr.Deref(dep.Spec.Replicas, 0) {
142+
rootShard.Status.Phase = operatorkcpiov1alpha1.RootShardPhaseRunning
143+
if err := r.Client.Status().Update(ctx, &rootShard); err != nil {
144+
return ctrl.Result{}, err
145+
}
146+
}
147+
}
148+
114149
return ctrl.Result{}, nil
115150
}
116151

117152
// SetupWithManager sets up the controller with the Manager.
118153
func (r *RootShardReconciler) SetupWithManager(mgr ctrl.Manager) error {
119154
return ctrl.NewControllerManagedBy(mgr).
120155
For(&operatorkcpiov1alpha1.RootShard{}).
156+
Owns(&appsv1.Deployment{}).
121157
Complete(r)
122158
}

0 commit comments

Comments
 (0)