mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-22 07:28:06 +00:00
Merge pull request #118 from 1Password/item-status
Add Status field to OnePasswordItem resource
This commit is contained in:
@@ -12,8 +12,6 @@ spec:
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: OnePasswordItem is the Schema for the onepassworditems API
|
||||
@@ -38,8 +36,41 @@ spec:
|
||||
type: object
|
||||
status:
|
||||
description: OnePasswordItemStatus defines the observed state of OnePasswordItem
|
||||
properties:
|
||||
conditions:
|
||||
description: 'Important: Run "operator-sdk generate k8s" to regenerate
|
||||
code after modifying this file Add custom validation using kubebuilder
|
||||
tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
|
||||
items:
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: Last time the condition transit from one status
|
||||
to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: Human-readable message indicating details about
|
||||
last transition.
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
type:
|
||||
description: Type of job condition, Completed.
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- conditions
|
||||
type: object
|
||||
type:
|
||||
description: 'Kubernetes secret type. More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types'
|
||||
type: string
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
@@ -11,11 +11,31 @@ type OnePasswordItemSpec struct {
|
||||
ItemPath string `json:"itemPath,omitempty"`
|
||||
}
|
||||
|
||||
type OnePasswordItemConditionType string
|
||||
|
||||
const (
|
||||
// OnePasswordItemReady means the Kubernetes secret is ready for use.
|
||||
OnePasswordItemReady OnePasswordItemConditionType = "Ready"
|
||||
)
|
||||
|
||||
type OnePasswordItemCondition struct {
|
||||
// Type of job condition, Completed.
|
||||
Type OnePasswordItemConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status metav1.ConditionStatus `json:"status"`
|
||||
// Last time the condition transit from one status to another.
|
||||
// +optional
|
||||
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
// Human-readable message indicating details about last transition.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// OnePasswordItemStatus defines the observed state of OnePasswordItem
|
||||
type OnePasswordItemStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
|
||||
// Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html
|
||||
Conditions []OnePasswordItemCondition `json:"conditions"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@@ -26,6 +46,8 @@ type OnePasswordItemStatus struct {
|
||||
type OnePasswordItem struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Kubernetes secret type. More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
Spec OnePasswordItemSpec `json:"spec,omitempty"`
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Code generated by operator-sdk. DO NOT EDIT.
|
||||
@@ -14,7 +15,7 @@ func (in *OnePasswordItem) DeepCopyInto(out *OnePasswordItem) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -36,6 +37,23 @@ func (in *OnePasswordItem) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OnePasswordItemCondition) DeepCopyInto(out *OnePasswordItemCondition) {
|
||||
*out = *in
|
||||
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OnePasswordItemCondition.
|
||||
func (in *OnePasswordItemCondition) DeepCopy() *OnePasswordItemCondition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OnePasswordItemCondition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OnePasswordItemList) DeepCopyInto(out *OnePasswordItemList) {
|
||||
*out = *in
|
||||
@@ -88,6 +106,13 @@ func (in *OnePasswordItemSpec) DeepCopy() *OnePasswordItemSpec {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OnePasswordItemStatus) DeepCopyInto(out *OnePasswordItemStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]OnePasswordItemCondition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -96,10 +96,11 @@ func (r *ReconcileOnePasswordItem) Reconcile(request reconcile.Request) (reconci
|
||||
}
|
||||
|
||||
// Handles creation or updating secrets for deployment if needed
|
||||
if err := r.HandleOnePasswordItem(onepassworditem, request); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
err := r.HandleOnePasswordItem(onepassworditem, request)
|
||||
if updateStatusErr := r.updateStatus(onepassworditem, err); updateStatusErr != nil {
|
||||
return reconcile.Result{}, fmt.Errorf("cannot update status: %s", updateStatusErr)
|
||||
}
|
||||
return reconcile.Result{}, nil
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
// If one password finalizer exists then we must cleanup associated secrets
|
||||
if utils.ContainsString(onepassworditem.ObjectMeta.Finalizers, finalizer) {
|
||||
@@ -169,3 +170,34 @@ func (r *ReconcileOnePasswordItem) HandleOnePasswordItem(resource *onepasswordv1
|
||||
|
||||
return kubeSecrets.CreateKubernetesSecretFromItem(r.kubeClient, secretName, resource.Namespace, item, autoRestart, labels, secretType, ownerRef)
|
||||
}
|
||||
|
||||
func (r *ReconcileOnePasswordItem) updateStatus(resource *onepasswordv1.OnePasswordItem, err error) error {
|
||||
existingCondition := findCondition(resource.Status.Conditions, onepasswordv1.OnePasswordItemReady)
|
||||
updatedCondition := existingCondition
|
||||
if err != nil {
|
||||
updatedCondition.Message = err.Error()
|
||||
updatedCondition.Status = metav1.ConditionFalse
|
||||
} else {
|
||||
updatedCondition.Message = ""
|
||||
updatedCondition.Status = metav1.ConditionTrue
|
||||
}
|
||||
|
||||
if existingCondition.Status != updatedCondition.Status {
|
||||
updatedCondition.LastTransitionTime = metav1.Now()
|
||||
}
|
||||
|
||||
resource.Status.Conditions = []onepasswordv1.OnePasswordItemCondition{updatedCondition}
|
||||
return r.kubeClient.Status().Update(context.Background(), resource)
|
||||
}
|
||||
|
||||
func findCondition(conditions []onepasswordv1.OnePasswordItemCondition, t onepasswordv1.OnePasswordItemConditionType) onepasswordv1.OnePasswordItemCondition {
|
||||
for _, c := range conditions {
|
||||
if c.Type == t {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return onepasswordv1.OnePasswordItemCondition{
|
||||
Type: t,
|
||||
Status: metav1.ConditionUnknown,
|
||||
}
|
||||
}
|
||||
|
@@ -44,8 +44,7 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa
|
||||
if autoRestart != "" {
|
||||
_, err := utils.StringToBool(autoRestart)
|
||||
if err != nil {
|
||||
log.Error(err, "Error parsing %v annotation on Secret %v. Must be true or false. Defaulting to false.", RestartDeploymentsAnnotation, secretName)
|
||||
return err
|
||||
return fmt.Errorf("Error parsing %v annotation on Secret %v. Must be true or false. Defaulting to false.", RestartDeploymentsAnnotation, secretName)
|
||||
}
|
||||
secretAnnotations[RestartDeploymentsAnnotation] = autoRestart
|
||||
}
|
||||
@@ -83,7 +82,10 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa
|
||||
currentSecret.ObjectMeta.Annotations = secretAnnotations
|
||||
currentSecret.ObjectMeta.Labels = labels
|
||||
currentSecret.Data = secret.Data
|
||||
return kubeClient.Update(context.Background(), currentSecret)
|
||||
if err := kubeClient.Update(context.Background(), currentSecret); err != nil {
|
||||
return fmt.Errorf("Kubernetes secret update failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info(fmt.Sprintf("Secret with name %v and version %v already exists", secret.Name, secret.Annotations[VersionAnnotation]))
|
||||
|
Reference in New Issue
Block a user