From 9a45b9266555b472e1ee8d3223dce966010d82f4 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 18 May 2023 10:25:34 -0700 Subject: [PATCH 01/54] wip --- api/v1alpha1/humiobootstraptoken_types.go | 94 ++++++++ api/v1alpha1/zz_generated.deepcopy.go | 226 ++++++++---------- .../core.humio.com_humiobootstraptokens.yaml | 179 ++++++++++++++ .../core.humio.com_humiobootstraptokens.yaml | 179 ++++++++++++++ config/crd/kustomization.yaml | 1 + config/manager/kustomization.yaml | 6 + .../humio-operator.clusterserviceversion.yaml | 80 +++++++ config/rbac/role.yaml | 26 ++ controllers/humiobootstraptoken_controller.go | 178 ++++++++++++++ controllers/humiobootstraptoken_defaults.go | 59 +++++ controllers/humiobootstraptoken_pods.go | 63 +++++ 11 files changed, 960 insertions(+), 131 deletions(-) create mode 100644 api/v1alpha1/humiobootstraptoken_types.go create mode 100644 charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml create mode 100644 config/crd/bases/core.humio.com_humiobootstraptokens.yaml create mode 100644 config/manifests/bases/humio-operator.clusterserviceversion.yaml create mode 100644 controllers/humiobootstraptoken_controller.go create mode 100644 controllers/humiobootstraptoken_defaults.go create mode 100644 controllers/humiobootstraptoken_pods.go diff --git a/api/v1alpha1/humiobootstraptoken_types.go b/api/v1alpha1/humiobootstraptoken_types.go new file mode 100644 index 00000000..2ba65e27 --- /dev/null +++ b/api/v1alpha1/humiobootstraptoken_types.go @@ -0,0 +1,94 @@ +/* +Copyright 2020 Humio https://humio.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( +// HumioExternalClusterStateUnknown is the Unknown state of the external cluster +//HumioExternalClusterStateUnknown = "Unknown" +// HumioExternalClusterStateReady is the Ready state of the external cluster +//HumioExternalClusterStateReady = "Ready" +) + +// HumioBootstrapTokenSpec defines the bootstrap token that Humio will use to bootstrap authentication +type HumioBootstrapTokenSpec struct { + // ManagedClusterName + ManagedClusterName string `json:"managedClusterName,omitempty"` + // ExternalClusterName refers to an object of type HumioExternalCluster where the Humio resources should be created. + // This conflicts with ManagedClusterName. + ExternalClusterName string `json:"externalClusterName,omitempty"` + + Image string `json:"image,omitempty"` + TokenSecret HumioTokenSecretSpec `json:"tokenSecret,omitempty"` + HashedTokenSecret HumioHashedTokenSecretSpec `json:"hashedTokenSecret,omitempty"` +} + +type HumioTokenSecretSpec struct { + CreateIfMissing bool `json:"createIfMissing"` + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` +} + +type HumioHashedTokenSecretSpec struct { + CreateIfMissing bool `json:"createIfMissing"` + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` +} + +type HumioBootstrapTokenStatus struct { + Created bool `json:"created,omitempty"` + TokenSecretKeyRef HumioTokenSecretStatus `json:"tokenSecretStatus,omitempty"` + HashedTokenSecretKeyRef HumioHashedTokenSecretStatus `json:"hashedTokenSecretStatus,omitempty"` +} + +type HumioTokenSecretStatus struct { + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` +} + +type HumioHashedTokenSecretStatus struct { + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:path=humiobootstraptokens,scope=Namespaced +//+kubebuilder:printcolumn:name="State",type="string",JSONPath=".status.state",description="The state of the bootstrap token" +//+operator-sdk:gen-csv:customresourcedefinitions.displayName="Humio Bootstrap Token" + +// HumioBootstrapToken defines the bootstrap token that Humio will use to bootstrap authentication +type HumioBootstrapToken struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec HumioBootstrapTokenSpec `json:"spec,omitempty"` + Status HumioBootstrapTokenStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// HumioBootstrapTokenList contains a list of HumioBootstrapTokens +type HumioBootstrapTokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []HumioBootstrapToken `json:"items"` +} + +func init() { + SchemeBuilder.Register(&HumioBootstrapToken{}, &HumioBootstrapTokenList{}) +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index ba56c5f6..6d51b33d 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -336,7 +336,7 @@ func (in *HumioActionWebhookProperties) DeepCopy() *HumioActionWebhookProperties } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAggregateAlert) DeepCopyInto(out *HumioAggregateAlert) { +func (in *HumioAlert) DeepCopyInto(out *HumioAlert) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -344,18 +344,18 @@ func (in *HumioAggregateAlert) DeepCopyInto(out *HumioAggregateAlert) { out.Status = in.Status } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlert. -func (in *HumioAggregateAlert) DeepCopy() *HumioAggregateAlert { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlert. +func (in *HumioAlert) DeepCopy() *HumioAlert { if in == nil { return nil } - out := new(HumioAggregateAlert) + out := new(HumioAlert) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HumioAggregateAlert) DeepCopyObject() runtime.Object { +func (in *HumioAlert) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -363,31 +363,31 @@ func (in *HumioAggregateAlert) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAggregateAlertList) DeepCopyInto(out *HumioAggregateAlertList) { +func (in *HumioAlertList) DeepCopyInto(out *HumioAlertList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]HumioAggregateAlert, len(*in)) + *out = make([]HumioAlert, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlertList. -func (in *HumioAggregateAlertList) DeepCopy() *HumioAggregateAlertList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlertList. +func (in *HumioAlertList) DeepCopy() *HumioAlertList { if in == nil { return nil } - out := new(HumioAggregateAlertList) + out := new(HumioAlertList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HumioAggregateAlertList) DeepCopyObject() runtime.Object { +func (in *HumioAlertList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -395,8 +395,9 @@ func (in *HumioAggregateAlertList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAggregateAlertSpec) DeepCopyInto(out *HumioAggregateAlertSpec) { +func (in *HumioAlertSpec) DeepCopyInto(out *HumioAlertSpec) { *out = *in + in.Query.DeepCopyInto(&out.Query) if in.Actions != nil { in, out := &in.Actions, &out.Actions *out = make([]string, len(*in)) @@ -409,52 +410,52 @@ func (in *HumioAggregateAlertSpec) DeepCopyInto(out *HumioAggregateAlertSpec) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlertSpec. -func (in *HumioAggregateAlertSpec) DeepCopy() *HumioAggregateAlertSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlertSpec. +func (in *HumioAlertSpec) DeepCopy() *HumioAlertSpec { if in == nil { return nil } - out := new(HumioAggregateAlertSpec) + out := new(HumioAlertSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAggregateAlertStatus) DeepCopyInto(out *HumioAggregateAlertStatus) { +func (in *HumioAlertStatus) DeepCopyInto(out *HumioAlertStatus) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlertStatus. -func (in *HumioAggregateAlertStatus) DeepCopy() *HumioAggregateAlertStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlertStatus. +func (in *HumioAlertStatus) DeepCopy() *HumioAlertStatus { if in == nil { return nil } - out := new(HumioAggregateAlertStatus) + out := new(HumioAlertStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAlert) DeepCopyInto(out *HumioAlert) { +func (in *HumioBootstrapToken) DeepCopyInto(out *HumioBootstrapToken) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlert. -func (in *HumioAlert) DeepCopy() *HumioAlert { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioBootstrapToken. +func (in *HumioBootstrapToken) DeepCopy() *HumioBootstrapToken { if in == nil { return nil } - out := new(HumioAlert) + out := new(HumioBootstrapToken) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HumioAlert) DeepCopyObject() runtime.Object { +func (in *HumioBootstrapToken) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -462,31 +463,31 @@ func (in *HumioAlert) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAlertList) DeepCopyInto(out *HumioAlertList) { +func (in *HumioBootstrapTokenList) DeepCopyInto(out *HumioBootstrapTokenList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]HumioAlert, len(*in)) + *out = make([]HumioBootstrapToken, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlertList. -func (in *HumioAlertList) DeepCopy() *HumioAlertList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioBootstrapTokenList. +func (in *HumioBootstrapTokenList) DeepCopy() *HumioBootstrapTokenList { if in == nil { return nil } - out := new(HumioAlertList) + out := new(HumioBootstrapTokenList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HumioAlertList) DeepCopyObject() runtime.Object { +func (in *HumioBootstrapTokenList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -494,42 +495,33 @@ func (in *HumioAlertList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAlertSpec) DeepCopyInto(out *HumioAlertSpec) { +func (in *HumioBootstrapTokenSpec) DeepCopyInto(out *HumioBootstrapTokenSpec) { *out = *in - in.Query.DeepCopyInto(&out.Query) - if in.Actions != nil { - in, out := &in.Actions, &out.Actions - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make([]string, len(*in)) - copy(*out, *in) - } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlertSpec. -func (in *HumioAlertSpec) DeepCopy() *HumioAlertSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioBootstrapTokenSpec. +func (in *HumioBootstrapTokenSpec) DeepCopy() *HumioBootstrapTokenSpec { if in == nil { return nil } - out := new(HumioAlertSpec) + out := new(HumioBootstrapTokenSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioAlertStatus) DeepCopyInto(out *HumioAlertStatus) { +func (in *HumioBootstrapTokenStatus) DeepCopyInto(out *HumioBootstrapTokenStatus) { *out = *in + in.TokenSecretKeyRef.DeepCopyInto(&out.TokenSecretKeyRef) + in.HashedTokenSecretKeyRef.DeepCopyInto(&out.HashedTokenSecretKeyRef) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAlertStatus. -func (in *HumioAlertStatus) DeepCopy() *HumioAlertStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioBootstrapTokenStatus. +func (in *HumioBootstrapTokenStatus) DeepCopy() *HumioBootstrapTokenStatus { if in == nil { return nil } - out := new(HumioAlertStatus) + out := new(HumioBootstrapTokenStatus) in.DeepCopyInto(out) return out } @@ -727,11 +719,6 @@ func (in *HumioClusterTLSSpec) DeepCopyInto(out *HumioClusterTLSSpec) { *out = new(bool) **out = **in } - if in.ExtraHostnames != nil { - in, out := &in.ExtraHostnames, &out.ExtraHostnames - *out = make([]string, len(*in)) - copy(*out, *in) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioClusterTLSSpec. @@ -854,6 +841,7 @@ func (in *HumioExternalClusterStatus) DeepCopy() *HumioExternalClusterStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +<<<<<<< HEAD func (in *HumioFilterAlert) DeepCopyInto(out *HumioFilterAlert) { *out = *in out.TypeMeta = in.TypeMeta @@ -933,11 +921,29 @@ func (in *HumioFilterAlertSpec) DeepCopy() *HumioFilterAlertSpec { return nil } out := new(HumioFilterAlertSpec) +======= +func (in *HumioHashedTokenSecretSpec) DeepCopyInto(out *HumioHashedTokenSecretSpec) { + *out = *in + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioHashedTokenSecretSpec. +func (in *HumioHashedTokenSecretSpec) DeepCopy() *HumioHashedTokenSecretSpec { + if in == nil { + return nil + } + out := new(HumioHashedTokenSecretSpec) +>>>>>>> d88f334 (wip) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +<<<<<<< HEAD func (in *HumioFilterAlertStatus) DeepCopyInto(out *HumioFilterAlertStatus) { *out = *in } @@ -948,6 +954,23 @@ func (in *HumioFilterAlertStatus) DeepCopy() *HumioFilterAlertStatus { return nil } out := new(HumioFilterAlertStatus) +======= +func (in *HumioHashedTokenSecretStatus) DeepCopyInto(out *HumioHashedTokenSecretStatus) { + *out = *in + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioHashedTokenSecretStatus. +func (in *HumioHashedTokenSecretStatus) DeepCopy() *HumioHashedTokenSecretStatus { + if in == nil { + return nil + } + out := new(HumioHashedTokenSecretStatus) +>>>>>>> d88f334 (wip) in.DeepCopyInto(out) return out } @@ -1611,100 +1634,41 @@ func (in *HumioRetention) DeepCopy() *HumioRetention { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioScheduledSearch) DeepCopyInto(out *HumioScheduledSearch) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearch. -func (in *HumioScheduledSearch) DeepCopy() *HumioScheduledSearch { - if in == nil { - return nil - } - out := new(HumioScheduledSearch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HumioScheduledSearch) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioScheduledSearchList) DeepCopyInto(out *HumioScheduledSearchList) { +func (in *HumioTokenSecretSpec) DeepCopyInto(out *HumioTokenSecretSpec) { *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]HumioScheduledSearch, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearchList. -func (in *HumioScheduledSearchList) DeepCopy() *HumioScheduledSearchList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioTokenSecretSpec. +func (in *HumioTokenSecretSpec) DeepCopy() *HumioTokenSecretSpec { if in == nil { return nil } - out := new(HumioScheduledSearchList) + out := new(HumioTokenSecretSpec) in.DeepCopyInto(out) return out } -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *HumioScheduledSearchList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioScheduledSearchSpec) DeepCopyInto(out *HumioScheduledSearchSpec) { +func (in *HumioTokenSecretStatus) DeepCopyInto(out *HumioTokenSecretStatus) { *out = *in - if in.Actions != nil { - in, out := &in.Actions, &out.Actions - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearchSpec. -func (in *HumioScheduledSearchSpec) DeepCopy() *HumioScheduledSearchSpec { - if in == nil { - return nil + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) } - out := new(HumioScheduledSearchSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HumioScheduledSearchStatus) DeepCopyInto(out *HumioScheduledSearchStatus) { - *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearchStatus. -func (in *HumioScheduledSearchStatus) DeepCopy() *HumioScheduledSearchStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioTokenSecretStatus. +func (in *HumioTokenSecretStatus) DeepCopy() *HumioTokenSecretStatus { if in == nil { return nil } - out := new(HumioScheduledSearchStatus) + out := new(HumioTokenSecretStatus) in.DeepCopyInto(out) return out } diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml new file mode 100644 index 00000000..87fedf45 --- /dev/null +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -0,0 +1,179 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: humiobootstraptokens.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' +spec: + group: core.humio.com + names: + kind: HumioBootstrapToken + listKind: HumioBootstrapTokenList + plural: humiobootstraptokens + singular: humiobootstraptoken + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The state of the bootstrap token + jsonPath: .status.state + name: State + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: HumioBootstrapToken defines the bootstrap token that Humio will + use to bootstrap authentication + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HumioBootstrapTokenSpec defines the bootstrap token that + Humio will use to bootstrap authentication + properties: + externalClusterName: + description: |- + ExternalClusterName refers to an object of type HumioExternalCluster where the Humio resources should be created. + This conflicts with ManagedClusterName. + type: string + hashedTokenSecret: + properties: + createIfMissing: + type: boolean + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - createIfMissing + type: object + image: + type: string + managedClusterName: + description: ManagedClusterName + type: string + tokenSecret: + properties: + createIfMissing: + type: boolean + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - createIfMissing + type: object + type: object + status: + properties: + created: + type: boolean + hashedTokenSecretStatus: + properties: + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tokenSecretStatus: + properties: + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml new file mode 100644 index 00000000..87fedf45 --- /dev/null +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -0,0 +1,179 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: humiobootstraptokens.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' +spec: + group: core.humio.com + names: + kind: HumioBootstrapToken + listKind: HumioBootstrapTokenList + plural: humiobootstraptokens + singular: humiobootstraptoken + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The state of the bootstrap token + jsonPath: .status.state + name: State + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: HumioBootstrapToken defines the bootstrap token that Humio will + use to bootstrap authentication + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HumioBootstrapTokenSpec defines the bootstrap token that + Humio will use to bootstrap authentication + properties: + externalClusterName: + description: |- + ExternalClusterName refers to an object of type HumioExternalCluster where the Humio resources should be created. + This conflicts with ManagedClusterName. + type: string + hashedTokenSecret: + properties: + createIfMissing: + type: boolean + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - createIfMissing + type: object + image: + type: string + managedClusterName: + description: ManagedClusterName + type: string + tokenSecret: + properties: + createIfMissing: + type: boolean + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - createIfMissing + type: object + type: object + status: + properties: + created: + type: boolean + hashedTokenSecretStatus: + properties: + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tokenSecretStatus: + properties: + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 7fb6e26c..fd131bb4 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -13,6 +13,7 @@ resources: - bases/core.humio.com_humiofilteralerts.yaml - bases/core.humio.com_humioscheduledsearches.yaml - bases/core.humio.com_humioaggregatealerts.yaml +- bases/core.humio.com_humiobootstraptokens.yaml # +kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 5c5f0b84..96532c80 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,2 +1,8 @@ resources: - manager.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: humio/humio-operator + newTag: latest diff --git a/config/manifests/bases/humio-operator.clusterserviceversion.yaml b/config/manifests/bases/humio-operator.clusterserviceversion.yaml new file mode 100644 index 00000000..f7695cb1 --- /dev/null +++ b/config/manifests/bases/humio-operator.clusterserviceversion.yaml @@ -0,0 +1,80 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: '[]' + capabilities: Basic Install + name: humio-operator.v0.0.0 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: HumioAction is the Schema for the humioactions API + displayName: Humio Action + kind: HumioAction + name: humioactions.core.humio.com + version: v1alpha1 + - description: HumioAlert is the Schema for the humioalerts API + displayName: Humio Alert + kind: HumioAlert + name: humioalerts.core.humio.com + version: v1alpha1 + - description: HumioCluster is the Schema for the humioclusters API + displayName: Humio Cluster + kind: HumioCluster + name: humioclusters.core.humio.com + version: v1alpha1 + - description: HumioExternalCluster is the Schema for the humioexternalclusters + API + displayName: Humio External Cluster + kind: HumioExternalCluster + name: humioexternalclusters.core.humio.com + version: v1alpha1 + - description: HumioIngestToken is the Schema for the humioingesttokens API + displayName: Humio Ingest Token + kind: HumioIngestToken + name: humioingesttokens.core.humio.com + version: v1alpha1 + - description: HumioParser is the Schema for the humioparsers API + displayName: Humio Parser + kind: HumioParser + name: humioparsers.core.humio.com + version: v1alpha1 + - description: HumioRepository is the Schema for the humiorepositories API + displayName: Humio Repository + kind: HumioRepository + name: humiorepositories.core.humio.com + version: v1alpha1 + - description: HumioView is the Schema for the humioviews API + displayName: Humio View + kind: HumioView + name: humioviews.core.humio.com + version: v1alpha1 + description: Operator for managing Humio Clusters + displayName: Humio Operator + icon: + - base64data: "" + mediatype: "" + install: + spec: + deployments: null + strategy: "" + installModes: + - supported: false + type: OwnNamespace + - supported: false + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - humio + links: + - name: Humio Operator + url: https://humio-operator.domain + maturity: alpha + provider: + name: Humio + version: 0.0.0 diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index ef45756c..a538a200 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -112,6 +112,32 @@ rules: - patch - update - watch +- apiGroups: + - core.humio.com + resources: + - HumioBootstrapTokens + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - core.humio.com + resources: + - HumioBootstrapTokens/finalizers + verbs: + - update +- apiGroups: + - core.humio.com + resources: + - HumioBootstrapTokens/status + verbs: + - get + - patch + - update - apiGroups: - core.humio.com resources: diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go new file mode 100644 index 00000000..b4554587 --- /dev/null +++ b/controllers/humiobootstraptoken_controller.go @@ -0,0 +1,178 @@ +/* +Copyright 2020 Humio https://humio.com +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "fmt" + "time" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + "github.com/humio/humio-operator/pkg/helpers" + "github.com/humio/humio-operator/pkg/kubernetes" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/go-logr/logr" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" +) + +// HumioBootstrapTokenReconciler reconciles a HumioBootstrapToken object +type HumioBootstrapTokenReconciler struct { + client.Client + BaseLogger logr.Logger + Log logr.Logger + Namespace string +} + +//+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/finalizers,verbs=update + +// Reconcile runs the reconciler for a HumioBootstrapToken object +func (r *HumioBootstrapTokenReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + if r.Namespace != "" { + if r.Namespace != req.Namespace { + return reconcile.Result{}, nil + } + } + + r.Log = r.BaseLogger.WithValues("Request.Namespace", req.Namespace, "Request.Name", req.Name, "Request.Type", helpers.GetTypeName(r), "Reconcile.ID", kubernetes.RandomString()) + r.Log.Info("Reconciling HumioBootstrapToken") + + // Fetch the HumioBootstrapToken + hbt := &humiov1alpha1.HumioBootstrapToken{} + if err := r.Get(ctx, req.NamespacedName, hbt); err != nil { + if k8serrors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + return reconcile.Result{RequeueAfter: time.Second * 60}, nil +} + +func (r *HumioBootstrapTokenReconciler) execCommand(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { + return nil +} + +func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { + existingPod := &corev1.Pod{} + humioCluster := &humiov1alpha1.HumioCluster{} + if err := r.Get(ctx, types.NamespacedName{ + Namespace: hbt.Namespace, + Name: hbt.Spec.ManagedClusterName, + }, humioCluster); err != nil { + if k8serrors.IsNotFound(err) { + humioCluster = nil + } + } + humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, humioCluster) + pod, err := ConstructBootstrapPod(&humioBootstrapTokenConfig) + if err != nil { + return r.logErrorAndReturn(err, "could not construct pod") + } + if err := r.Get(ctx, types.NamespacedName{ + Namespace: pod.Namespace, + Name: pod.Name, + }, existingPod); err != nil { + if k8serrors.IsNotFound(err) { + if err := controllerutil.SetControllerReference(hbt, pod, r.Scheme()); err != nil { + return r.logErrorAndReturn(err, "could not set controller reference") + } + if err := r.Create(ctx, pod); err != nil { + return r.logErrorAndReturn(err, "could not create pod") + } + } + } + return nil +} + +func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { + existingPod := &corev1.Pod{} + humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt) + pod, err := ConstructBootstrapPod(&humioBootstrapTokenConfig) + if err != nil { + return r.logErrorAndReturn(err, "could not construct pod") + } + if err := r.Get(ctx, types.NamespacedName{ + Namespace: pod.Namespace, + Name: pod.Name, + }, existingPod); err != nil { + if !k8serrors.IsNotFound(err) { + if err := r.Delete(ctx, pod); err != nil { + return r.logErrorAndReturn(err, "could not delete pod") + } + } + } + return nil +} + +func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { + if !hbt.Spec.TokenSecret.CreateIfMissing { + return nil + } + + existingSecret := &corev1.Secret{} + humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt) + + if err := r.Get(ctx, types.NamespacedName{ + Namespace: hbt.Namespace, + Name: humioBootstrapTokenConfig.bootstrapTokenName(), + }, existingSecret); err != nil { + if k8serrors.IsNotFound(err) { + randomPass := kubernetes.RandomString() + secretData := map[string][]byte{ + "passphrase": []byte(randomPass), + } + secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) + if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { + return r.logErrorAndReturn(err, "could not set controller reference") + } + r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) + if err := r.Create(ctx, secret); err != nil { + return r.logErrorAndReturn(err, "could not create secret") + } + return nil + } else { + return r.logErrorAndReturn(err, "could not get secret") + } + } + + return nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *HumioBootstrapTokenReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&humiov1alpha1.HumioBootstrapToken{}). + Owns(&corev1.Secret{}). + Owns(&corev1.Pod{}). + Complete(r) +} + +func (r *HumioBootstrapTokenReconciler) logErrorAndReturn(err error, msg string) error { + r.Log.Error(err, msg) + return fmt.Errorf("%s: %w", msg, err) +} diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go new file mode 100644 index 00000000..5b09fda7 --- /dev/null +++ b/controllers/humiobootstraptoken_defaults.go @@ -0,0 +1,59 @@ +package controllers + +import ( + "fmt" + + "github.com/humio/humio-operator/api/v1alpha1" + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" +) + +const ( + BootstrapTokenSuffix = "bootstrap-token" + HashedBootstrapTokenSuffix = "hashed-bootstrap-token" +) + +type HumioBootstrapTokenConfig struct { + BootstrapToken *v1alpha1.HumioBootstrapToken + ManagedHumioCluster *v1alpha1.HumioCluster +} + +func NewHumioBootstrapTokenConfig(bootstrapToken *humiov1alpha1.HumioBootstrapToken, managedHumioCluster *v1alpha1.HumioCluster) HumioBootstrapTokenConfig { + return HumioBootstrapTokenConfig{BootstrapToken: bootstrapToken, ManagedHumioCluster: managedHumioCluster} +} + +func (b *HumioBootstrapTokenConfig) bootstrapTokenName() string { + if b.BootstrapToken.Spec.TokenSecret.SecretKeyRef != nil { + return b.BootstrapToken.Spec.TokenSecret.SecretKeyRef.Name + } + return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, BootstrapTokenSuffix) +} + +func (b *HumioBootstrapTokenConfig) hashedBootstrapTokenName() string { + if b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef != nil { + return b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef.Name + } + return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, HashedBootstrapTokenSuffix) +} + +func (b *HumioBootstrapTokenConfig) image() string { + if b.BootstrapToken.Spec.Image != "" { + return b.BootstrapToken.Spec.Image + } + if b.ManagedHumioCluster.Spec.Image != "" { + return b.ManagedHumioCluster.Spec.Image + } + if b.ManagedHumioCluster != nil { + if len(b.ManagedHumioCluster.Spec.NodePools) > 0 { + return b.ManagedHumioCluster.Spec.NodePools[0].Image + } + } + return Image +} + +func (b *HumioBootstrapTokenConfig) name() string { + return b.BootstrapToken.Name +} + +func (b *HumioBootstrapTokenConfig) namespace() string { + return b.BootstrapToken.Namespace +} diff --git a/controllers/humiobootstraptoken_pods.go b/controllers/humiobootstraptoken_pods.go new file mode 100644 index 00000000..2fe556ac --- /dev/null +++ b/controllers/humiobootstraptoken_pods.go @@ -0,0 +1,63 @@ +package controllers + +import ( + "fmt" + + "github.com/humio/humio-operator/pkg/helpers" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func ConstructBootstrapPod(bootstrapConfig *HumioBootstrapTokenConfig) (*corev1.Pod, error) { + //var pod corev1.Pod + //productVersion := "unknown" + //imageSplit := strings.SplitN(bootstrapConfig.image(), ":", 2) + //if len(imageSplit) == 2 { + // productVersion = imageSplit[1] + //} + userID := int64(65534) + + return &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-bootstrap-token-onetime", bootstrapConfig.name()), + Namespace: bootstrapConfig.namespace(), + }, + Spec: corev1.PodSpec{ + //ShareProcessNamespace: hnp.GetShareProcessNamespace(), + //ServiceAccountName: hnp.GetHumioServiceAccountName(), + ////ImagePullSecrets: hnp.GetImagePullSecrets(), + Containers: []corev1.Container{ + { + Name: HumioContainerName, + Image: bootstrapConfig.image(), + ////ImagePullPolicy: hnp.GetImagePullPolicy(), + Command: []string{"/bin/sh", "/bin/sleep", "900"}, + Env: []corev1.EnvVar{ + { + Name: "HUMIO_LOG4J_CONFIGURATION", + Value: "log4j2-json-stdout.xml", + }, + }, + //Resources: hnp.GetResources(), + SecurityContext: &corev1.SecurityContext{ + Privileged: helpers.BoolPtr(false), + AllowPrivilegeEscalation: helpers.BoolPtr(false), + ReadOnlyRootFilesystem: helpers.BoolPtr(true), + RunAsUser: &userID, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + }, + }, + }, + //Affinity: hnp.GetAffinity(), + //Tolerations: hnp.GetTolerations(), + //TopologySpreadConstraints: hnp.GetTopologySpreadConstraints(), + //SecurityContext: hnp.GetPodSecurityContext(), + //TerminationGracePeriodSeconds: hnp.GetTerminationGracePeriodSeconds(), + }, + }, nil + +} From 5955f8b70c9fa4283ab63fb991a9b5cbc3f0da7f Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 26 Jun 2023 14:47:39 -0700 Subject: [PATCH 02/54] wip --- api/v1alpha1/humiobootstraptoken_types.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/v1alpha1/humiobootstraptoken_types.go b/api/v1alpha1/humiobootstraptoken_types.go index 2ba65e27..e6a7996c 100644 --- a/api/v1alpha1/humiobootstraptoken_types.go +++ b/api/v1alpha1/humiobootstraptoken_types.go @@ -22,10 +22,10 @@ import ( ) const ( -// HumioExternalClusterStateUnknown is the Unknown state of the external cluster -//HumioExternalClusterStateUnknown = "Unknown" -// HumioExternalClusterStateReady is the Ready state of the external cluster -//HumioExternalClusterStateReady = "Ready" + // HumioBootstrapTokenStateMissing is the Missing state of the bootstrap token + HumioBootstrapTokenStateMissing = "Missing" + // HumioBootstrapTokenStateReady is the Ready state of the bootstrap token + HumioBootstrapTokenStateReady = "Ready" ) // HumioBootstrapTokenSpec defines the bootstrap token that Humio will use to bootstrap authentication From c963de50764db8fb9a028460f8c5bd15c2d2eabd Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 26 Jun 2023 15:50:14 -0700 Subject: [PATCH 03/54] wip --- api/v1alpha1/zz_generated.deepcopy.go | 4 ++- .../core.humio.com_humiobootstraptokens.yaml | 27 ++++++++++++++ .../core.humio.com_humiobootstraptokens.yaml | 27 ++++++++++++++ controllers/humiobootstraptoken_controller.go | 35 +++++++++++++++---- 4 files changed, 85 insertions(+), 8 deletions(-) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6d51b33d..8db0b490 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -440,7 +440,7 @@ func (in *HumioBootstrapToken) DeepCopyInto(out *HumioBootstrapToken) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) } @@ -497,6 +497,8 @@ func (in *HumioBootstrapTokenList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioBootstrapTokenSpec) DeepCopyInto(out *HumioBootstrapTokenSpec) { *out = *in + in.TokenSecret.DeepCopyInto(&out.TokenSecret) + in.HashedTokenSecret.DeepCopyInto(&out.HashedTokenSecret) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioBootstrapTokenSpec. diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index 87fedf45..df22aa95 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -87,6 +87,33 @@ spec: type: object image: type: string + hashedTokenSecret: + properties: + createIfMissing: + type: boolean + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + required: + - createIfMissing + type: object + image: + type: string managedClusterName: description: ManagedClusterName type: string diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 87fedf45..df22aa95 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -87,6 +87,33 @@ spec: type: object image: type: string + hashedTokenSecret: + properties: + createIfMissing: + type: boolean + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + required: + - createIfMissing + type: object + image: + type: string managedClusterName: description: ManagedClusterName type: string diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index b4554587..917007e3 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -70,6 +70,24 @@ func (r *HumioBootstrapTokenReconciler) Reconcile(ctx context.Context, req ctrl. return reconcile.Result{}, err } + hc := &humiov1alpha1.HumioCluster{} + hcRequest := types.NamespacedName{ + Name: hbt.Spec.ManagedClusterName, + Namespace: hbt.Namespace, + } + if err := r.Get(ctx, hcRequest, hc); err != nil { + if k8serrors.IsNotFound(err) { + r.Log.Error(err, fmt.Sprintf("humiocluster %s not found", hcRequest.Name)) + return reconcile.Result{}, err + } + r.Log.Error(err, fmt.Sprintf("problem fetching humiocluster %s", hcRequest.Name)) + return reconcile.Result{}, err + } + + if err := r.ensureBootstrapTokenSecret(ctx, hbt, hc); err != nil { + return reconcile.Result{}, err + } + return reconcile.Result{RequeueAfter: time.Second * 60}, nil } @@ -109,9 +127,9 @@ func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humi return nil } -func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { +func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) error { existingPod := &corev1.Pod{} - humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt) + humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, hc) pod, err := ConstructBootstrapPod(&humioBootstrapTokenConfig) if err != nil { return r.logErrorAndReturn(err, "could not construct pod") @@ -129,19 +147,22 @@ func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humi return nil } -func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { - if !hbt.Spec.TokenSecret.CreateIfMissing { - return nil - } +func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) error { + r.Log.Info("ensuring bootstrap token") + // TODO: default is true here + //if !hbt.Spec.TokenSecret.CreateIfMissing { + // return nil + //} existingSecret := &corev1.Secret{} - humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt) + humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, hc) if err := r.Get(ctx, types.NamespacedName{ Namespace: hbt.Namespace, Name: humioBootstrapTokenConfig.bootstrapTokenName(), }, existingSecret); err != nil { if k8serrors.IsNotFound(err) { + // TODO: something better randomPass := kubernetes.RandomString() secretData := map[string][]byte{ "passphrase": []byte(randomPass), From 8ab8bce7362520e815ba3e2aaedeb8e67df39c91 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 29 Jun 2023 16:01:19 -0700 Subject: [PATCH 04/54] wip --- api/v1alpha1/humiobootstraptoken_types.go | 4 +- controllers/humiobootstraptoken_controller.go | 181 ++++++++++++++++-- controllers/humiobootstraptoken_defaults.go | 7 + controllers/humiobootstraptoken_pods.go | 3 +- 4 files changed, 171 insertions(+), 24 deletions(-) diff --git a/api/v1alpha1/humiobootstraptoken_types.go b/api/v1alpha1/humiobootstraptoken_types.go index e6a7996c..97f91baf 100644 --- a/api/v1alpha1/humiobootstraptoken_types.go +++ b/api/v1alpha1/humiobootstraptoken_types.go @@ -42,12 +42,12 @@ type HumioBootstrapTokenSpec struct { } type HumioTokenSecretSpec struct { - CreateIfMissing bool `json:"createIfMissing"` + CreateIfMissing *bool `json:"createIfMissing"` SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } type HumioHashedTokenSecretSpec struct { - CreateIfMissing bool `json:"createIfMissing"` + CreateIfMissing *bool `json:"createIfMissing"` SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 917007e3..7cfdd918 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -14,10 +14,18 @@ limitations under the License. package controllers import ( + "bytes" "context" + "encoding/json" "fmt" "time" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/tools/clientcmd" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/remotecommand" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -42,6 +50,11 @@ type HumioBootstrapTokenReconciler struct { Namespace string } +type HumioBootstrapTokenSecretData struct { + Secret string `json:"secret"` + HashedToken string `json:"hashedToken"` +} + //+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/finalizers,verbs=update @@ -88,14 +101,68 @@ func (r *HumioBootstrapTokenReconciler) Reconcile(ctx context.Context, req ctrl. return reconcile.Result{}, err } + if err := r.ensureBootstrapTokenHashedToken(ctx, hbt, hc); err != nil { + return reconcile.Result{}, err + } + return reconcile.Result{RequeueAfter: time.Second * 60}, nil } -func (r *HumioBootstrapTokenReconciler) execCommand(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { - return nil +func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []string) (string, error) { + configLoader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + clientcmd.NewDefaultClientConfigLoadingRules(), + &clientcmd.ConfigOverrides{}, + ) + + // create the Config object + cfg, err := configLoader.ClientConfig() + if err != nil { + return "", err + } + + // we want to use the core API (namespaces lives here) + cfg.APIPath = "/api" + cfg.GroupVersion = &corev1.SchemeGroupVersion + cfg.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + // create a RESTClient + rc, err := rest.RESTClientFor(cfg) + if err != nil { + return "", err + } + + req := rc.Post(). + Resource("pods"). + Name(pod.Name). + Namespace(pod.Namespace). + SubResource("exec") + req.VersionedParams(&corev1.PodExecOptions{ + Container: "humio", // TODO: changeme + Command: args, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: false, + }, scheme.ParameterCodec) + + exec, err := remotecommand.NewSPDYExecutor(cfg, "POST", req.URL()) + if err != nil { + return "", err + } + var stdout, stderr bytes.Buffer + err = exec.Stream(remotecommand.StreamOptions{ + Stdin: nil, + Stdout: &stdout, + Stderr: &stderr, + Tty: false, + }) + if err != nil { + return "", err + } + return stdout.String(), nil } -func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { +func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) (*corev1.Pod, error) { existingPod := &corev1.Pod{} humioCluster := &humiov1alpha1.HumioCluster{} if err := r.Get(ctx, types.NamespacedName{ @@ -109,7 +176,7 @@ func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humi humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, humioCluster) pod, err := ConstructBootstrapPod(&humioBootstrapTokenConfig) if err != nil { - return r.logErrorAndReturn(err, "could not construct pod") + return &corev1.Pod{}, r.logErrorAndReturn(err, "could not construct pod") } if err := r.Get(ctx, types.NamespacedName{ Namespace: pod.Namespace, @@ -117,14 +184,16 @@ func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humi }, existingPod); err != nil { if k8serrors.IsNotFound(err) { if err := controllerutil.SetControllerReference(hbt, pod, r.Scheme()); err != nil { - return r.logErrorAndReturn(err, "could not set controller reference") + return &corev1.Pod{}, r.logErrorAndReturn(err, "could not set controller reference") } + r.Log.Info("creating onetime pod") if err := r.Create(ctx, pod); err != nil { - return r.logErrorAndReturn(err, "could not create pod") + return &corev1.Pod{}, r.logErrorAndReturn(err, "could not create pod") } + return pod, nil } } - return nil + return existingPod, nil } func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) error { @@ -139,6 +208,7 @@ func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humi Name: pod.Name, }, existingPod); err != nil { if !k8serrors.IsNotFound(err) { + r.Log.Info("deleting onetime pod") if err := r.Delete(ctx, pod); err != nil { return r.logErrorAndReturn(err, "could not delete pod") } @@ -148,24 +218,27 @@ func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humi } func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) error { - r.Log.Info("ensuring bootstrap token") - // TODO: default is true here - //if !hbt.Spec.TokenSecret.CreateIfMissing { - // return nil - //} - - existingSecret := &corev1.Secret{} + r.Log.Info("ensuring bootstrap token secret") humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, hc) - - if err := r.Get(ctx, types.NamespacedName{ - Namespace: hbt.Namespace, - Name: humioBootstrapTokenConfig.bootstrapTokenName(), - }, existingSecret); err != nil { + if !humioBootstrapTokenConfig.tokenSecretCreateIfMissing() { + return nil + } + if _, err := r.getBootstrapTokenSecret(ctx, hbt, hc); err != nil { if k8serrors.IsNotFound(err) { // TODO: something better - randomPass := kubernetes.RandomString() + //randomPass := kubernetes.RandomString() secretData := map[string][]byte{ - "passphrase": []byte(randomPass), + //"passphrase": []byte(randomPass), + } + // TODO: make passphrase constant + if hbt.Spec.TokenSecret.SecretKeyRef != nil { + secret, err := kubernetes.GetSecret(ctx, r, hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Namespace) + if err != nil { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get secret %s", hbt.Spec.TokenSecret.SecretKeyRef.Name)) + } + if passphrase, ok := secret.Data["passphrase"]; ok { + secretData["passphrase"] = passphrase + } } secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { @@ -184,6 +257,72 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.C return nil } +func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) error { + r.Log.Info("ensuring bootstrap hashed token") + bootstrapTokenSecret, err := r.getBootstrapTokenSecret(ctx, hbt, hc) + if err != nil { + return r.logErrorAndReturn(err, "could not get bootstrap token secret") + } + // TODO: make tokenHash constant + if _, ok := bootstrapTokenSecret.Data["hashedToken"]; ok { + return nil + } + + commandArgs := []string{"/bin/bash", "/app/humio/humio/bin/humio-run-class.sh", "com.humio.main.TokenHashing", "--json"} + + if tokenSecret, ok := bootstrapTokenSecret.Data["secret"]; ok { + commandArgs = append(commandArgs, string(tokenSecret)) + } + + pod, err := r.createPod(ctx, hbt) + if err != nil { + return err + } + + // TODO: wait for pod to start + time.Sleep(time.Second * 10) + + defer func(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) { + if err := r.deletePod(ctx, hbt, hc); err != nil { + r.Log.Error(err, "failed to delete pod") + } + }(ctx, hbt, hc) + + r.Log.Info("execing onetime pod") + output, err := r.execCommand(pod, commandArgs) + if err != nil { + return r.logErrorAndReturn(err, "failed to exec pod") + } + + var secretData HumioBootstrapTokenSecretData + err = json.Unmarshal([]byte(output), &secretData) + if err != nil { + r.Log.Error(fmt.Errorf("failed to read output from exec command"), "omitting output") + } + + updatedSecret, err := r.getBootstrapTokenSecret(ctx, hbt, hc) + if err != nil { + return err + } + // TODO: make tokenHash constant + updatedSecret.Data = map[string][]byte{"hashedToken": []byte(secretData.HashedToken), "secret": []byte(secretData.Secret)} + + if err = r.Update(ctx, updatedSecret); err != nil { + return r.logErrorAndReturn(err, "failed to update secret with hashedToken data") + } + return nil +} + +func (r *HumioBootstrapTokenReconciler) getBootstrapTokenSecret(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) (*corev1.Secret, error) { + humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, hc) + existingSecret := &corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ + Namespace: hbt.Namespace, + Name: humioBootstrapTokenConfig.bootstrapTokenName(), + }, existingSecret) + return existingSecret, err +} + // SetupWithManager sets up the controller with the Manager. func (r *HumioBootstrapTokenReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index 5b09fda7..63265ad6 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -35,6 +35,13 @@ func (b *HumioBootstrapTokenConfig) hashedBootstrapTokenName() string { return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, HashedBootstrapTokenSuffix) } +func (b *HumioBootstrapTokenConfig) tokenSecretCreateIfMissing() bool { + if b.BootstrapToken.Spec.TokenSecret.CreateIfMissing != nil { + return *b.BootstrapToken.Spec.TokenSecret.CreateIfMissing + } + return true +} + func (b *HumioBootstrapTokenConfig) image() string { if b.BootstrapToken.Spec.Image != "" { return b.BootstrapToken.Spec.Image diff --git a/controllers/humiobootstraptoken_pods.go b/controllers/humiobootstraptoken_pods.go index 2fe556ac..512fd6ff 100644 --- a/controllers/humiobootstraptoken_pods.go +++ b/controllers/humiobootstraptoken_pods.go @@ -31,7 +31,8 @@ func ConstructBootstrapPod(bootstrapConfig *HumioBootstrapTokenConfig) (*corev1. Name: HumioContainerName, Image: bootstrapConfig.image(), ////ImagePullPolicy: hnp.GetImagePullPolicy(), - Command: []string{"/bin/sh", "/bin/sleep", "900"}, + //Command: []string{"/bin/sh"}, + Command: []string{"/bin/sleep", "900"}, Env: []corev1.EnvVar{ { Name: "HUMIO_LOG4J_CONFIGURATION", From bfd1e1429c4f10aeb59ec66e2ba24ab45f163c20 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 12 Jul 2023 16:24:41 -0700 Subject: [PATCH 05/54] wip --- api/v1alpha1/humiobootstraptoken_types.go | 10 +- api/v1alpha1/humiocluster_types.go | 3 - api/v1alpha1/zz_generated.deepcopy.go | 10 + .../core.humio.com_humiobootstraptokens.yaml | 101 ++--- .../crds/core.humio.com_humioclusters.yaml | 10 - .../bases/core.humio.com_humioactions.yaml | 6 - .../core.humio.com_humioaggregatealerts.yaml | 6 - .../crd/bases/core.humio.com_humioalerts.yaml | 6 - .../core.humio.com_humiobootstraptokens.yaml | 48 +-- .../bases/core.humio.com_humioclusters.yaml | 16 - .../core.humio.com_humioexternalclusters.yaml | 6 - .../core.humio.com_humiofilteralerts.yaml | 6 - .../core.humio.com_humioingesttokens.yaml | 6 - .../bases/core.humio.com_humioparsers.yaml | 6 - .../core.humio.com_humiorepositories.yaml | 6 - ...core.humio.com_humioscheduledsearches.yaml | 6 - .../crd/bases/core.humio.com_humioviews.yaml | 6 - controllers/humioaction_controller.go | 2 +- controllers/humioalert_controller.go | 5 +- controllers/humiobootstraptoken_controller.go | 54 ++- controllers/humiobootstraptoken_defaults.go | 1 + controllers/humiocluster_controller.go | 239 ++++-------- controllers/humiocluster_defaults.go | 36 +- controllers/humiocluster_permission_tokens.go | 361 ++++++++++++++++++ controllers/humiocluster_pods.go | 187 ++------- .../humioexternalcluster_controller.go | 5 +- controllers/humioingesttoken_controller.go | 7 +- controllers/humioparser_controller.go | 4 +- controllers/humiorepository_controller.go | 10 + controllers/humioview_controller.go | 4 + .../clusters/humiocluster_controller_test.go | 65 +--- controllers/suite/common.go | 241 +++++++++--- .../humioresources_controller_test.go | 2 +- controllers/suite/resources/suite_test.go | 2 +- ...umiocluster-multi-nodepool-kind-local.yaml | 6 +- go.mod | 3 + go.sum | 9 + pkg/helpers/clusterinterface.go | 30 +- pkg/helpers/clusterinterface_test.go | 28 +- pkg/humio/client.go | 108 ++++++ pkg/humio/client_mock.go | 32 +- pkg/kubernetes/secrets.go | 5 +- 42 files changed, 1003 insertions(+), 701 deletions(-) create mode 100644 controllers/humiocluster_permission_tokens.go diff --git a/api/v1alpha1/humiobootstraptoken_types.go b/api/v1alpha1/humiobootstraptoken_types.go index 97f91baf..57d0cdd9 100644 --- a/api/v1alpha1/humiobootstraptoken_types.go +++ b/api/v1alpha1/humiobootstraptoken_types.go @@ -30,6 +30,7 @@ const ( // HumioBootstrapTokenSpec defines the bootstrap token that Humio will use to bootstrap authentication type HumioBootstrapTokenSpec struct { + // TODO: determine if we even want to reference the cluster here // ManagedClusterName ManagedClusterName string `json:"managedClusterName,omitempty"` // ExternalClusterName refers to an object of type HumioExternalCluster where the Humio resources should be created. @@ -42,16 +43,21 @@ type HumioBootstrapTokenSpec struct { } type HumioTokenSecretSpec struct { - CreateIfMissing *bool `json:"createIfMissing"` + // TODO: we could clean this up by removing the "CreateIfMissing" and in docs explain if you want to use your own secret + // then create the secret before the bootstraptoken resource + CreateIfMissing *bool `json:"createIfMissing,omitempty"` SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } type HumioHashedTokenSecretSpec struct { - CreateIfMissing *bool `json:"createIfMissing"` + // TODO: maybe remove CreateIfMissing + CreateIfMissing *bool `json:"createIfMissing,omitempty"` SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } type HumioBootstrapTokenStatus struct { + // TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec + // here as the spec could be empty. Or do we want to Created bool `json:"created,omitempty"` TokenSecretKeyRef HumioTokenSecretStatus `json:"tokenSecretStatus,omitempty"` HashedTokenSecretKeyRef HumioHashedTokenSecretStatus `json:"hashedTokenSecretStatus,omitempty"` diff --git a/api/v1alpha1/humiocluster_types.go b/api/v1alpha1/humiocluster_types.go index aa87b743..7c71b1fc 100644 --- a/api/v1alpha1/humiocluster_types.go +++ b/api/v1alpha1/humiocluster_types.go @@ -118,9 +118,6 @@ type HumioNodeSpec struct { // DataVolumeSource is the volume that is mounted on the humio pods. This conflicts with DataVolumePersistentVolumeClaimSpecTemplate. DataVolumeSource corev1.VolumeSource `json:"dataVolumeSource,omitempty"` - // AuthServiceAccountName is the name of the Kubernetes Service Account that will be attached to the auth container in the humio pod. - AuthServiceAccountName string `json:"authServiceAccountName,omitempty"` - // DisableInitContainer is used to disable the init container completely which collects the availability zone from the Kubernetes worker node. // This is not recommended, unless you are using auto rebalancing partitions and are running in a single availability zone. DisableInitContainer bool `json:"disableInitContainer,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 8db0b490..62745822 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -926,6 +926,11 @@ func (in *HumioFilterAlertSpec) DeepCopy() *HumioFilterAlertSpec { ======= func (in *HumioHashedTokenSecretSpec) DeepCopyInto(out *HumioHashedTokenSecretSpec) { *out = *in + if in.CreateIfMissing != nil { + in, out := &in.CreateIfMissing, &out.CreateIfMissing + *out = new(bool) + **out = **in + } if in.SecretKeyRef != nil { in, out := &in.SecretKeyRef, &out.SecretKeyRef *out = new(v1.SecretKeySelector) @@ -1638,6 +1643,11 @@ func (in *HumioRetention) DeepCopy() *HumioRetention { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioTokenSecretSpec) DeepCopyInto(out *HumioTokenSecretSpec) { *out = *in + if in.CreateIfMissing != nil { + in, out := &in.CreateIfMissing, &out.CreateIfMissing + *out = new(bool) + **out = **in + } if in.SecretKeyRef != nil { in, out := &in.SecretKeyRef, &out.SecretKeyRef *out = new(v1.SecretKeySelector) diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index df22aa95..d8f1438b 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -1,16 +1,18 @@ + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null name: humiobootstraptokens.core.humio.com labels: app: 'humio-operator' app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' + helm.sh/chart: 'humio-operator-0.19.0' spec: group: core.humio.com names: @@ -32,19 +34,14 @@ spec: use to bootstrap authentication properties: apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -53,43 +50,14 @@ spec: Humio will use to bootstrap authentication properties: externalClusterName: - description: |- - ExternalClusterName refers to an object of type HumioExternalCluster where the Humio resources should be created. - This conflicts with ManagedClusterName. - type: string - hashedTokenSecret: - properties: - createIfMissing: - type: boolean - secretKeyRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? - type: string - optional: - description: Specify whether the Secret or its key must be - defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - required: - - createIfMissing - type: object - image: + description: ExternalClusterName refers to an object of type HumioExternalCluster + where the Humio resources should be created. This conflicts with + ManagedClusterName. type: string hashedTokenSecret: properties: createIfMissing: + description: 'TODO: maybe remove CreateIfMissing' type: boolean secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -109,17 +77,19 @@ spec: required: - key type: object - required: - - createIfMissing type: object image: type: string managedClusterName: - description: ManagedClusterName + description: 'TODO: determine if we even want to reference the cluster + here ManagedClusterName' type: string tokenSecret: properties: createIfMissing: + description: 'TODO: we could clean this up by removing the "CreateIfMissing" + and in docs explain if you want to use your own secret then + create the secret before the bootstraptoken resource' type: boolean secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -129,10 +99,8 @@ spec: a valid secret key. type: string name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: description: Specify whether the Secret or its key must be @@ -141,14 +109,15 @@ spec: required: - key type: object - x-kubernetes-map-type: atomic - required: - - createIfMissing type: object type: object status: properties: created: + description: TODO set the status. This is used by the HumioCluster + resource to get the secret reference and load the secret. We don't + want to rely on the spec here as the spec could be empty. Or do + we want to type: boolean hashedTokenSecretStatus: properties: @@ -160,10 +129,8 @@ spec: a valid secret key. type: string name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: description: Specify whether the Secret or its key must be @@ -172,7 +139,6 @@ spec: required: - key type: object - x-kubernetes-map-type: atomic type: object tokenSecretStatus: properties: @@ -184,10 +150,8 @@ spec: a valid secret key. type: string name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: description: Specify whether the Secret or its key must be @@ -196,7 +160,6 @@ spec: required: - key type: object - x-kubernetes-map-type: atomic type: object type: object type: object @@ -204,3 +167,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/charts/humio-operator/crds/core.humio.com_humioclusters.yaml b/charts/humio-operator/crds/core.humio.com_humioclusters.yaml index 0794678c..4c4bbe8a 100644 --- a/charts/humio-operator/crds/core.humio.com_humioclusters.yaml +++ b/charts/humio-operator/crds/core.humio.com_humioclusters.yaml @@ -945,11 +945,6 @@ spec: type: array type: object type: object - authServiceAccountName: - description: AuthServiceAccountName is the name of the Kubernetes - Service Account that will be attached to the auth container in the - humio pod. - type: string autoRebalancePartitions: description: |- AutoRebalancePartitions will enable auto-rebalancing of both digest and storage partitions assigned to humio cluster nodes. @@ -6639,11 +6634,6 @@ spec: type: array type: object type: object - authServiceAccountName: - description: AuthServiceAccountName is the name of the Kubernetes - Service Account that will be attached to the auth container - in the humio pod. - type: string containerLivenessProbe: description: |- ContainerLivenessProbe is the liveness probe applied to the Humio container diff --git a/config/crd/bases/core.humio.com_humioactions.yaml b/config/crd/bases/core.humio.com_humioactions.yaml index 275ad98a..8b7b1fda 100644 --- a/config/crd/bases/core.humio.com_humioactions.yaml +++ b/config/crd/bases/core.humio.com_humioactions.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioactions.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioaggregatealerts.yaml b/config/crd/bases/core.humio.com_humioaggregatealerts.yaml index 7fd4369f..2747e8c4 100644 --- a/config/crd/bases/core.humio.com_humioaggregatealerts.yaml +++ b/config/crd/bases/core.humio.com_humioaggregatealerts.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioaggregatealerts.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioalerts.yaml b/config/crd/bases/core.humio.com_humioalerts.yaml index 2dbc7e8e..e2545259 100644 --- a/config/crd/bases/core.humio.com_humioalerts.yaml +++ b/config/crd/bases/core.humio.com_humioalerts.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioalerts.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index df22aa95..97ac2c68 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humiobootstraptokens.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: @@ -60,6 +54,7 @@ spec: hashedTokenSecret: properties: createIfMissing: + description: 'TODO: maybe remove CreateIfMissing' type: boolean secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -82,44 +77,20 @@ spec: - key type: object x-kubernetes-map-type: atomic - required: - - createIfMissing - type: object - image: - type: string - hashedTokenSecret: - properties: - createIfMissing: - type: boolean - secretKeyRef: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be - defined - type: boolean - required: - - key - type: object - required: - - createIfMissing type: object image: type: string managedClusterName: - description: ManagedClusterName + description: |- + TODO: determine if we even want to reference the cluster here + ManagedClusterName type: string tokenSecret: properties: createIfMissing: + description: |- + TODO: we could clean this up by removing the "CreateIfMissing" and in docs explain if you want to use your own secret + then create the secret before the bootstraptoken resource type: boolean secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -142,13 +113,14 @@ spec: - key type: object x-kubernetes-map-type: atomic - required: - - createIfMissing type: object type: object status: properties: created: + description: |- + TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec + here as the spec could be empty. Or do we want to type: boolean hashedTokenSecretStatus: properties: diff --git a/config/crd/bases/core.humio.com_humioclusters.yaml b/config/crd/bases/core.humio.com_humioclusters.yaml index 0794678c..479b88e2 100644 --- a/config/crd/bases/core.humio.com_humioclusters.yaml +++ b/config/crd/bases/core.humio.com_humioclusters.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioclusters.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: @@ -945,11 +939,6 @@ spec: type: array type: object type: object - authServiceAccountName: - description: AuthServiceAccountName is the name of the Kubernetes - Service Account that will be attached to the auth container in the - humio pod. - type: string autoRebalancePartitions: description: |- AutoRebalancePartitions will enable auto-rebalancing of both digest and storage partitions assigned to humio cluster nodes. @@ -6639,11 +6628,6 @@ spec: type: array type: object type: object - authServiceAccountName: - description: AuthServiceAccountName is the name of the Kubernetes - Service Account that will be attached to the auth container - in the humio pod. - type: string containerLivenessProbe: description: |- ContainerLivenessProbe is the liveness probe applied to the Humio container diff --git a/config/crd/bases/core.humio.com_humioexternalclusters.yaml b/config/crd/bases/core.humio.com_humioexternalclusters.yaml index b60263f9..7d09a980 100644 --- a/config/crd/bases/core.humio.com_humioexternalclusters.yaml +++ b/config/crd/bases/core.humio.com_humioexternalclusters.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioexternalclusters.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiofilteralerts.yaml b/config/crd/bases/core.humio.com_humiofilteralerts.yaml index 1a5107b9..48c2d478 100644 --- a/config/crd/bases/core.humio.com_humiofilteralerts.yaml +++ b/config/crd/bases/core.humio.com_humiofilteralerts.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humiofilteralerts.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioingesttokens.yaml b/config/crd/bases/core.humio.com_humioingesttokens.yaml index 4632eda0..dc9ac5f9 100644 --- a/config/crd/bases/core.humio.com_humioingesttokens.yaml +++ b/config/crd/bases/core.humio.com_humioingesttokens.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioingesttokens.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioparsers.yaml b/config/crd/bases/core.humio.com_humioparsers.yaml index acf7ba2f..b4f7ad31 100644 --- a/config/crd/bases/core.humio.com_humioparsers.yaml +++ b/config/crd/bases/core.humio.com_humioparsers.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioparsers.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiorepositories.yaml b/config/crd/bases/core.humio.com_humiorepositories.yaml index 08244fb4..c6fc6552 100644 --- a/config/crd/bases/core.humio.com_humiorepositories.yaml +++ b/config/crd/bases/core.humio.com_humiorepositories.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humiorepositories.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioscheduledsearches.yaml b/config/crd/bases/core.humio.com_humioscheduledsearches.yaml index 5cbec6f9..15dcec30 100644 --- a/config/crd/bases/core.humio.com_humioscheduledsearches.yaml +++ b/config/crd/bases/core.humio.com_humioscheduledsearches.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioscheduledsearches.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioviews.yaml b/config/crd/bases/core.humio.com_humioviews.yaml index 5cf7950a..52a21041 100644 --- a/config/crd/bases/core.humio.com_humioviews.yaml +++ b/config/crd/bases/core.humio.com_humioviews.yaml @@ -5,12 +5,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioviews.core.humio.com - labels: - app: 'humio-operator' - app.kubernetes.io/name: 'humio-operator' - app.kubernetes.io/instance: 'humio-operator' - app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/controllers/humioaction_controller.go b/controllers/humioaction_controller.go index eca81448..796a6268 100644 --- a/controllers/humioaction_controller.go +++ b/controllers/humioaction_controller.go @@ -73,7 +73,7 @@ func (r *HumioActionReconciler) Reconcile(ctx context.Context, req ctrl.Request) r.Log = r.Log.WithValues("Request.UID", ha.UID) - cluster, err := helpers.NewCluster(ctx, r, ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName, ha.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName, ha.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioActionStateConfigError, ha) if setStateErr != nil { diff --git a/controllers/humioalert_controller.go b/controllers/humioalert_controller.go index e772f31a..1eded9bf 100644 --- a/controllers/humioalert_controller.go +++ b/controllers/humioalert_controller.go @@ -20,10 +20,11 @@ import ( "context" "errors" "fmt" - "github.com/humio/humio-operator/pkg/kubernetes" "reflect" "time" + "github.com/humio/humio-operator/pkg/kubernetes" + humioapi "github.com/humio/cli/api" "github.com/humio/humio-operator/pkg/helpers" @@ -76,7 +77,7 @@ func (r *HumioAlertReconciler) Reconcile(ctx context.Context, req ctrl.Request) r.Log = r.Log.WithValues("Request.UID", ha.UID) - cluster, err := helpers.NewCluster(ctx, r, ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName, ha.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName, ha.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioAlertStateConfigError, ha) if setStateErr != nil { diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 7cfdd918..d1a99f76 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -105,6 +105,35 @@ func (r *HumioBootstrapTokenReconciler) Reconcile(ctx context.Context, req ctrl. return reconcile.Result{}, err } + if err := r.Get(ctx, req.NamespacedName, hbt); err != nil { + return reconcile.Result{}, err + } + + // TODO: rather than status, should we set a default in the spec instead? + hbt.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", hbt.Name), + }, + Key: "secret", + }, + } + hbt.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", hbt.Name), + }, + Key: "hashedToken", + }, + } + if err := r.Client.Status().Update(ctx, hbt); err != nil { + return reconcile.Result{}, err + } + + // TODO: take code from images/helper/main.go and use "secret" to create an admin user and store the token in a k8s secret. Update the + // HumioBootstrapToken Status to also include the admin token. + // Alternatively, the creation of the admin user could be handled by the humiocluster controller. Perhaps that is a better place for it? + return reconcile.Result{RequeueAfter: time.Second * 60}, nil } @@ -207,12 +236,14 @@ func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humi Namespace: pod.Namespace, Name: pod.Name, }, existingPod); err != nil { - if !k8serrors.IsNotFound(err) { - r.Log.Info("deleting onetime pod") - if err := r.Delete(ctx, pod); err != nil { - return r.logErrorAndReturn(err, "could not delete pod") - } + if k8serrors.IsNotFound(err) { + return nil } + return r.logErrorAndReturn(err, "could not delete pod") + } + r.Log.Info("deleting onetime pod") + if err := r.Delete(ctx, pod); err != nil { + return r.logErrorAndReturn(err, "could not delete pod") } return nil } @@ -263,6 +294,13 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont if err != nil { return r.logErrorAndReturn(err, "could not get bootstrap token secret") } + + defer func(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) { + if err := r.deletePod(ctx, hbt, hc); err != nil { + r.Log.Error(err, "failed to delete pod") + } + }(ctx, hbt, hc) + // TODO: make tokenHash constant if _, ok := bootstrapTokenSecret.Data["hashedToken"]; ok { return nil @@ -282,12 +320,6 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont // TODO: wait for pod to start time.Sleep(time.Second * 10) - defer func(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) { - if err := r.deletePod(ctx, hbt, hc); err != nil { - r.Log.Error(err, "failed to delete pod") - } - }(ctx, hbt, hc) - r.Log.Info("execing onetime pod") output, err := r.execCommand(pod, commandArgs) if err != nil { diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index 63265ad6..8a5b9541 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -35,6 +35,7 @@ func (b *HumioBootstrapTokenConfig) hashedBootstrapTokenName() string { return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, HashedBootstrapTokenSuffix) } +// TODO: remove this? func (b *HumioBootstrapTokenConfig) tokenSecretCreateIfMissing() bool { if b.BootstrapToken.Spec.TokenSecret.CreateIfMissing != nil { return *b.BootstrapToken.Spec.TokenSecret.CreateIfMissing diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index 314c21bf..758bfdea 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -31,6 +31,7 @@ import ( corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -121,6 +122,11 @@ func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request withObservedGeneration(hc.GetGeneration())) }(ctx, r.HumioClient, hc) + if err := r.ensureHumioClusterBootstrapToken(ctx, hc); err != nil { + return r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). + withMessage(err.Error())) + } + for _, pool := range humioNodePools.Filter(NodePoolFilterHasNode) { if err := r.setImageFromSource(ctx, pool); err != nil { return r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). @@ -240,7 +246,6 @@ func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request r.ensureService, r.ensureHumioPodPermissions, r.ensureInitContainerPermissions, - r.ensureAuthContainerPermissions, r.ensureHumioNodeCertificates, r.ensureExtraKafkaConfigsConfigMap, } { @@ -306,7 +311,7 @@ func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request } } - cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { return r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). withMessage(r.logErrorAndReturn(err, "unable to obtain humio client config").Error()). @@ -451,6 +456,51 @@ func (r *HumioClusterReconciler) ensurePodRevisionAnnotation(ctx context.Context } return hc.Status.State, nil } +func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Context, hc *humiov1alpha1.HumioCluster) error { + key := types.NamespacedName{ + Namespace: hc.Namespace, + Name: hc.Name, + } + hbt := &humiov1alpha1.HumioBootstrapToken{} + err := r.Client.Get(ctx, key, hbt) + if err != nil { + if k8serrors.IsNotFound(err) { + hbt := &humiov1alpha1.HumioBootstrapToken{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + Spec: humiov1alpha1.HumioBootstrapTokenSpec{ + ManagedClusterName: hc.Name, + // TokenSecret: humiov1alpha1.HumioTokenSecretSpec{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), + // }, + // Key: "secret", + // }, + // }, + // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), + // }, + // Key: "hashedToken", + // }, + // }, + }, + } + err = r.Create(ctx, hbt) + if err != nil { + return r.logErrorAndReturn(err, "could not create bootstrap token resource") + } + if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { + return r.logErrorAndReturn(err, "could not set controller reference") + } + } + } + return nil +} func (r *HumioClusterReconciler) validateInitialPodSpec(hnp *HumioNodePool) error { if _, err := ConstructPod(hnp, "", &podAttachments{}); err != nil { @@ -877,42 +927,6 @@ func (r *HumioClusterReconciler) ensureInitContainerPermissions(ctx context.Cont return nil } -func (r *HumioClusterReconciler) ensureAuthContainerPermissions(ctx context.Context, hc *humiov1alpha1.HumioCluster, hnp *HumioNodePool) error { - // Only add the service account secret if the authServiceAccountName is supplied. This implies the service account, - // cluster role and cluster role binding are managed outside of the operator, so we skip the remaining tasks. - if hnp.AuthServiceAccountIsSetByUser() { - // We do not want to attach the auth service account to the humio pod. Instead, only the auth container should use this - // service account. To do this, we can attach the service account directly to the auth container as per - // https://github.com/kubernetes/kubernetes/issues/66020#issuecomment-590413238 - if err := r.ensureServiceAccountSecretExists(ctx, hc, hnp, hnp.GetAuthServiceAccountSecretName(), hnp.GetAuthServiceAccountName()); err != nil { - return r.logErrorAndReturn(err, "unable to ensure auth service account secret exists") - } - return nil - } - - // The service account is used by the auth container attached to the humio pods. - if err := r.ensureServiceAccountExists(ctx, hc, hnp, hnp.GetAuthServiceAccountName(), map[string]string{}); err != nil { - return r.logErrorAndReturn(err, "unable to ensure auth service account exists") - } - - // We do not want to attach the auth service account to the humio pod. Instead, only the auth container should use this - // service account. To do this, we can attach the service account directly to the auth container as per - // https://github.com/kubernetes/kubernetes/issues/66020#issuecomment-590413238 - if err := r.ensureServiceAccountSecretExists(ctx, hc, hnp, hnp.GetAuthServiceAccountSecretName(), hnp.GetAuthServiceAccountName()); err != nil { - return r.logErrorAndReturn(err, "unable to ensure auth service account secret exists") - } - - if err := r.ensureAuthRole(ctx, hc, hnp); err != nil { - return r.logErrorAndReturn(err, "unable to ensure auth role exists") - } - - if err := r.ensureAuthRoleBinding(ctx, hc, hnp); err != nil { - return r.logErrorAndReturn(err, "unable to ensure auth role binding exists") - } - - return nil -} - // Ensure the CA Issuer is valid/ready func (r *HumioClusterReconciler) ensureValidCAIssuer(ctx context.Context, hc *humiov1alpha1.HumioCluster) error { if !helpers.TLSEnabled(hc) { @@ -1113,27 +1127,6 @@ func (r *HumioClusterReconciler) ensureInitClusterRole(ctx context.Context, hnp return nil } -func (r *HumioClusterReconciler) ensureAuthRole(ctx context.Context, hc *humiov1alpha1.HumioCluster, hnp *HumioNodePool) error { - roleName := hnp.GetAuthRoleName() - _, err := kubernetes.GetRole(ctx, r, roleName, hnp.GetNamespace()) - if err != nil { - if k8serrors.IsNotFound(err) { - role := kubernetes.ConstructAuthRole(roleName, hnp.GetNamespace(), hnp.GetNodePoolLabels()) - if err := controllerutil.SetControllerReference(hc, role, r.Scheme()); err != nil { - return r.logErrorAndReturn(err, "could not set controller reference") - } - r.Log.Info(fmt.Sprintf("creating role: %s", role.Name)) - err = r.Create(ctx, role) - if err != nil { - return r.logErrorAndReturn(err, "unable to create auth role") - } - r.Log.Info(fmt.Sprintf("successfully created auth role %s", roleName)) - humioClusterPrometheusMetrics.Counters.RolesCreated.Inc() - } - } - return nil -} - func (r *HumioClusterReconciler) ensureInitClusterRoleBinding(ctx context.Context, hnp *HumioNodePool) error { clusterRoleBindingName := hnp.GetInitClusterRoleBindingName() _, err := kubernetes.GetClusterRoleBinding(ctx, r, clusterRoleBindingName) @@ -1160,33 +1153,6 @@ func (r *HumioClusterReconciler) ensureInitClusterRoleBinding(ctx context.Contex return nil } -func (r *HumioClusterReconciler) ensureAuthRoleBinding(ctx context.Context, hc *humiov1alpha1.HumioCluster, hnp *HumioNodePool) error { - roleBindingName := hnp.GetAuthRoleBindingName() - _, err := kubernetes.GetRoleBinding(ctx, r, roleBindingName, hnp.GetNamespace()) - if err != nil { - if k8serrors.IsNotFound(err) { - roleBinding := kubernetes.ConstructRoleBinding( - roleBindingName, - hnp.GetAuthRoleName(), - hnp.GetNamespace(), - hnp.GetAuthServiceAccountName(), - hnp.GetNodePoolLabels(), - ) - if err := controllerutil.SetControllerReference(hc, roleBinding, r.Scheme()); err != nil { - return r.logErrorAndReturn(err, "could not set controller reference") - } - r.Log.Info(fmt.Sprintf("creating role binding: %s", roleBinding.Name)) - err = r.Create(ctx, roleBinding) - if err != nil { - return r.logErrorAndReturn(err, "unable to create auth role binding") - } - r.Log.Info(fmt.Sprintf("successfully created auth role binding %s", roleBindingName)) - humioClusterPrometheusMetrics.Counters.RoleBindingsCreated.Inc() - } - } - return nil -} - // validateUserDefinedServiceAccountsExists confirms that the user-defined service accounts all exist as they should. // If any of the service account names explicitly set does not exist, or that we get an error, we return an error. // In case the user does not define any service accounts or that all user-defined service accounts already exists, we return nil. @@ -1209,15 +1175,6 @@ func (r *HumioClusterReconciler) validateUserDefinedServiceAccountsExists(ctx co return r.logErrorAndReturn(err, "could not get service accounts") } } - if hc.Spec.AuthServiceAccountName != "" { - _, err := kubernetes.GetServiceAccount(ctx, r, hc.Spec.AuthServiceAccountName, hc.Namespace) - if err != nil { - if k8serrors.IsNotFound(err) { - return r.logErrorAndReturn(err, "not all referenced service accounts exists") - } - return r.logErrorAndReturn(err, "could not get service accounts") - } - } return nil } @@ -1399,7 +1356,7 @@ func (r *HumioClusterReconciler) ensureLicense(ctx context.Context, hc *humiov1a // Configure a Humio client without an API token which we can use to check the current license on the cluster noLicense := humioapi.OnPremLicense{} - cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false) + cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false, false) if err != nil { return reconcile.Result{}, err } @@ -1446,7 +1403,19 @@ func (r *HumioClusterReconciler) ensureLicense(ctx context.Context, hc *humiov1a return reconcile.Result{Requeue: true}, nil } - cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true) + cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false, true) + if err = r.HumioClient.InstallLicense(cluster.Config(), req, licenseStr); err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "could not authenticate with bootstrap token") + } + + // TODO: ensureLicense should be broken into multiple steps + if err = r.ensurePermissionTokens(ctx, cluster.Config(), req, hc); err != nil { + // It's failing here due to: Got err trying to obtain user ID of admin user: Message: License does not allow adding users. Please contact Humio support + // I'm thinking the user may need to be added to the org, or if single org is enabled then we need to do something differently? + return reconcile.Result{}, r.logErrorAndReturn(err, fmt.Sprintf("config: %+v", cluster.Config())) + } + + cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) if err != nil { return reconcile.Result{}, err } @@ -1654,50 +1623,6 @@ func (r *HumioClusterReconciler) ensureNodePoolSpecificResourcesHaveLabelWithNod } } - if !hnp.AuthServiceAccountIsSetByUser() { - serviceAccount, err := kubernetes.GetServiceAccount(ctx, r.Client, hnp.GetAuthServiceAccountName(), hnp.GetNamespace()) - if err == nil { - serviceAccount.SetLabels(hnp.GetNodePoolLabels()) - err = r.Client.Update(ctx, serviceAccount) - if err != nil { - return r.logErrorAndReturn(err, "unable to update auth service account") - } - } - if err != nil { - if !k8serrors.IsNotFound(err) { - return r.logErrorAndReturn(err, "unable to get auth service account") - } - } - - role, err := kubernetes.GetRole(ctx, r.Client, hnp.GetAuthRoleName(), hnp.GetNamespace()) - if err == nil { - role.SetLabels(hnp.GetNodePoolLabels()) - err = r.Client.Update(ctx, role) - if err != nil { - return r.logErrorAndReturn(err, "unable to update auth role") - } - } - if err != nil { - if !k8serrors.IsNotFound(err) { - return r.logErrorAndReturn(err, "unable to get auth role") - } - } - - roleBinding, err := kubernetes.GetRoleBinding(ctx, r.Client, hnp.GetAuthRoleBindingName(), hnp.GetNamespace()) - if err == nil { - roleBinding.SetLabels(hnp.GetNodePoolLabels()) - err = r.Client.Update(ctx, roleBinding) - if err != nil { - return r.logErrorAndReturn(err, "unable to update auth role binding") - } - } - if err != nil { - if !k8serrors.IsNotFound(err) { - return r.logErrorAndReturn(err, "unable to get auth role binding") - } - } - } - return nil } @@ -1915,24 +1840,6 @@ func (r *HumioClusterReconciler) getInitServiceAccountSecretName(ctx context.Con return foundInitServiceAccountSecretsList[0].Name, nil } -func (r *HumioClusterReconciler) getAuthServiceAccountSecretName(ctx context.Context, hnp *HumioNodePool) (string, error) { - foundAuthServiceAccountNameSecretsList, err := kubernetes.ListSecrets(ctx, r, hnp.GetNamespace(), hnp.GetLabelsForSecret(hnp.GetAuthServiceAccountSecretName())) - if err != nil { - return "", err - } - if len(foundAuthServiceAccountNameSecretsList) == 0 { - return "", nil - } - if len(foundAuthServiceAccountNameSecretsList) > 1 { - var secretNames []string - for _, secret := range foundAuthServiceAccountNameSecretsList { - secretNames = append(secretNames, secret.Name) - } - return "", fmt.Errorf("found more than one auth service account secret: %s", strings.Join(secretNames, ", ")) - } - return foundAuthServiceAccountNameSecretsList[0].Name, nil -} - func (r *HumioClusterReconciler) ensureHumioServiceAccountAnnotations(ctx context.Context, hnp *HumioNodePool) (bool, error) { // Don't change the service account annotations if the service account is not managed by the operator if hnp.HumioServiceAccountIsSetByUser() { @@ -2009,6 +1916,20 @@ func (r *HumioClusterReconciler) ensureMismatchedPodsAreDeleted(ctx context.Cont attachments.envVarSourceData = envVarSourceData } + // asdf + key := types.NamespacedName{ + Namespace: hc.Namespace, + Name: hc.Name, + } + hbt := &humiov1alpha1.HumioBootstrapToken{} + err = r.Client.Get(ctx, key, hbt) + if err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "failed to get bootstrap token") + } + if hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef != nil { + attachments.bootstrapTokenSecretReference = hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef + } + // prioritize deleting the pods with errors var podList []corev1.Pod if podsStatus.havePodsWithErrors() { diff --git a/controllers/humiocluster_defaults.go b/controllers/humiocluster_defaults.go index 3097248d..8feec50a 100644 --- a/controllers/humiocluster_defaults.go +++ b/controllers/humiocluster_defaults.go @@ -44,7 +44,6 @@ const ( ViewGroupPermissionsFilename = "view-group-permissions.json" RolePermissionsFilename = "role-permissions.json" HumioContainerName = "humio" - AuthContainerName = "humio-auth" InitContainerName = "humio-init" // cluster-wide resources: @@ -55,10 +54,6 @@ const ( HumioServiceAccountNameSuffix = "humio" initServiceAccountNameSuffix = "init" initServiceAccountSecretNameIdentifier = "init" - authServiceAccountNameSuffix = "auth" - authServiceAccountSecretNameIdentifier = "auth" - authRoleSuffix = "auth" - authRoleBindingSuffix = "auth" extraKafkaConfigsConfigMapNameSuffix = "extra-kafka-configs" viewGroupPermissionsConfigMapNameSuffix = "view-group-permissions" rolePermissionsConfigMapNameSuffix = "role-permissions" @@ -102,7 +97,6 @@ func NewHumioNodeManagerFromHumioCluster(hc *humiov1alpha1.HumioCluster) *HumioN DataVolumePersistentVolumeClaimSpecTemplate: hc.Spec.DataVolumePersistentVolumeClaimSpecTemplate, DataVolumePersistentVolumeClaimPolicy: hc.Spec.DataVolumePersistentVolumeClaimPolicy, DataVolumeSource: hc.Spec.DataVolumeSource, - AuthServiceAccountName: hc.Spec.AuthServiceAccountName, DisableInitContainer: hc.Spec.DisableInitContainer, EnvironmentVariablesSource: hc.Spec.EnvironmentVariablesSource, PodAnnotations: hc.Spec.PodAnnotations, @@ -164,7 +158,6 @@ func NewHumioNodeManagerFromHumioNodePool(hc *humiov1alpha1.HumioCluster, hnp *h NodeCount: hnp.NodeCount, DataVolumePersistentVolumeClaimSpecTemplate: hnp.DataVolumePersistentVolumeClaimSpecTemplate, DataVolumeSource: hnp.DataVolumeSource, - AuthServiceAccountName: hnp.AuthServiceAccountName, DisableInitContainer: hnp.DisableInitContainer, EnvironmentVariablesSource: hnp.EnvironmentVariablesSource, PodAnnotations: hnp.PodAnnotations, @@ -308,6 +301,10 @@ func (hnp *HumioNodePool) GetIngress() humiov1alpha1.HumioClusterIngressSpec { return hnp.ingress } +func (hnp HumioNodePool) GetBootstrapTokenName() string { + return hnp.clusterName +} + func (hnp *HumioNodePool) GetEnvironmentVariables() []corev1.EnvVar { envVars := make([]corev1.EnvVar, len(hnp.humioNodeSpec.EnvironmentVariables)) copy(envVars, hnp.humioNodeSpec.EnvironmentVariables) @@ -502,11 +499,7 @@ func (hnp *HumioNodePool) GetPodAnnotations() map[string]string { return hnp.humioNodeSpec.PodAnnotations } -func (hnp *HumioNodePool) GetAuthServiceAccountSecretName() string { - return fmt.Sprintf("%s-%s", hnp.GetNodePoolName(), authServiceAccountSecretNameIdentifier) -} - -func (hnp *HumioNodePool) GetInitServiceAccountSecretName() string { +func (hnp HumioNodePool) GetInitServiceAccountSecretName() string { return fmt.Sprintf("%s-%s", hnp.GetNodePoolName(), initServiceAccountSecretNameIdentifier) } @@ -521,17 +514,6 @@ func (hnp *HumioNodePool) InitServiceAccountIsSetByUser() bool { return hnp.humioNodeSpec.InitServiceAccountName != "" } -func (hnp *HumioNodePool) GetAuthServiceAccountName() string { - if hnp.humioNodeSpec.AuthServiceAccountName != "" { - return hnp.humioNodeSpec.AuthServiceAccountName - } - return fmt.Sprintf("%s-%s", hnp.GetNodePoolName(), authServiceAccountNameSuffix) -} - -func (hnp *HumioNodePool) AuthServiceAccountIsSetByUser() bool { - return hnp.humioNodeSpec.AuthServiceAccountName != "" -} - func (hnp *HumioNodePool) GetInitClusterRoleName() string { return fmt.Sprintf("%s-%s-%s", hnp.GetNamespace(), hnp.GetNodePoolName(), initClusterRoleSuffix) } @@ -540,14 +522,6 @@ func (hnp *HumioNodePool) GetInitClusterRoleBindingName() string { return fmt.Sprintf("%s-%s-%s", hnp.GetNamespace(), hnp.GetNodePoolName(), initClusterRoleBindingSuffix) } -func (hnp *HumioNodePool) GetAuthRoleName() string { - return fmt.Sprintf("%s-%s", hnp.GetNodePoolName(), authRoleSuffix) -} - -func (hnp *HumioNodePool) GetAuthRoleBindingName() string { - return fmt.Sprintf("%s-%s", hnp.GetNodePoolName(), authRoleBindingSuffix) -} - func (hnp *HumioNodePool) GetShareProcessNamespace() *bool { if hnp.humioNodeSpec.ShareProcessNamespace == nil { return helpers.BoolPtr(false) diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go new file mode 100644 index 00000000..48151683 --- /dev/null +++ b/controllers/humiocluster_permission_tokens.go @@ -0,0 +1,361 @@ +package controllers + +import ( + "context" + "fmt" + "os" + + "k8s.io/apimachinery/pkg/types" + + "github.com/humio/humio-operator/api/v1alpha1" + + "github.com/humio/humio-operator/pkg/kubernetes" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + humioapi "github.com/humio/cli/api" + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + // apiTokenMethodAnnotationName is used to signal what mechanism was used to obtain the API token + apiTokenMethodAnnotationName = "humio.com/api-token-method" // #nosec G101 + // apiTokenMethodFromAPI is used to indicate that the API token was obtained using an API call + apiTokenMethodFromAPI = "api" +) + +// getFileContent returns the content of a file as a string +func getFileContent(filePath string) string { + data, err := os.ReadFile(filePath) // #nosec G304 + if err != nil { + fmt.Printf("Got an error while trying to read file %s: %s\n", filePath, err) + return "" + } + return string(data) +} + +//// createNewAdminUser creates a new Humio admin user +//func (r *HumioClusterReconciler) createNewAdminUser(ctx context.Context, config *humioapi.Config, req reconcile.Request,, username string) error { +// isRoot := true +// return r.HumioClient.AddAdminUser(config, req) +// +//} + +// getApiTokenForUserID returns the API token for the given user ID +//func (r *HumioClusterReconciler) getApiTokenForUserID(config *humioapi.Config, req reconcile.Request, userID string) (string, string, error) { +// // Try using the API to rotate and get the API token +// r.HumioClient.RotateUserApiTokenAndGet(userID) +// if err == nil { +// // If API works, return the token +// fmt.Printf("Successfully rotated and extracted API token using the API.\n") +// return token, apiTokenMethodFromAPI, nil +// } +// +// return "", "", fmt.Errorf("could not rotate apiToken for userID %s, err: %w", userID, err) +//} + +//type user struct { +// Id string +// Username string +//} + +// listAllHumioUsersSingleOrg returns a list of all Humio users when running in single org mode with user ID and username +//func listAllHumioUsersSingleOrg(client *humio.Client) ([]user, error) { +// var q struct { +// Users []user `graphql:"users"` +// } +// err := client.Query(&q, nil) +// return q.Users, err +//} + +type OrganizationSearchResultEntry struct { + EntityId string `graphql:"entityId"` + SearchMatch string `graphql:"searchMatch"` + OrganizationName string `graphql:"organizationName"` +} + +type OrganizationSearchResultSet struct { + Results []OrganizationSearchResultEntry `graphql:"results"` +} + +// listAllHumioUsersMultiOrg returns a list of all Humio users when running in multi org mode with user ID and username +// TODO: move this to client api +//func listAllHumioUsersMultiOrg(username string, organization string, client *humio.Client) ([]OrganizationSearchResultEntry, error) { +// var q struct { +// OrganizationSearchResultSet `graphql:"searchOrganizations(searchFilter: $username, typeFilter: User, sortBy: Name, orderBy: ASC, limit: 1000000, skip: 0)"` +// } +// +// variables := map[string]interface{}{ +// "username": username, +// } +// +// err := client.Query(&q, variables) +// if err != nil { +// return []OrganizationSearchResultEntry{}, err +// } +// +// var allUserResultEntries []OrganizationSearchResultEntry +// for _, result := range q.OrganizationSearchResultSet.Results { +// //if result.OrganizationName == "RecoveryRootOrg" { +// if result.OrganizationName == organization { +// allUserResultEntries = append(allUserResultEntries, result) +// } +// } +// +// return allUserResultEntries, nil +//} + +// extractExistingHumioAdminUserID finds the user ID of the Humio user for the admin account, and returns +// empty string and no error if the user doesn't exist +func (r *HumioClusterReconciler) extractExistingHumioAdminUserID(config *humioapi.Config, req reconcile.Request, organizationMode string, username string, organization string) (string, error) { + if organizationMode == "multi" { + //var allUserResults []OrganizationSearchResultEntry + + allUserResults, err := r.HumioClient.ListAllHumioUsersMultiOrg(config, req, username, organization) // client.Users().List(username, organization, client) + if err != nil { + // unable to list all users + return "", err + } + // TODO: cleanup/remove duplicate code + for _, userResult := range allUserResults { + if userResult.OrganizationName == "RecoveryRootOrg" { + if userResult.SearchMatch == fmt.Sprintf(" | %s () ()", username) { + fmt.Printf("Found user ID using multi-organization query.\n") + return userResult.EntityId, nil + } + } + } + } + + allUsers, err := r.HumioClient.ListAllHumioUsersSingleOrg(config, req) + if err != nil { + // unable to list all users + return "", err + } + for _, user := range allUsers { + if user.Username == username { + fmt.Printf("Found user ID using single-organization query.\n") + return user.Id, nil + } + } + + return "", nil +} + +// createAndGetAdminAccountUserID ensures a Humio admin account exists and returns the user ID for it +func (r *HumioClusterReconciler) createAndGetAdminAccountUserID(ctx context.Context, config *humioapi.Config, req reconcile.Request, organizationMode string, username string, organization string) (string, error) { + // List all users and grab the user ID for an existing user + userID, err := r.extractExistingHumioAdminUserID(config, req, organizationMode, username, organization) + if err != nil { + // Error while grabbing the user ID + return "", err + } + if userID != "" { + // If we found a user ID, return it + return userID, nil + } + + // If we didn't find a user ID, create a user, extract the user ID and return it + user, err := r.HumioClient.AddUser(config, req, username, true) + if err != nil { + return "", err + } + userID, err = r.extractExistingHumioAdminUserID(config, req, organizationMode, username, organization) + if err != nil { + return "", err + } + if userID != "" { + // If we found a user ID, return it + return userID, nil + } + if userID != user.ID { + return "", fmt.Errorf("unexpected error. userid %s does not match %s", userID, user.ID) + } + + // Return error if we didn't find a valid user ID + return "", fmt.Errorf("could not obtain user ID") +} + +//validateAdminSecretContent grabs the current token stored in kubernetes and returns nil if it is valid +//func (r *HumioClusterReconciler) validateAdminSecretContent(ctx context.Context, hc *v1alpha1.HumioCluster, req reconcile.Request, adminSecretNameSuffix string, nodeURL *url.URL) error { +// // Get existing Kubernetes secret +// adminSecretName := fmt.Sprintf("%s-%s", hc.Name, adminSecretNameSuffix) +// secret := &corev1.Secret{} +// key := types.NamespacedName{ +// Name: adminSecretName, +// Namespace: hc.Namespace, +// } +// if err := r.Client.Get(ctx, key, secret); err != nil { +// return fmt.Errorf("got err while trying to get existing secret from k8s: %w", err) +// } +// +// // Check if secret currently holds a valid humio api token +// if adminToken, ok := secret.Data["token"]; ok { +// cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) +// clientNotReady := +// cluster.Config().Token != string(secret.Data["token"]) || +// cluster.Config().Address == nil +// if clientNotReady { +// cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) +// if err != nil { +// return err +// } +// } +// +// _, err = r.HumioClient.GetClusters(cluster.Config(), req) +// if err != nil { +// return fmt.Errorf("got err while trying to use apiToken: %w", err) +// } +// +// // We could successfully get information about the cluster, so the token must be valid +// return nil +// } +// return fmt.Errorf("Unable to validate if kubernetes secret %s holds a valid humio API token", adminSecretName) +//} + +// ensureAdminSecretContent ensures the target Kubernetes secret contains the desired API token +func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, hc *v1alpha1.HumioCluster, adminSecretNameSuffix string, desiredAPIToken string) error { + // Get existing Kubernetes secret + adminSecretName := fmt.Sprintf("%s-%s", hc.Name, adminSecretNameSuffix) + key := types.NamespacedName{ + Name: adminSecretName, + Namespace: hc.Namespace, + } + adminSecret := &corev1.Secret{} + err := r.Client.Get(ctx, key, adminSecret) + if k8serrors.IsNotFound(err) { + // If the secret doesn't exist, create it + desiredSecret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + Labels: kubernetes.LabelsForHumio(hc.Name), + }, + StringData: map[string]string{ + "token": desiredAPIToken, + }, + Type: corev1.SecretTypeOpaque, + } + if err := r.Client.Create(ctx, &desiredSecret); err != nil { + return r.logErrorAndReturn(err, "unable to create secret") + } + } + + // If we got no error, we compare current token with desired token and update if needed. + if adminSecret.StringData["token"] != desiredAPIToken { + adminSecret.StringData = map[string]string{"token": desiredAPIToken} + if err := r.Client.Update(ctx, adminSecret); err != nil { + return r.logErrorAndReturn(err, "unable to update secret") + } + } + + return nil +} + +// labelsForHumio returns the set of common labels for Humio resources. +// NB: There is a copy of this function in pkg/kubernetes/kubernetes.go to work around helper depending on main project. +//func labelsForHumio(clusterName string) map[string]string { +// labels := map[string]string{ +// "app.kubernetes.io/instance": clusterName, +// "app.kubernetes.io/managed-by": "humio-operator", +// "app.kubernetes.io/name": "humio", +// } +// return labels +//} + +// fileExists returns true if the specified path exists and is not a directory +func fileExists(path string) bool { + fileInfo, err := os.Stat(path) + if err != nil { + return false + } + return !fileInfo.IsDir() +} + +//func newKubernetesClientset() *k8s.Clientset { +// config, err := rest.InClusterConfig() +// if err != nil { +// panic(err.Error()) +// } +// +// clientset, err := k8s.NewForConfig(config) +// if err != nil { +// panic(err.Error()) +// } +// return clientset +//} + +func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, config *humioapi.Config, req reconcile.Request, hc *v1alpha1.HumioCluster, username string, organization string) error { + adminSecretNameSuffix := "admin-secret" + + // TODO: contstant? Run this in a separate function? + organizationMode := "single" + if EnvVarHasKey(hc.Spec.EnvironmentVariables, "ORGANIZATION_MODE") { + organizationMode = EnvVarValue(hc.Spec.EnvironmentVariables, "ORGANIZATION_MODE") + } + for _, pool := range hc.Spec.NodePools { + if EnvVarHasKey(pool.EnvironmentVariables, "ORGANIZATION_MODE") { + organizationMode = EnvVarValue(pool.EnvironmentVariables, "ORGANIZATION_MODE") + } + } + + // kubernetesClient := r.Client + + //for { + // // Check required files exist before we continue + // if !fileExists(localAdminTokenFile) { + // fmt.Printf("Waiting on the Humio container to create the files %s. Retrying in 5 seconds.\n", localAdminTokenFile) + // time.Sleep(5 * time.Second) + // continue + // } + // + // // Get local admin token and create humio client with it + // localAdminToken := getFileContent(localAdminTokenFile) + // if localAdminToken == "" { + // fmt.Printf("Local admin token file is empty. This might be due to Humio not being fully started up yet. Retrying in 5 seconds.\n") + // time.Sleep(5 * time.Second) + // continue + // } + // + // nodeURL, err := url.Parse(humioNodeURL) + // if err != nil { + // fmt.Printf("Unable to parse URL %s: %s\n", humioNodeURL, err) + // time.Sleep(5 * time.Second) + // continue + // } + + //humioClient := r.HumioClient.GetHumioClient(cluster.Config(), req) + //r.HumioClient.ListAllHumioUsersSingleOrg(config, req) + + //err := r.validateAdminSecretContent(ctx, config, req, namespace, clusterName, adminSecretNameSuffix) + //if err == nil { + // fmt.Printf("Existing token is still valid, thus no changes required. Will confirm again in 30 seconds.\n") + // time.Sleep(30 * time.Second) + // continue + //} + + //fmt.Printf("Could not validate existing admin secret: %s\n", err) + r.Log.Info("ensuring admin user") + + // Get user ID of admin account + userID, err := r.createAndGetAdminAccountUserID(ctx, config, req, organizationMode, username, organization) + if err != nil { + return fmt.Errorf("Got err trying to obtain user ID of admin user: %s\n", err) + } + + // Get API token for user ID of admin account + apiToken, err := r.HumioClient.RotateUserApiTokenAndGet(config, req, userID) + if err != nil { + return r.logErrorAndReturn(err, fmt.Sprintf("failed to rotate api key for userID %s", userID)) + } + + // Update Kubernetes secret if needed + err = r.ensureAdminSecretContent(ctx, hc, adminSecretNameSuffix, apiToken) + if err != nil { + return r.logErrorAndReturn(err, "unable to ensure admin secret") + + } + + return nil +} diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index c7b837ad..ce8628eb 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -41,7 +41,6 @@ import ( "github.com/humio/humio-operator/pkg/kubernetes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" ) const ( @@ -53,10 +52,10 @@ const ( ) type podAttachments struct { - dataVolumeSource corev1.VolumeSource - initServiceAccountSecretName string - authServiceAccountSecretName string - envVarSourceData *map[string]string + dataVolumeSource corev1.VolumeSource + initServiceAccountSecretName string + envVarSourceData *map[string]string + bootstrapTokenSecretReference *corev1.SecretKeySelector } // ConstructContainerArgs returns the container arguments for the Humio pods. We want to grab a UUID from zookeeper @@ -105,96 +104,6 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta Subdomain: headlessServiceName(hnp.GetClusterName()), Hostname: humioNodeName, Containers: []corev1.Container{ - { - Name: AuthContainerName, - Image: hnp.GetHelperImage(), - ImagePullPolicy: hnp.GetImagePullPolicy(), - Env: []corev1.EnvVar{ - { - Name: "NAMESPACE", - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "metadata.namespace", - }, - }, - }, - { - Name: "POD_NAME", - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "metadata.name", - }, - }, - }, - { - Name: "MODE", - Value: "auth", - }, - { - Name: "ADMIN_SECRET_NAME_SUFFIX", - Value: kubernetes.ServiceTokenSecretNameSuffix, - }, - { - Name: "CLUSTER_NAME", - Value: hnp.GetClusterName(), - }, - { - Name: "HUMIO_NODE_URL", - Value: fmt.Sprintf("%s://$(POD_NAME):%d/", strings.ToLower(string(hnp.GetProbeScheme())), HumioPort), - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "humio-data", - MountPath: HumioDataPath, - ReadOnly: true, - }, - { - Name: "auth-service-account-secret", - MountPath: "/var/run/secrets/kubernetes.io/serviceaccount", - ReadOnly: true, - }, - }, - ReadinessProbe: &corev1.Probe{ - FailureThreshold: 3, - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/", - Port: intstr.IntOrString{IntVal: 8180}, - Scheme: corev1.URISchemeHTTP, - }, - }, - PeriodSeconds: 10, - SuccessThreshold: 1, - TimeoutSeconds: 1, - }, - LivenessProbe: &corev1.Probe{ - FailureThreshold: 3, - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/", - Port: intstr.IntOrString{IntVal: 8180}, - Scheme: corev1.URISchemeHTTP, - }, - }, - PeriodSeconds: 10, - SuccessThreshold: 1, - TimeoutSeconds: 1, - }, - Resources: corev1.ResourceRequirements{ - Limits: corev1.ResourceList{ - corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), - corev1.ResourceMemory: *resource.NewQuantity(750*1024*1024, resource.BinarySI), - }, - Requests: corev1.ResourceList{ - corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), - corev1.ResourceMemory: *resource.NewQuantity(150*1024*1024, resource.BinarySI), - }, - }, - SecurityContext: hnp.GetContainerSecurityContext(), - }, { Name: HumioContainerName, Image: hnp.GetImage(), @@ -245,15 +154,6 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta Name: "tmp", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, }, - { - Name: "auth-service-account-secret", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: attachments.authServiceAccountSecretName, - DefaultMode: &mode, - }, - }, - }, }, Affinity: hnp.GetAffinity(), Tolerations: hnp.GetTolerations(), @@ -286,6 +186,9 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta } } + // TODO: restart pods when bootstrap token changes? + //attachments.bootstrapTokenSecretReference.Key + if EnvVarHasValue(pod.Spec.Containers[humioIdx].Env, "AUTHENTICATION_METHOD", "saml") { pod.Spec.Containers[humioIdx].Env = append(pod.Spec.Containers[humioIdx].Env, corev1.EnvVar{ Name: "SAML_IDP_CERTIFICATE", @@ -377,6 +280,15 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta }) } + if attachments.bootstrapTokenSecretReference != nil { + pod.Spec.Containers[humioIdx].Env = append(pod.Spec.Containers[humioIdx].Env, corev1.EnvVar{ + Name: "BOOTSTRAP_ROOT_TOKEN_HASHED", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: attachments.bootstrapTokenSecretReference, + }, + }) + } + if hnp.GetExtraKafkaConfigs() != "" { pod.Spec.Containers[humioIdx].Env = append(pod.Spec.Containers[humioIdx].Env, corev1.EnvVar{ Name: "EXTRA_KAFKA_CONFIGS_FILE", @@ -528,19 +440,6 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta MountPath: "/var/lib/humio/tls-certificate-secret", }) - // Configuration specific to auth container - authIdx, err := kubernetes.GetContainerIndexByName(pod, AuthContainerName) - if err != nil { - return &corev1.Pod{}, err - } - // We mount in the certificate on top of default system root certs so auth container automatically uses it: - // https://golang.org/src/crypto/x509/root_linux.go - pod.Spec.Containers[authIdx].VolumeMounts = append(pod.Spec.Containers[authIdx].VolumeMounts, corev1.VolumeMount{ - Name: "ca-cert", - ReadOnly: true, - MountPath: "/etc/pki/tls", - }) - // Common configuration for all containers pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ Name: "tls-cert", @@ -574,17 +473,6 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta pod.Spec.PriorityClassName = priorityClassName } - if EnvVarHasValue(pod.Spec.Containers[humioIdx].Env, "ENABLE_ORGANIZATIONS", "true") && EnvVarHasKey(pod.Spec.Containers[humioIdx].Env, "ORGANIZATION_MODE") { - authIdx, err := kubernetes.GetContainerIndexByName(pod, AuthContainerName) - if err != nil { - return &corev1.Pod{}, err - } - pod.Spec.Containers[authIdx].Env = append(pod.Spec.Containers[authIdx].Env, corev1.EnvVar{ - Name: "ORGANIZATION_MODE", - Value: EnvVarValue(pod.Spec.Containers[humioIdx].Env, "ORGANIZATION_MODE"), - }) - } - containerArgs, err := ConstructContainerArgs(hnp, pod.Spec.Containers[humioIdx].Env) if err != nil { return &corev1.Pod{}, fmt.Errorf("unable to construct node container args: %w", err) @@ -660,17 +548,6 @@ func sanitizePod(hnp *HumioNodePool, pod *corev1.Pod) *corev1.Pod { } } container.Env = sanitizedEnvVars - } else if container.Name == AuthContainerName { - for _, envVar := range container.Env { - if envVar.Name == "HUMIO_NODE_URL" { - sanitizedEnvVars = append(sanitizedEnvVars, corev1.EnvVar{ - Name: "HUMIO_NODE_URL", - Value: fmt.Sprintf("%s://%s-core-%s.%s:%d/", strings.ToLower(string(hnp.GetProbeScheme())), hnp.GetNodePoolName(), "", hnp.GetNamespace(), HumioPort), - }) - } else { - sanitizedEnvVars = append(sanitizedEnvVars, envVar) - } - } } else { sanitizedEnvVars = container.Env } @@ -1046,18 +923,10 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum if volumeSource.PersistentVolumeClaim != nil { pvcClaimNamesInUse[volumeSource.PersistentVolumeClaim.ClaimName] = struct{}{} } - authSASecretName, err := r.getAuthServiceAccountSecretName(ctx, hnp) - if err != nil { - return &podAttachments{}, fmt.Errorf("unable get auth service account secret for HumioCluster: %w", err) - } - if authSASecretName == "" { - return &podAttachments{}, errors.New("unable to create Pod for HumioCluster: the auth service account secret does not exist") - } if hnp.InitContainerDisabled() { return &podAttachments{ - dataVolumeSource: volumeSource, - authServiceAccountSecretName: authSASecretName, + dataVolumeSource: volumeSource, }, nil } @@ -1074,11 +943,25 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", err) } + key := types.NamespacedName{ + Namespace: hnp.GetNamespace(), + Name: hnp.GetBootstrapTokenName(), + } + hbt := &humiov1alpha1.HumioBootstrapToken{} + err = r.Client.Get(ctx, key, hbt) + if err != nil { + return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", err) + } + + if hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef == nil { + return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", fmt.Errorf("bootstraptoken %s does not contain a status for the hashed token secret reference", hnp.GetBootstrapTokenName())) + } + return &podAttachments{ - dataVolumeSource: volumeSource, - initServiceAccountSecretName: initSASecretName, - authServiceAccountSecretName: authSASecretName, - envVarSourceData: envVarSourceData, + dataVolumeSource: volumeSource, + initServiceAccountSecretName: initSASecretName, + envVarSourceData: envVarSourceData, + bootstrapTokenSecretReference: hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef, }, nil } diff --git a/controllers/humioexternalcluster_controller.go b/controllers/humioexternalcluster_controller.go index 6b56b179..f7497bcd 100644 --- a/controllers/humioexternalcluster_controller.go +++ b/controllers/humioexternalcluster_controller.go @@ -19,11 +19,12 @@ package controllers import ( "context" "fmt" + "time" + "github.com/humio/humio-operator/pkg/helpers" "github.com/humio/humio-operator/pkg/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "time" "github.com/go-logr/logr" ctrl "sigs.k8s.io/controller-runtime" @@ -79,7 +80,7 @@ func (r *HumioExternalClusterReconciler) Reconcile(ctx context.Context, req ctrl } } - cluster, err := helpers.NewCluster(ctx, r, "", hec.Name, hec.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, "", hec.Name, hec.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster.Config() == nil { return reconcile.Result{}, r.logErrorAndReturn(fmt.Errorf("unable to obtain humio client config: %w", err), "unable to obtain humio client config") } diff --git a/controllers/humioingesttoken_controller.go b/controllers/humioingesttoken_controller.go index f27b9f7d..f9bba373 100644 --- a/controllers/humioingesttoken_controller.go +++ b/controllers/humioingesttoken_controller.go @@ -20,6 +20,8 @@ import ( "context" "errors" "fmt" + "time" + "github.com/go-logr/logr" humioapi "github.com/humio/cli/api" "github.com/humio/humio-operator/pkg/helpers" @@ -30,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "time" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" "github.com/humio/humio-operator/pkg/humio" @@ -77,7 +78,7 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req r.Log = r.Log.WithValues("Request.UID", hit.UID) - cluster, err := helpers.NewCluster(ctx, r, hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName, hit.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName, hit.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioIngestTokenStateConfigError, hit) if setStateErr != nil { @@ -184,7 +185,7 @@ func (r *HumioIngestTokenReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *HumioIngestTokenReconciler) finalize(ctx context.Context, config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { - _, err := helpers.NewCluster(ctx, r, hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName, hit.Namespace, helpers.UseCertManager(), true) + _, err := helpers.NewCluster(ctx, r, hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName, hit.Namespace, helpers.UseCertManager(), true, false) if err != nil { if k8serrors.IsNotFound(err) { return nil diff --git a/controllers/humioparser_controller.go b/controllers/humioparser_controller.go index 14d15799..cc257d5a 100644 --- a/controllers/humioparser_controller.go +++ b/controllers/humioparser_controller.go @@ -77,7 +77,7 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) r.Log = r.Log.WithValues("Request.UID", hp.UID) - cluster, err := helpers.NewCluster(ctx, r, hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName, hp.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName, hp.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioParserStateConfigError, hp) if setStateErr != nil { @@ -201,7 +201,7 @@ func (r *HumioParserReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *HumioParserReconciler) finalize(ctx context.Context, config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) error { - _, err := helpers.NewCluster(ctx, r, hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName, hp.Namespace, helpers.UseCertManager(), true) + _, err := helpers.NewCluster(ctx, r, hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName, hp.Namespace, helpers.UseCertManager(), true, false) if err != nil { if k8serrors.IsNotFound(err) { return nil diff --git a/controllers/humiorepository_controller.go b/controllers/humiorepository_controller.go index ff4238e8..72299cfb 100644 --- a/controllers/humiorepository_controller.go +++ b/controllers/humiorepository_controller.go @@ -73,9 +73,13 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ return reconcile.Result{}, err } +<<<<<<< HEAD r.Log = r.Log.WithValues("Request.UID", hr.UID) cluster, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true) +======= + cluster, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true, false) +>>>>>>> 2e2b16a (wip) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioRepositoryStateConfigError, hr) if setStateErr != nil { @@ -189,12 +193,18 @@ func (r *HumioRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *HumioRepositoryReconciler) finalize(ctx context.Context, config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { +<<<<<<< HEAD _, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true) if err != nil { if k8serrors.IsNotFound(err) { return nil } return err +======= + _, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true, false) + if k8serrors.IsNotFound(err) { + return nil +>>>>>>> 2e2b16a (wip) } return r.HumioClient.DeleteRepository(config, req, hr) diff --git a/controllers/humioview_controller.go b/controllers/humioview_controller.go index e56e04e3..898fbbec 100644 --- a/controllers/humioview_controller.go +++ b/controllers/humioview_controller.go @@ -73,9 +73,13 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return reconcile.Result{}, err } +<<<<<<< HEAD r.Log = r.Log.WithValues("Request.UID", hv.UID) cluster, err := helpers.NewCluster(ctx, r, hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName, hv.Namespace, helpers.UseCertManager(), true) +======= + cluster, err := helpers.NewCluster(ctx, r, hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName, hv.Namespace, helpers.UseCertManager(), true, false) +>>>>>>> 2e2b16a (wip) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioParserStateConfigError, hv) if setStateErr != nil { diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index b62b8c99..5d155a5c 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -69,7 +69,7 @@ var _ = Describe("HumioCluster Controller", func() { // your API definition. // Avoid adding tests for vanilla CRUD operations because they would // test Kubernetes API server, which isn't the goal here. - Context("Humio Cluster Simple", func() { + FContext("Humio Cluster Simple", func() { It("Should bootstrap cluster correctly", func() { key := types.NamespacedName{ Name: "humiocluster-simple", @@ -1242,18 +1242,6 @@ var _ = Describe("HumioCluster Controller", func() { clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) - suite.UsingClusterBy(key.Name, "Validating pod uses default helper image as auth sidecar container") - Eventually(func() string { - clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) - _ = suite.MarkPodsAsRunning(ctx, k8sClient, clusterPods, key.Name) - - for _, pod := range clusterPods { - authIdx, _ := kubernetes.GetContainerIndexByName(pod, controllers.AuthContainerName) - return pod.Spec.InitContainers[authIdx].Image - } - return "" - }, testTimeout, suite.TestInterval).Should(Equal(controllers.HelperImage)) - suite.UsingClusterBy(key.Name, "Overriding helper image") var updatedHumioCluster humiov1alpha1.HumioCluster customHelperImage := "humio/humio-operator-helper:master" @@ -1279,16 +1267,6 @@ var _ = Describe("HumioCluster Controller", func() { return "" }, testTimeout, suite.TestInterval).Should(Equal(customHelperImage)) - suite.UsingClusterBy(key.Name, "Validating pod is recreated using the explicitly defined helper image as auth sidecar container") - Eventually(func() string { - clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) - for _, pod := range clusterPods { - authIdx, _ := kubernetes.GetContainerIndexByName(pod, controllers.AuthContainerName) - return pod.Spec.InitContainers[authIdx].Image - } - return "" - }, testTimeout, suite.TestInterval).Should(Equal(customHelperImage)) - updatedClusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { @@ -4143,7 +4121,6 @@ var _ = Describe("HumioCluster Controller", func() { } toCreate := suite.ConstructBasicSingleNodeHumioCluster(key, true) toCreate.Spec.InitServiceAccountName = "init-custom-service-account" - toCreate.Spec.AuthServiceAccountName = "auth-custom-service-account" toCreate.Spec.HumioServiceAccountName = "humio-custom-service-account" suite.UsingClusterBy(key.Name, "Creating the cluster successfully") @@ -4170,24 +4147,6 @@ var _ = Describe("HumioCluster Controller", func() { } } } - suite.UsingClusterBy(key.Name, "Confirming auth container is using the correct service account") - for _, pod := range clusterPods { - humioIdx, _ := kubernetes.GetContainerIndexByName(pod, controllers.AuthContainerName) - var serviceAccountSecretVolumeName string - for _, volumeMount := range pod.Spec.Containers[humioIdx].VolumeMounts { - if volumeMount.MountPath == "/var/run/secrets/kubernetes.io/serviceaccount" { - serviceAccountSecretVolumeName = volumeMount.Name - } - } - Expect(serviceAccountSecretVolumeName).To(Not(BeEmpty())) - for _, volume := range pod.Spec.Volumes { - if volume.Name == serviceAccountSecretVolumeName { - secret, err := kubernetes.GetSecret(ctx, k8sClient, volume.Secret.SecretName, key.Namespace) - Expect(err).ShouldNot(HaveOccurred()) - Expect(secret.ObjectMeta.Annotations[corev1.ServiceAccountNameKey]).To(Equal(toCreate.Spec.AuthServiceAccountName)) - } - } - } suite.UsingClusterBy(key.Name, "Confirming humio pod is using the correct service account") for _, pod := range clusterPods { Expect(pod.Spec.ServiceAccountName).To(Equal(toCreate.Spec.HumioServiceAccountName)) @@ -4201,7 +4160,6 @@ var _ = Describe("HumioCluster Controller", func() { } toCreate := suite.ConstructBasicSingleNodeHumioCluster(key, true) toCreate.Spec.InitServiceAccountName = "custom-service-account" - toCreate.Spec.AuthServiceAccountName = "custom-service-account" toCreate.Spec.HumioServiceAccountName = "custom-service-account" suite.UsingClusterBy(key.Name, "Creating the cluster successfully") @@ -4228,24 +4186,6 @@ var _ = Describe("HumioCluster Controller", func() { } } } - suite.UsingClusterBy(key.Name, "Confirming auth container is using the correct service account") - for _, pod := range clusterPods { - humioIdx, _ := kubernetes.GetContainerIndexByName(pod, controllers.AuthContainerName) - var serviceAccountSecretVolumeName string - for _, volumeMount := range pod.Spec.Containers[humioIdx].VolumeMounts { - if volumeMount.MountPath == "/var/run/secrets/kubernetes.io/serviceaccount" { - serviceAccountSecretVolumeName = volumeMount.Name - } - } - Expect(serviceAccountSecretVolumeName).To(Not(BeEmpty())) - for _, volume := range pod.Spec.Volumes { - if volume.Name == serviceAccountSecretVolumeName { - secret, err := kubernetes.GetSecret(ctx, k8sClient, volume.Secret.SecretName, key.Namespace) - Expect(err).ShouldNot(HaveOccurred()) - Expect(secret.ObjectMeta.Annotations[corev1.ServiceAccountNameKey]).To(Equal(toCreate.Spec.AuthServiceAccountName)) - } - } - } suite.UsingClusterBy(key.Name, "Confirming humio pod is using the correct service account") for _, pod := range clusterPods { Expect(pod.Spec.ServiceAccountName).To(Equal(toCreate.Spec.HumioServiceAccountName)) @@ -4498,9 +4438,6 @@ var _ = Describe("HumioCluster Controller", func() { if container.Name == controllers.HumioContainerName { continue } - if container.Name == controllers.AuthContainerName { - continue - } return container.Name } } diff --git a/controllers/suite/common.go b/controllers/suite/common.go index 8f88b02f..c0b72c96 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -33,10 +33,6 @@ import ( ) const ( - // apiTokenMethodAnnotationName is used to signal what mechanism was used to obtain the API token - apiTokenMethodAnnotationName = "humio.com/api-token-method" // #nosec G101 - // apiTokenMethodFromAPI is used to indicate that the API token was obtained using an API call - apiTokenMethodFromAPI = "api" // dockerUsernameEnvVar is used to login to docker when pulling images dockerUsernameEnvVar = "DOCKER_USERNAME" // dockerPasswordEnvVar is used to login to docker when pulling images @@ -118,22 +114,6 @@ func CleanupCluster(ctx context.Context, k8sClient client.Client, hc *humiov1alp Expect(k8sClient.Delete(ctx, serviceAccount)).To(Succeed()) } } - if cluster.Spec.AuthServiceAccountName != "" { - roleBinding, err := kubernetes.GetRoleBinding(ctx, k8sClient, cluster.Spec.AuthServiceAccountName, cluster.Namespace) - if err == nil { - Expect(k8sClient.Delete(ctx, roleBinding)).To(Succeed()) - } - - role, err := kubernetes.GetRole(ctx, k8sClient, cluster.Spec.AuthServiceAccountName, cluster.Namespace) - if err == nil { - Expect(k8sClient.Delete(ctx, role)).To(Succeed()) - } - - serviceAccount, err := kubernetes.GetServiceAccount(ctx, k8sClient, cluster.Spec.AuthServiceAccountName, cluster.Namespace) - if err == nil { - Expect(k8sClient.Delete(ctx, serviceAccount)).To(Succeed()) - } - } UsingClusterBy(cluster.Name, "Cleaning up any secrets for the cluster") var allSecrets corev1.SecretList @@ -376,34 +356,187 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum } } - if cluster.Spec.AuthServiceAccountName != "" { - if cluster.Spec.AuthServiceAccountName != cluster.Spec.HumioServiceAccountName { - UsingClusterBy(key.Name, "Creating service account for auth container") - authServiceAccount := kubernetes.ConstructServiceAccount(cluster.Spec.AuthServiceAccountName, cluster.Namespace, map[string]string{}, map[string]string{}) - Expect(k8sClient.Create(ctx, authServiceAccount)).To(Succeed()) - } - - UsingClusterBy(key.Name, "Creating role for auth container") - authRole := kubernetes.ConstructAuthRole(cluster.Spec.AuthServiceAccountName, key.Namespace, map[string]string{}) - Expect(k8sClient.Create(ctx, authRole)).To(Succeed()) - - UsingClusterBy(key.Name, "Creating role binding for auth container") - authRoleBinding := kubernetes.ConstructRoleBinding(cluster.Spec.AuthServiceAccountName, authRole.Name, key.Namespace, cluster.Spec.AuthServiceAccountName, map[string]string{}) - Expect(k8sClient.Create(ctx, authRoleBinding)).To(Succeed()) - } - if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { // Simulate sidecar creating the secret which contains the admin token used to authenticate with humio secretData := map[string][]byte{"token": []byte("")} - adminTokenSecretName := fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix) - UsingClusterBy(key.Name, "Simulating the auth container creating the secret containing the API token") - desiredSecret := kubernetes.ConstructSecret(key.Name, key.Namespace, adminTokenSecretName, secretData, nil) + authTokenSecretName := fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix) + UsingClusterBy(key.Name, "Simulating the auth token secret containing the API token") + desiredSecret := kubernetes.ConstructSecret(key.Name, key.Namespace, authTokenSecretName, secretData, nil) Expect(k8sClient.Create(ctx, desiredSecret)).To(Succeed()) - } + + UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") + humioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + //Spec: humiov1alpha1.HumioBootstrapTokenSpec{ + // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // }, + // Key: "hashedToken", + // }, + // }, + //}, + Status: humiov1alpha1.HumioBootstrapTokenStatus{ + TokenSecretKeyRef: humiov1alpha1.HumioTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + }, + Key: "secret", + }, + }, + HashedTokenSecretKeyRef: humiov1alpha1.HumioHashedTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + }, + Key: "hashedToken", + }}, + }, + } + UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") + Expect(k8sClient.Create(ctx, humioBootstrapToken)).Should(Succeed()) + } + + UsingClusterBy(key.Name, "Simulating the humio bootstrap token controller creating the secret containing the API token") + secretData := map[string][]byte{"hashedToken": []byte("P2HS9.20.r+ZbMqd0pHF65h3yQiOt8n1xNytv/4ePWKIj3cElP7gt8YD+gOtdGGvJYmG229kyFWLs6wXx9lfSDiRGGu/xuQ"), "secret": []byte("cYsrKi6IeyOJVzVIdmVK3M6RGl4y9GpgduYKXk4qWvvj")} + bootstrapTokenSecretName := fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix) + desiredSecret := kubernetes.ConstructSecret(key.Name, key.Namespace, bootstrapTokenSecretName, secretData, nil) + Expect(k8sClient.Create(ctx, desiredSecret)).To(Succeed()) + + //UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") + //humioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{ + // ObjectMeta: metav1.ObjectMeta{ + // Name: fmt.Sprintf(key.Name), + // Namespace: key.Namespace, + // }, + // Spec: humiov1alpha1.HumioBootstrapTokenSpec{ + // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token-test", key.Name), + // }, + // Key: "hashedToken", + // }, + // }, + // }, + // //Status: humiov1alpha1.HumioBootstrapTokenStatus{ + // // TokenSecretKeyRef: humiov1alpha1.HumioTokenSecretStatus{&corev1.SecretKeySelector{ + // // LocalObjectReference: corev1.LocalObjectReference{ + // // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // // }, + // // Key: "secret", + // // }, + // // }, + // // HashedTokenSecretKeyRef: humiov1alpha1.HumioHashedTokenSecretStatus{&corev1.SecretKeySelector{ + // // LocalObjectReference: corev1.LocalObjectReference{ + // // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // // }, + // // Key: "hashedToken", + // // }}, + // //}, + //} + + //UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") + //Expect(k8sClient.Create(ctx, humioBootstrapToken)).Should(Succeed()) + + //UsingClusterBy(key.Name, "Updating HumioBootstrapToken status") + //updatedHumioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{} + //humioBootstrapTokenKey := types.NamespacedName{ + // Namespace: humioBootstrapToken.Namespace, + // Name: humioBootstrapToken.Name, + //} + //Expect(k8sClient.Get(ctx, humioBootstrapTokenKey, updatedHumioBootstrapToken)).Should(Succeed()) + // + //updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // }, + // Key: "secret", + // }, + //} + //updatedHumioBootstrapToken.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // }, + // Key: "hashedToken", + // }, + //} + //Expect(k8sClient.Status().Update(ctx, updatedHumioBootstrapToken)).Should(Succeed()) + // + //Expect(k8sClient.Get(ctx, humioBootstrapTokenKey, updatedHumioBootstrapToken)).Should(Succeed()) + // + //updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // }, + // Key: "secret", + // }, + //} + //updatedHumioBootstrapToken.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // }, + // Key: "hashedToken", + // }, + //} + //Expect(k8sClient.Status().Update(ctx, updatedHumioBootstrapToken)).Should(Succeed()) + // + //Expect(k8sClient.Get(ctx, humioBootstrapTokenKey, updatedHumioBootstrapToken)).Should(Succeed()) + // + //updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // }, + // Key: "secret", + // }, + //} + //updatedHumioBootstrapToken.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + // }, + // Key: "hashedToken", + // }, + //} + //Expect(k8sClient.Status().Update(ctx, updatedHumioBootstrapToken)).Should(Succeed()) UsingClusterBy(key.Name, "Creating HumioCluster resource") Expect(k8sClient.Create(ctx, cluster)).Should(Succeed()) + UsingClusterBy(key.Name, "Simulating HumioBootstrapToken Controller running and adding the secret and status") + Eventually(func() error { + var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken + err := k8sClient.Get(ctx, key, &updatedHumioBootstrapToken) + if err != nil && !k8serrors.IsNotFound(err) { + Expect(err).Should(Succeed()) + } + updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + }, + Key: "secret", + }, + } + updatedHumioBootstrapToken.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + }, + Key: "hashedToken", + }, + } + return k8sClient.Status().Update(ctx, &updatedHumioBootstrapToken) + }, testTimeout, TestInterval).Should(Succeed()) + if expectedState != humiov1alpha1.HumioClusterStateRunning { return } @@ -492,7 +625,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum }, testTimeout, TestInterval).Should(HaveKeyWithValue(revisionKey, "1")) } - UsingClusterBy(key.Name, "Waiting for the auth sidecar to populate the secret containing the API token") + UsingClusterBy(key.Name, "Waiting for the bootstrap token controller to populate the secret containing the API token") Eventually(func() error { clusterPods, _ = kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster).GetCommonClusterLabels()) for idx := range clusterPods { @@ -501,33 +634,23 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum return k8sClient.Get(ctx, types.NamespacedName{ Namespace: key.Namespace, - Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix), + Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), }, &corev1.Secret{}) }, testTimeout, TestInterval).Should(Succeed()) - if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { - UsingClusterBy(key.Name, "Validating API token was obtained using the API method") - var apiTokenSecret corev1.Secret - Eventually(func() error { - return k8sClient.Get(ctx, types.NamespacedName{ - Namespace: key.Namespace, - Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix), - }, &apiTokenSecret) - }, testTimeout, TestInterval).Should(Succeed()) - Expect(apiTokenSecret.Annotations).Should(HaveKeyWithValue(apiTokenMethodAnnotationName, apiTokenMethodFromAPI)) - } - if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { UsingClusterBy(key.Name, "Validating cluster nodes have ZONE configured correctly") if updatedHumioCluster.Spec.DisableInitContainer { Eventually(func() []string { - clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), true) + clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), false, true) Expect(err).To(BeNil()) Expect(clusterConfig).ToNot(BeNil()) Expect(clusterConfig.Config()).ToNot(BeNil()) + //Expect(fmt.Sprintf("%+v", clusterConfig.Config())).To(Equal("")) + cluster, err := humioClient.GetClusters(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) - UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v", cluster, err)) + UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v, config: %v", cluster, err, clusterConfig.Config())) if err != nil { return []string{fmt.Sprintf("got err: %s", err)} } @@ -548,13 +671,15 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum }, testTimeout, TestInterval).Should(BeEmpty()) } else { Eventually(func() []string { - clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), true) + clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), false, true) Expect(err).To(BeNil()) Expect(clusterConfig).ToNot(BeNil()) Expect(clusterConfig.Config()).ToNot(BeNil()) cluster, err := humioClient.GetClusters(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) - UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v", cluster, err)) + //UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v", cluster, err)) + UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v, config: %v", cluster, err, clusterConfig.Config())) + if err != nil || len(cluster.Nodes) < 1 { return []string{} } diff --git a/controllers/suite/resources/humioresources_controller_test.go b/controllers/suite/resources/humioresources_controller_test.go index c3d88029..d9047a01 100644 --- a/controllers/suite/resources/humioresources_controller_test.go +++ b/controllers/suite/resources/humioresources_controller_test.go @@ -673,7 +673,7 @@ var _ = Describe("Humio Resources Controllers", func() { }, Spec: humiov1alpha1.HumioExternalClusterSpec{ Url: fmt.Sprintf("%s://%s.%s:8080/", protocol, clusterKey.Name, clusterKey.Namespace), - APITokenSecretName: fmt.Sprintf("%s-admin-token", clusterKey.Name), + APITokenSecretName: fmt.Sprintf("%s-bootstrap-token", clusterKey.Name), }, } diff --git a/controllers/suite/resources/suite_test.go b/controllers/suite/resources/suite_test.go index 0c49cb58..2dfbd0fc 100644 --- a/controllers/suite/resources/suite_test.go +++ b/controllers/suite/resources/suite_test.go @@ -261,7 +261,7 @@ var _ = BeforeSuite(func() { cluster.Spec.HumioNodeSpec.Image = "humio/humio-core:1.150.0" suite.CreateAndBootstrapCluster(context.TODO(), k8sClient, humioClient, cluster, true, corev1alpha1.HumioClusterStateRunning, testTimeout) - sharedCluster, err = helpers.NewCluster(context.TODO(), k8sClient, clusterKey.Name, "", clusterKey.Namespace, helpers.UseCertManager(), true) + sharedCluster, err = helpers.NewCluster(context.TODO(), k8sClient, clusterKey.Name, "", clusterKey.Namespace, helpers.UseCertManager(), true, false) Expect(err).To(BeNil()) Expect(sharedCluster).ToNot(BeNil()) Expect(sharedCluster.Config()).ToNot(BeNil()) diff --git a/examples/humiocluster-multi-nodepool-kind-local.yaml b/examples/humiocluster-multi-nodepool-kind-local.yaml index 1d079ded..3b989aae 100644 --- a/examples/humiocluster-multi-nodepool-kind-local.yaml +++ b/examples/humiocluster-multi-nodepool-kind-local.yaml @@ -1,7 +1,7 @@ apiVersion: core.humio.com/v1alpha1 kind: HumioCluster metadata: - name: example-humiocluster-3 + name: example-humiocluster spec: nodePools: - name: ingest-only @@ -33,7 +33,7 @@ spec: name: example-humiocluster-license key: data image: "humio/humio-core:1.82.1" - nodeCount: 1 + nodeCount: 0 tls: enabled: false targetReplicationFactor: 1 @@ -58,4 +58,4 @@ spec: - name: "ZOOKEEPER_URL" value: "humio-cp-zookeeper-0.humio-cp-zookeeper-headless.default:2181" - name: "KAFKA_SERVERS" - value: "humio-cp-kafka-0.humio-cp-kafka-headless.default:9092" \ No newline at end of file + value: "humio-cp-kafka-0.humio-cp-kafka-headless.default:9092" diff --git a/go.mod b/go.mod index b833a082..83e3d1a4 100644 --- a/go.mod +++ b/go.mod @@ -40,13 +40,16 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.52.3 // indirect diff --git a/go.sum b/go.sum index 78948ccb..d606f55e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cert-manager/cert-manager v1.12.12 h1:upG8EhS1bLdX1VlZkmKD2QBjld/aXtjVKvTsZkbWEQ4= @@ -52,6 +54,9 @@ github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQu github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce h1:WRVLad++Yerg08UcQCzAXY9UwV0P7U1lkOvrdMYUjVY= github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= @@ -68,6 +73,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -75,6 +82,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= diff --git a/pkg/helpers/clusterinterface.go b/pkg/helpers/clusterinterface.go index 83b4a0db..90c3cdd9 100644 --- a/pkg/helpers/clusterinterface.go +++ b/pkg/helpers/clusterinterface.go @@ -35,7 +35,7 @@ type ClusterInterface interface { Url(context.Context, client.Client) (*url.URL, error) Name() string Config() *humioapi.Config - constructHumioConfig(context.Context, client.Client, bool) (*humioapi.Config, error) + constructHumioConfig(context.Context, client.Client, bool, bool) (*humioapi.Config, error) } type Cluster struct { @@ -44,10 +44,11 @@ type Cluster struct { namespace string certManagerEnabled bool withAPIToken bool + withBootstrapToken bool humioConfig *humioapi.Config } -func NewCluster(ctx context.Context, k8sClient client.Client, managedClusterName, externalClusterName, namespace string, certManagerEnabled bool, withAPIToken bool) (ClusterInterface, error) { +func NewCluster(ctx context.Context, k8sClient client.Client, managedClusterName, externalClusterName, namespace string, certManagerEnabled bool, withAPIToken bool, withBootstrapToken bool) (ClusterInterface, error) { // Return error immediately if we do not have exactly one of the cluster names configured if managedClusterName != "" && externalClusterName != "" { return nil, fmt.Errorf("cannot have both ManagedClusterName and ExternalClusterName set at the same time") @@ -64,9 +65,10 @@ func NewCluster(ctx context.Context, k8sClient client.Client, managedClusterName namespace: namespace, certManagerEnabled: certManagerEnabled, withAPIToken: withAPIToken, + withBootstrapToken: withBootstrapToken, } - humioConfig, err := cluster.constructHumioConfig(ctx, k8sClient, withAPIToken) + humioConfig, err := cluster.constructHumioConfig(ctx, k8sClient, withAPIToken, withBootstrapToken) if err != nil { return nil, err } @@ -129,7 +131,7 @@ func (c Cluster) Config() *humioapi.Config { } // constructHumioConfig returns a config to use with Humio API client with the necessary CA and API token. -func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Client, withAPIToken bool) (*humioapi.Config, error) { +func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Client, withAPIToken bool, withBootstrapToken bool) (*humioapi.Config, error) { if c.managedClusterName != "" { // Lookup ManagedHumioCluster resource to figure out if we expect to use TLS or not var humioManagedCluster humiov1alpha1.HumioCluster @@ -159,11 +161,29 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie Name: fmt.Sprintf("%s-%s", c.managedClusterName, kubernetes.ServiceTokenSecretNameSuffix), }, &apiToken) if err != nil { - return nil, fmt.Errorf("unable to get secret containing api token: %w", err) + return nil, fmt.Errorf("unable to get admin secret containing api token: %w", err) } config.Token = string(apiToken.Data["token"]) } + var bootstrapToken corev1.Secret + if withBootstrapToken { + // Get API token + err = k8sClient.Get(ctx, types.NamespacedName{ + Namespace: c.namespace, + //Name: fmt.Sprintf("%s-%s", c.managedClusterName, kubernetes.ServiceTokenSecretNameSuffix), + // TODO: pass in BootstrapTokenSuffix + Name: fmt.Sprintf("%s-bootstrap-token", c.managedClusterName), + }, &bootstrapToken) + if err != nil { + return nil, fmt.Errorf("unable to get bootstrap secret containing api token: %w", err) + } + if _, ok := bootstrapToken.Data["secret"]; !ok { + return nil, fmt.Errorf("unable to get bootstrap secret containing api token. secret does not contain key named \"secret\"") + } + config.Token = fmt.Sprintf("localroot~%s", string(bootstrapToken.Data["secret"])) + } + // If we do not use TLS, return a client without CA certificate if !c.certManagerEnabled || !TLSEnabled(&humioManagedCluster) { config.Insecure = true diff --git a/pkg/helpers/clusterinterface_test.go b/pkg/helpers/clusterinterface_test.go index 45dd5fbe..2cab38f4 100644 --- a/pkg/helpers/clusterinterface_test.go +++ b/pkg/helpers/clusterinterface_test.go @@ -152,8 +152,18 @@ func TestCluster_HumioConfig_managedHumioCluster(t *testing.T) { Name: fmt.Sprintf("%s-admin-token", tt.managedHumioCluster.Name), Namespace: tt.managedHumioCluster.Namespace, }, - StringData: map[string]string{ - "token": "secret-api-token", + Data: map[string][]byte{ + "token": []byte("secret-api-token"), + }, + } + bootstrapTokenSecret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-bootstrap-token", tt.managedHumioCluster.Name), + Namespace: tt.managedHumioCluster.Namespace, + }, + Data: map[string][]byte{ + "hashedToken": []byte("hashed-token"), + "secret": []byte("secret-api-token"), }, } caCertificateSecret := corev1.Secret{ @@ -168,6 +178,7 @@ func TestCluster_HumioConfig_managedHumioCluster(t *testing.T) { objs := []runtime.Object{ &tt.managedHumioCluster, &apiTokenSecret, + &bootstrapTokenSecret, &caCertificateSecret, } // Register operator types with the runtime scheme. @@ -176,7 +187,7 @@ func TestCluster_HumioConfig_managedHumioCluster(t *testing.T) { cl := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - cluster, err := NewCluster(context.Background(), cl, tt.managedHumioCluster.Name, "", tt.managedHumioCluster.Namespace, tt.certManagerEnabled, true) + cluster, err := NewCluster(context.Background(), cl, tt.managedHumioCluster.Name, "", tt.managedHumioCluster.Namespace, tt.certManagerEnabled, true, false) if err != nil || cluster.Config() == nil { t.Errorf("unable to obtain humio client config: %s", err) } @@ -338,7 +349,7 @@ func TestCluster_HumioConfig_externalHumioCluster(t *testing.T) { t.Run(tt.name, func(t *testing.T) { apiTokenSecretName := tt.externalHumioCluster.Spec.APITokenSecretName if apiTokenSecretName == "" { - apiTokenSecretName = fmt.Sprintf("%s-unspecified-api-token", tt.externalHumioCluster.Name) + apiTokenSecretName = fmt.Sprintf("%s-unspecified-admin-token", tt.externalHumioCluster.Name) } apiTokenSecret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -373,7 +384,7 @@ func TestCluster_HumioConfig_externalHumioCluster(t *testing.T) { cl := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - cluster, err := NewCluster(context.Background(), cl, "", tt.externalHumioCluster.Name, tt.externalHumioCluster.Namespace, false, true) + cluster, err := NewCluster(context.Background(), cl, "", tt.externalHumioCluster.Name, tt.externalHumioCluster.Namespace, false, true, false) if tt.expectedConfigFailure && (err == nil) { t.Errorf("unable to get a valid config: %s", err) } @@ -483,8 +494,9 @@ func TestCluster_NewCluster(t *testing.T) { Name: "managed-admin-token", Namespace: "default", }, - StringData: map[string]string{ - "token": "secret-api-token", + Data: map[string][]byte{ + "hashedToken": []byte("secret-api-token"), + "secret": []byte("secret-api-token"), }, } @@ -500,7 +512,7 @@ func TestCluster_NewCluster(t *testing.T) { cl := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - _, err := NewCluster(context.Background(), cl, tt.managedClusterName, tt.externalClusterName, tt.namespace, false, true) + _, err := NewCluster(context.Background(), cl, tt.managedClusterName, tt.externalClusterName, tt.namespace, false, true, false) if tt.expectError == (err == nil) { t.Fatalf("expectError: %+v but got=%+v", tt.expectError, err) } diff --git a/pkg/humio/client.go b/pkg/humio/client.go index 77a81013..0f573aea 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -48,6 +48,7 @@ type Client interface { FilterAlertsClient AggregateAlertsClient ScheduledSearchClient + UsersClient } type ClusterClient interface { @@ -131,6 +132,14 @@ type LicenseClient interface { InstallLicense(*humioapi.Config, reconcile.Request, string) error } +type UsersClient interface { + AddUser(*humioapi.Config, reconcile.Request, string, bool) (*humioapi.User, error) + ListAllHumioUsersSingleOrg(*humioapi.Config, reconcile.Request) ([]user, error) + ListAllHumioUsersMultiOrg(*humioapi.Config, reconcile.Request, string, string) ([]OrganizationSearchResultEntry, error) + ExtractExistingHumioAdminUserID(*humioapi.Config, reconcile.Request, string, string, string) (string, error) + RotateUserApiTokenAndGet(*humioapi.Config, reconcile.Request, string) (string, error) +} + // ClientConfig stores our Humio api client type ClientConfig struct { humioClients map[humioClientKey]*humioClientConnection @@ -898,3 +907,102 @@ func (h *ClientConfig) ValidateActionsForAggregateAlert(config *humioapi.Config, } return nil } + +type user struct { + Id string + Username string +} + +type OrganizationSearchResultEntry struct { + EntityId string `graphql:"entityId"` + SearchMatch string `graphql:"searchMatch"` + OrganizationName string `graphql:"organizationName"` +} + +type OrganizationSearchResultSet struct { + Results []OrganizationSearchResultEntry `graphql:"results"` +} + +func (h *ClientConfig) ListAllHumioUsersSingleOrg(config *humioapi.Config, req reconcile.Request) ([]user, error) { + var q struct { + Users []user `graphql:"users"` + } + err := h.GetHumioClient(config, req).Query(&q, nil) + return q.Users, err +} + +func (h *ClientConfig) ListAllHumioUsersMultiOrg(config *humioapi.Config, req reconcile.Request, username string, organization string) ([]OrganizationSearchResultEntry, error) { + var q struct { + OrganizationSearchResultSet `graphql:"searchOrganizations(searchFilter: $username, typeFilter: User, sortBy: Name, orderBy: ASC, limit: 1000000, skip: 0)"` + } + + variables := map[string]interface{}{ + "username": username, + } + + err := h.GetHumioClient(config, req).Query(&q, variables) + if err != nil { + return []OrganizationSearchResultEntry{}, err + } + + var allUserResultEntries []OrganizationSearchResultEntry + for _, result := range q.OrganizationSearchResultSet.Results { + //if result.OrganizationName == "RecoveryRootOrg" { + if result.OrganizationName == organization { + allUserResultEntries = append(allUserResultEntries, result) + } + } + + return allUserResultEntries, nil +} + +func (h *ClientConfig) ExtractExistingHumioAdminUserID(config *humioapi.Config, req reconcile.Request, organizationMode string, username string, organization string) (string, error) { + if organizationMode == "multi" { + var allUserResults []OrganizationSearchResultEntry + allUserResults, err := h.ListAllHumioUsersMultiOrg(config, req, username, organization) + if err != nil { + // unable to list all users + return "", err + } + for _, userResult := range allUserResults { + if userResult.OrganizationName == "RecoveryRootOrg" { + if userResult.SearchMatch == fmt.Sprintf(" | %s () ()", username) { + fmt.Printf("Found user ID using multi-organization query.\n") + return userResult.EntityId, nil + } + } + } + } + + allUsers, err := h.ListAllHumioUsersSingleOrg(config, req) + if err != nil { + // unable to list all users + return "", err + } + for _, user := range allUsers { + if user.Username == username { + fmt.Printf("Found user ID using single-organization query.\n") + return user.Id, nil + } + } + + return "", nil +} + +func (h *ClientConfig) RotateUserApiTokenAndGet(config *humioapi.Config, req reconcile.Request, userID string) (string, error) { + token, err := h.GetHumioClient(config, req).Users().RotateUserApiTokenAndGet(userID) + if err != nil { + return "", fmt.Errorf("could not rotate apiToken for userID %s, err: %w", userID, err) + } + return token, nil +} + +func (h *ClientConfig) AddUser(config *humioapi.Config, req reconcile.Request, username string, isRoot bool) (*humioapi.User, error) { + user, err := h.GetHumioClient(config, req).Users().Add(username, humioapi.UserChangeSet{ + IsRoot: &isRoot, + }) + if err != nil { + return &humioapi.User{}, err + } + return &user, nil +} diff --git a/pkg/humio/client_mock.go b/pkg/humio/client_mock.go index 68f413e4..be302735 100644 --- a/pkg/humio/client_mock.go +++ b/pkg/humio/client_mock.go @@ -20,10 +20,11 @@ import ( "crypto/sha512" "encoding/hex" "fmt" - "github.com/humio/humio-operator/pkg/helpers" "net/url" "sync" + "github.com/humio/humio-operator/pkg/helpers" + humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" "github.com/humio/humio-operator/pkg/kubernetes" @@ -59,6 +60,8 @@ type ClientMock struct { FilterAlert map[resourceKey]humioapi.FilterAlert AggregateAlert map[resourceKey]humioapi.AggregateAlert ScheduledSearch map[resourceKey]humioapi.ScheduledSearch + + User humioapi.User } type MockClientConfig struct { @@ -80,6 +83,8 @@ func NewMockClient() *MockClientConfig { FilterAlert: make(map[resourceKey]humioapi.FilterAlert), AggregateAlert: make(map[resourceKey]humioapi.AggregateAlert), ScheduledSearch: make(map[resourceKey]humioapi.ScheduledSearch), + + User: humioapi.User{}, }, } @@ -965,3 +970,28 @@ func (h *MockClientConfig) searchDomainNameExists(clusterName, searchDomainName return false } + +func (h *MockClientConfig) ListAllHumioUsersSingleOrg(config *humioapi.Config, req reconcile.Request) ([]user, error) { + return []user{}, nil +} + +func (h *MockClientConfig) ListAllHumioUsersMultiOrg(config *humioapi.Config, req reconcile.Request, username string, organization string) ([]OrganizationSearchResultEntry, error) { + return []OrganizationSearchResultEntry{}, nil +} + +func (h *MockClientConfig) ExtractExistingHumioAdminUserID(config *humioapi.Config, req reconcile.Request, organizationMode string, username string, organization string) (string, error) { + return "", nil +} + +func (h *MockClientConfig) RotateUserApiTokenAndGet(config *humioapi.Config, req reconcile.Request, userID string) (string, error) { + return "", nil +} + +func (h *MockClientConfig) AddUser(config *humioapi.Config, req reconcile.Request, username string, isRoot bool) (*humioapi.User, error) { + h.apiClient.User = humioapi.User{ + ID: "id", + Username: username, + IsRoot: isRoot, + } + return &h.apiClient.User, nil +} diff --git a/pkg/kubernetes/secrets.go b/pkg/kubernetes/secrets.go index e699bacd..7e819a38 100644 --- a/pkg/kubernetes/secrets.go +++ b/pkg/kubernetes/secrets.go @@ -27,8 +27,9 @@ import ( ) const ( - ServiceTokenSecretNameSuffix = "admin-token" - SecretNameLabelName = "humio.com/secret-identifier" // #nosec G101 + ServiceTokenSecretNameSuffix = "admin-token" + BootstrapTokenSecretNameSuffix = "bootstrap-token" + SecretNameLabelName = "humio.com/secret-identifier" // #nosec G101 ) // LabelsForSecret returns a map of labels which contains a common set of labels and additional user-defined secret labels. From 30cf39f9f4a491d2c54817931919a3c45164bef0 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 23 Aug 2023 08:43:49 -0700 Subject: [PATCH 06/54] WIP --- controllers/humiocluster_controller.go | 17 ++- controllers/humiocluster_permission_tokens.go | 131 ++++++++++-------- controllers/humiocluster_pods.go | 43 +++--- .../humioexternalcluster_controller.go | 2 +- .../clusters/humiocluster_controller_test.go | 6 +- controllers/suite/common.go | 23 ++- .../humioresources_controller_test.go | 2 +- examples/humiobootstraptoken.yaml | 6 + ...umiocluster-multi-nodepool-kind-local.yaml | 6 + pkg/humio/client.go | 1 - 10 files changed, 141 insertions(+), 96 deletions(-) create mode 100644 examples/humiobootstraptoken.yaml diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index 758bfdea..7a6010ca 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -497,7 +497,9 @@ func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Co if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { return r.logErrorAndReturn(err, "could not set controller reference") } + return nil } + return r.logErrorAndReturn(err, "could not get bootstrap token resource") } return nil } @@ -1394,6 +1396,11 @@ func (r *HumioClusterReconciler) ensureLicense(ctx context.Context, hc *humiov1a // At this point we know a non-empty license has been returned by the Humio API, // so we can continue to parse the license and issue a license update if needed. if existingLicense == nil || existingLicense == noLicense { + cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false, true) + if err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "could not install initial license") + } + if err = r.HumioClient.InstallLicense(cluster.Config(), req, licenseStr); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not install initial license") } @@ -1404,9 +1411,12 @@ func (r *HumioClusterReconciler) ensureLicense(ctx context.Context, hc *humiov1a } cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false, true) - if err = r.HumioClient.InstallLicense(cluster.Config(), req, licenseStr); err != nil { + if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not authenticate with bootstrap token") } + if err = r.HumioClient.InstallLicense(cluster.Config(), req, licenseStr); err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "could not install license") + } // TODO: ensureLicense should be broken into multiple steps if err = r.ensurePermissionTokens(ctx, cluster.Config(), req, hc); err != nil { @@ -1441,6 +1451,11 @@ func (r *HumioClusterReconciler) ensureLicense(ctx context.Context, hc *humiov1a return reconcile.Result{}, nil } +func (r *HumioClusterReconciler) ensurePermissionTokens(ctx context.Context, config *humioapi.Config, req reconcile.Request, hc *humiov1alpha1.HumioCluster) error { + r.Log.Info("ensuring permission tokens") + return r.createPermissionToken(ctx, config, req, hc, "admin", "RootOrg") +} + func (r *HumioClusterReconciler) ensureService(ctx context.Context, hc *humiov1alpha1.HumioCluster, hnp *HumioNodePool) error { r.Log.Info("ensuring service") existingService, err := kubernetes.GetService(ctx, r, hnp.GetNodePoolName(), hnp.GetNamespace()) diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go index 48151683..54a009bb 100644 --- a/controllers/humiocluster_permission_tokens.go +++ b/controllers/humiocluster_permission_tokens.go @@ -5,17 +5,20 @@ import ( "fmt" "os" + "github.com/humio/humio-operator/pkg/helpers" + + "github.com/humio/humio-operator/pkg/kubernetes" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/kubernetes" "sigs.k8s.io/controller-runtime/pkg/reconcile" humioapi "github.com/humio/cli/api" corev1 "k8s.io/api/core/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -135,7 +138,6 @@ func (r *HumioClusterReconciler) extractExistingHumioAdminUserID(config *humioap } for _, user := range allUsers { if user.Username == username { - fmt.Printf("Found user ID using single-organization query.\n") return user.Id, nil } } @@ -177,69 +179,76 @@ func (r *HumioClusterReconciler) createAndGetAdminAccountUserID(ctx context.Cont return "", fmt.Errorf("could not obtain user ID") } -//validateAdminSecretContent grabs the current token stored in kubernetes and returns nil if it is valid -//func (r *HumioClusterReconciler) validateAdminSecretContent(ctx context.Context, hc *v1alpha1.HumioCluster, req reconcile.Request, adminSecretNameSuffix string, nodeURL *url.URL) error { -// // Get existing Kubernetes secret -// adminSecretName := fmt.Sprintf("%s-%s", hc.Name, adminSecretNameSuffix) -// secret := &corev1.Secret{} -// key := types.NamespacedName{ -// Name: adminSecretName, -// Namespace: hc.Namespace, -// } -// if err := r.Client.Get(ctx, key, secret); err != nil { -// return fmt.Errorf("got err while trying to get existing secret from k8s: %w", err) -// } -// -// // Check if secret currently holds a valid humio api token -// if adminToken, ok := secret.Data["token"]; ok { -// cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) -// clientNotReady := -// cluster.Config().Token != string(secret.Data["token"]) || -// cluster.Config().Address == nil -// if clientNotReady { -// cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) -// if err != nil { -// return err -// } -// } -// -// _, err = r.HumioClient.GetClusters(cluster.Config(), req) -// if err != nil { -// return fmt.Errorf("got err while trying to use apiToken: %w", err) -// } -// -// // We could successfully get information about the cluster, so the token must be valid -// return nil -// } -// return fmt.Errorf("Unable to validate if kubernetes secret %s holds a valid humio API token", adminSecretName) -//} +// validateAdminSecretContent grabs the current token stored in kubernetes and returns nil if it is valid +func (r *HumioClusterReconciler) validateAdminSecretContent(ctx context.Context, hc *v1alpha1.HumioCluster, req reconcile.Request) error { + // Get existing Kubernetes secret + adminSecretName := fmt.Sprintf("%s-%s", hc.Name, kubernetes.ServiceTokenSecretNameSuffix) + secret := &corev1.Secret{} + key := types.NamespacedName{ + Name: adminSecretName, + Namespace: hc.Namespace, + } + if err := r.Client.Get(ctx, key, secret); err != nil { + return fmt.Errorf("got err while trying to get existing secret from k8s: %w", err) + } + + // Check if secret currently holds a valid humio api token + if _, ok := secret.Data["token"]; ok { + cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) + if err != nil { + return fmt.Errorf("got err while trying to authenticate using apiToken: %w", err) + } + clientNotReady := + cluster.Config().Token != string(secret.Data["token"]) || + cluster.Config().Address == nil + if clientNotReady { + _, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) + if err != nil { + return fmt.Errorf("got err while trying to authenticate using apiToken: %w", err) + } + } + + _, err = r.HumioClient.GetClusters(cluster.Config(), req) + if err != nil { + return fmt.Errorf("got err while trying to use apiToken: %w", err) + } + + // We could successfully get information about the cluster, so the token must be valid + return nil + } + return fmt.Errorf("Unable to validate if kubernetes secret %s holds a valid humio API token", adminSecretName) +} // ensureAdminSecretContent ensures the target Kubernetes secret contains the desired API token -func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, hc *v1alpha1.HumioCluster, adminSecretNameSuffix string, desiredAPIToken string) error { +func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, hc *v1alpha1.HumioCluster, desiredAPIToken string) error { // Get existing Kubernetes secret - adminSecretName := fmt.Sprintf("%s-%s", hc.Name, adminSecretNameSuffix) + adminSecretName := fmt.Sprintf("%s-%s", hc.Name, kubernetes.ServiceTokenSecretNameSuffix) key := types.NamespacedName{ Name: adminSecretName, Namespace: hc.Namespace, } adminSecret := &corev1.Secret{} err := r.Client.Get(ctx, key, adminSecret) - if k8serrors.IsNotFound(err) { - // If the secret doesn't exist, create it - desiredSecret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: key.Name, - Namespace: key.Namespace, - Labels: kubernetes.LabelsForHumio(hc.Name), - }, - StringData: map[string]string{ - "token": desiredAPIToken, - }, - Type: corev1.SecretTypeOpaque, - } - if err := r.Client.Create(ctx, &desiredSecret); err != nil { - return r.logErrorAndReturn(err, "unable to create secret") + if err != nil { + if k8serrors.IsNotFound(err) { + // If the secret doesn't exist, create it + desiredSecret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + Labels: kubernetes.LabelsForHumio(hc.Name), + }, + StringData: map[string]string{ + "token": desiredAPIToken, + }, + Type: corev1.SecretTypeOpaque, + } + if err := r.Client.Create(ctx, &desiredSecret); err != nil { + return r.logErrorAndReturn(err, "unable to create secret") + } + return nil } + return r.logErrorAndReturn(err, "unable to get secret") } // If we got no error, we compare current token with desired token and update if needed. @@ -287,7 +296,7 @@ func fileExists(path string) bool { //} func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, config *humioapi.Config, req reconcile.Request, hc *v1alpha1.HumioCluster, username string, organization string) error { - adminSecretNameSuffix := "admin-secret" + //adminSecretNameSuffix := "admin-token" // TODO: contstant? Run this in a separate function? organizationMode := "single" @@ -344,6 +353,10 @@ func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, conf return fmt.Errorf("Got err trying to obtain user ID of admin user: %s\n", err) } + if err := r.validateAdminSecretContent(ctx, hc, req); err == nil { + return nil + } + // Get API token for user ID of admin account apiToken, err := r.HumioClient.RotateUserApiTokenAndGet(config, req, userID) if err != nil { @@ -351,7 +364,7 @@ func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, conf } // Update Kubernetes secret if needed - err = r.ensureAdminSecretContent(ctx, hc, adminSecretNameSuffix, apiToken) + err = r.ensureAdminSecretContent(ctx, hc, apiToken) if err != nil { return r.logErrorAndReturn(err, "unable to ensure admin secret") diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index ce8628eb..42234e58 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -585,16 +585,7 @@ func sanitizePod(hnp *HumioNodePool, pod *corev1.Pod) *corev1.Pod { }, }, }) - } else if volume.Name == "auth-service-account-secret" { - sanitizedVolumes = append(sanitizedVolumes, corev1.Volume{ - Name: "auth-service-account-secret", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: fmt.Sprintf("%s-auth-%s", hnp.GetNodePoolName(), ""), - DefaultMode: &mode, - }, - }, - }) + } else if strings.HasPrefix("kube-api-access-", volume.Name) { sanitizedVolumes = append(sanitizedVolumes, corev1.Volume{ Name: "kube-api-access-", @@ -924,20 +915,6 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum pvcClaimNamesInUse[volumeSource.PersistentVolumeClaim.ClaimName] = struct{}{} } - if hnp.InitContainerDisabled() { - return &podAttachments{ - dataVolumeSource: volumeSource, - }, nil - } - - initSASecretName, err := r.getInitServiceAccountSecretName(ctx, hnp) - if err != nil { - return &podAttachments{}, fmt.Errorf("unable get init service account secret for HumioCluster: %w", err) - } - if initSASecretName == "" { - return &podAttachments{}, errors.New("unable to create Pod for HumioCluster: the init service account secret does not exist") - } - envVarSourceData, err := r.getEnvVarSource(ctx, hnp) if err != nil { return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", err) @@ -950,13 +927,29 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum hbt := &humiov1alpha1.HumioBootstrapToken{} err = r.Client.Get(ctx, key, hbt) if err != nil { - return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", err) + return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster. could not find HumioBootstrapToken: %w", err) } if hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef == nil { return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", fmt.Errorf("bootstraptoken %s does not contain a status for the hashed token secret reference", hnp.GetBootstrapTokenName())) } + if hnp.InitContainerDisabled() { + return &podAttachments{ + dataVolumeSource: volumeSource, + envVarSourceData: envVarSourceData, + bootstrapTokenSecretReference: hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef, + }, nil + } + + initSASecretName, err := r.getInitServiceAccountSecretName(ctx, hnp) + if err != nil { + return &podAttachments{}, fmt.Errorf("unable get init service account secret for HumioCluster: %w", err) + } + if initSASecretName == "" { + return &podAttachments{}, errors.New("unable to create Pod for HumioCluster: the init service account secret does not exist") + } + return &podAttachments{ dataVolumeSource: volumeSource, initServiceAccountSecretName: initSASecretName, diff --git a/controllers/humioexternalcluster_controller.go b/controllers/humioexternalcluster_controller.go index f7497bcd..c27b5dec 100644 --- a/controllers/humioexternalcluster_controller.go +++ b/controllers/humioexternalcluster_controller.go @@ -87,7 +87,7 @@ func (r *HumioExternalClusterReconciler) Reconcile(ctx context.Context, req ctrl err = r.HumioClient.TestAPIToken(cluster.Config(), req) if err != nil { - r.Log.Error(err, "unable to test if the API token is works") + r.Log.Error(err, fmt.Sprintf("unable to test if the API token is works. client: %+v", cluster.Config())) err = r.Client.Get(ctx, req.NamespacedName, hec) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "unable to get cluster state") diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index 5d155a5c..efb0b468 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -69,7 +69,7 @@ var _ = Describe("HumioCluster Controller", func() { // your API definition. // Avoid adding tests for vanilla CRUD operations because they would // test Kubernetes API server, which isn't the goal here. - FContext("Humio Cluster Simple", func() { + Context("Humio Cluster Simple", func() { It("Should bootstrap cluster correctly", func() { key := types.NamespacedName{ Name: "humiocluster-simple", @@ -3292,7 +3292,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) - initialExpectedVolumesCount := 6 + initialExpectedVolumesCount := 5 initialExpectedVolumeMountsCount := 4 if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { @@ -4376,7 +4376,7 @@ var _ = Describe("HumioCluster Controller", func() { if pod.Spec.ShareProcessNamespace != nil { Expect(*pod.Spec.ShareProcessNamespace).To(BeFalse()) } - Expect(pod.Spec.Containers).Should(HaveLen(2)) + Expect(pod.Spec.Containers).Should(HaveLen(1)) } suite.UsingClusterBy(key.Name, "Enabling shared process namespace and sidecars") diff --git a/controllers/suite/common.go b/controllers/suite/common.go index c0b72c96..01753527 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -364,7 +364,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum desiredSecret := kubernetes.ConstructSecret(key.Name, key.Namespace, authTokenSecretName, secretData, nil) Expect(k8sClient.Create(ctx, desiredSecret)).To(Succeed()) - UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") + UsingClusterBy(key.Name, "Simulating the creation of the HumioBootstrapToken resource") humioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{ ObjectMeta: metav1.ObjectMeta{ Name: key.Name, @@ -625,7 +625,20 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum }, testTimeout, TestInterval).Should(HaveKeyWithValue(revisionKey, "1")) } - UsingClusterBy(key.Name, "Waiting for the bootstrap token controller to populate the secret containing the API token") + //UsingClusterBy(key.Name, "Waiting for the bootstrap token controller to populate the secret containing the bootstrap token") + //Eventually(func() error { + // clusterPods, _ = kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster).GetCommonClusterLabels()) + // for idx := range clusterPods { + // UsingClusterBy(key.Name, fmt.Sprintf("Pod status %s status: %v", clusterPods[idx].Name, clusterPods[idx].Status)) + // } + // + // return k8sClient.Get(ctx, types.NamespacedName{ + // Namespace: key.Namespace, + // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), + // }, &corev1.Secret{}) + //}, testTimeout, TestInterval).Should(Succeed()) + + UsingClusterBy(key.Name, "Waiting for the controller to populate the secret containing the admin token") Eventually(func() error { clusterPods, _ = kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster).GetCommonClusterLabels()) for idx := range clusterPods { @@ -634,7 +647,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum return k8sClient.Get(ctx, types.NamespacedName{ Namespace: key.Namespace, - Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), + Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix), }, &corev1.Secret{}) }, testTimeout, TestInterval).Should(Succeed()) @@ -642,7 +655,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum UsingClusterBy(key.Name, "Validating cluster nodes have ZONE configured correctly") if updatedHumioCluster.Spec.DisableInitContainer { Eventually(func() []string { - clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), false, true) + clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), true, false) Expect(err).To(BeNil()) Expect(clusterConfig).ToNot(BeNil()) Expect(clusterConfig.Config()).ToNot(BeNil()) @@ -671,7 +684,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum }, testTimeout, TestInterval).Should(BeEmpty()) } else { Eventually(func() []string { - clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), false, true) + clusterConfig, err := helpers.NewCluster(ctx, k8sClient, key.Name, "", key.Namespace, helpers.UseCertManager(), true, false) Expect(err).To(BeNil()) Expect(clusterConfig).ToNot(BeNil()) Expect(clusterConfig.Config()).ToNot(BeNil()) diff --git a/controllers/suite/resources/humioresources_controller_test.go b/controllers/suite/resources/humioresources_controller_test.go index d9047a01..c3d88029 100644 --- a/controllers/suite/resources/humioresources_controller_test.go +++ b/controllers/suite/resources/humioresources_controller_test.go @@ -673,7 +673,7 @@ var _ = Describe("Humio Resources Controllers", func() { }, Spec: humiov1alpha1.HumioExternalClusterSpec{ Url: fmt.Sprintf("%s://%s.%s:8080/", protocol, clusterKey.Name, clusterKey.Namespace), - APITokenSecretName: fmt.Sprintf("%s-bootstrap-token", clusterKey.Name), + APITokenSecretName: fmt.Sprintf("%s-admin-token", clusterKey.Name), }, } diff --git a/examples/humiobootstraptoken.yaml b/examples/humiobootstraptoken.yaml new file mode 100644 index 00000000..93ce328f --- /dev/null +++ b/examples/humiobootstraptoken.yaml @@ -0,0 +1,6 @@ +apiVersion: core.humio.com/v1alpha1 +kind: HumioBootstrapToken +metadata: + name: example-bootstraptoken +spec: + managedClusterName: example-humiocluster diff --git a/examples/humiocluster-multi-nodepool-kind-local.yaml b/examples/humiocluster-multi-nodepool-kind-local.yaml index 3b989aae..61094fa3 100644 --- a/examples/humiocluster-multi-nodepool-kind-local.yaml +++ b/examples/humiocluster-multi-nodepool-kind-local.yaml @@ -3,9 +3,11 @@ kind: HumioCluster metadata: name: example-humiocluster spec: + #disableInitContainer: true nodePools: - name: ingest-only spec: + #disableInitContainer: true image: "humio/humio-core:1.82.1" nodeCount: 1 dataVolumePersistentVolumeClaimSpecTemplate: @@ -28,6 +30,10 @@ spec: value: "humio-cp-zookeeper-0.humio-cp-zookeeper-headless.default:2181" - name: "KAFKA_SERVERS" value: "humio-cp-kafka-0.humio-cp-kafka-headless.default:9092" + # - name: "STATIC_USERS" + # value: "user:user" + - name: "AUTHENTICATION_METHOD" + value: "static" license: secretKeyRef: name: example-humiocluster-license diff --git a/pkg/humio/client.go b/pkg/humio/client.go index 0f573aea..bc359458 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -981,7 +981,6 @@ func (h *ClientConfig) ExtractExistingHumioAdminUserID(config *humioapi.Config, } for _, user := range allUsers { if user.Username == username { - fmt.Printf("Found user ID using single-organization query.\n") return user.Id, nil } } From c716b7d5dceda617d8e9c693126056fc5960df36 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 30 Aug 2023 10:02:28 -0700 Subject: [PATCH 07/54] WIP --- controllers/humiobootstraptoken_controller.go | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index d1a99f76..e733d997 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -42,6 +42,13 @@ import ( humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" ) +const ( + // BootstrapTokenSecretHashedTokenName is the name of the hashed token key inside the bootstrap token secret + BootstrapTokenSecretHashedTokenName = "hashedToken" + // BootstrapTokenSecretName is the name of the secret key inside the bootstrap token secret + BootstrapTokenSecretName = "secret" +) + // HumioBootstrapTokenReconciler reconciles a HumioBootstrapToken object type HumioBootstrapTokenReconciler struct { client.Client @@ -301,14 +308,13 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont } }(ctx, hbt, hc) - // TODO: make tokenHash constant - if _, ok := bootstrapTokenSecret.Data["hashedToken"]; ok { + if _, ok := bootstrapTokenSecret.Data[BootstrapTokenSecretHashedTokenName]; ok { return nil } commandArgs := []string{"/bin/bash", "/app/humio/humio/bin/humio-run-class.sh", "com.humio.main.TokenHashing", "--json"} - if tokenSecret, ok := bootstrapTokenSecret.Data["secret"]; ok { + if tokenSecret, ok := bootstrapTokenSecret.Data[BootstrapTokenSecretName]; ok { commandArgs = append(commandArgs, string(tokenSecret)) } @@ -317,8 +323,24 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont return err } - // TODO: wait for pod to start - time.Sleep(time.Second * 10) + var podRunning bool + for i := 0; i < waitForPodTimeoutSeconds; i++ { + latestPodList, err := kubernetes.ListPods(ctx, r, hbt.GetNamespace(), hbt.GetLabels()) + if err != nil { + return err + } + for _, pod := range latestPodList { + if pod.Status.Phase == corev1.PodRunning { + podRunning = true + break + } + } + r.Log.Info("waiting for bootstrap token pod to start") + time.Sleep(time.Second * 1) + } + if !podRunning { + return r.logErrorAndReturn(err, "failed to start bootstrap token pod") + } r.Log.Info("execing onetime pod") output, err := r.execCommand(pod, commandArgs) @@ -337,7 +359,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont return err } // TODO: make tokenHash constant - updatedSecret.Data = map[string][]byte{"hashedToken": []byte(secretData.HashedToken), "secret": []byte(secretData.Secret)} + updatedSecret.Data = map[string][]byte{BootstrapTokenSecretHashedTokenName: []byte(secretData.HashedToken), BootstrapTokenSecretName: []byte(secretData.Secret)} if err = r.Update(ctx, updatedSecret); err != nil { return r.logErrorAndReturn(err, "failed to update secret with hashedToken data") From aee0ee1a782fa14862d1c86f249bfeca296f2e82 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 21 Sep 2023 14:58:52 -0700 Subject: [PATCH 08/54] WIP --- controllers/humiocluster_annotations.go | 11 ++- controllers/humiocluster_controller.go | 9 +- controllers/humiocluster_pods.go | 91 ++++++++++++++++--- .../clusters/humiocluster_controller_test.go | 66 ++++++++++++++ examples/humiocluster-kind-local.yaml | 4 +- 5 files changed, 161 insertions(+), 20 deletions(-) diff --git a/controllers/humiocluster_annotations.go b/controllers/humiocluster_annotations.go index 3a5f51ef..1cc8836d 100644 --- a/controllers/humiocluster_annotations.go +++ b/controllers/humiocluster_annotations.go @@ -31,11 +31,12 @@ import ( ) const ( - certHashAnnotation = "humio.com/certificate-hash" - PodHashAnnotation = "humio.com/pod-hash" - PodRevisionAnnotation = "humio.com/pod-revision" - envVarSourceHashAnnotation = "humio.com/env-var-source-hash" - pvcHashAnnotation = "humio_pvc_hash" + certHashAnnotation = "humio.com/certificate-hash" + PodHashAnnotation = "humio.com/pod-hash" + PodRevisionAnnotation = "humio.com/pod-revision" + envVarSourceHashAnnotation = "humio.com/env-var-source-hash" + pvcHashAnnotation = "humio_pvc_hash" + bootstrapTokenHashAnnotation = "humio.com/bootstrap-token-hash" ) func (r *HumioClusterReconciler) incrementHumioClusterPodRevision(ctx context.Context, hc *humiov1alpha1.HumioCluster, hnp *HumioNodePool) (int, error) { diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index 7a6010ca..e4ad2495 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -1941,8 +1941,15 @@ func (r *HumioClusterReconciler) ensureMismatchedPodsAreDeleted(ctx context.Cont if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "failed to get bootstrap token") } + if hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef != nil { - attachments.bootstrapTokenSecretReference = hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef + attachments.bootstrapTokenSecretReference.secretReference = hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef + + bootstrapTokenHash, err := r.getDesiredBootstrapTokenHash(ctx, hnp) + if err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "unable to find bootstrap token secret") + } + attachments.bootstrapTokenSecretReference.hash = bootstrapTokenHash } // prioritize deleting the pods with errors diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index 42234e58..b44efcdb 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -55,7 +55,12 @@ type podAttachments struct { dataVolumeSource corev1.VolumeSource initServiceAccountSecretName string envVarSourceData *map[string]string - bootstrapTokenSecretReference *corev1.SecretKeySelector + bootstrapTokenSecretReference bootstrapTokenSecret +} + +type bootstrapTokenSecret struct { + hash string + secretReference *corev1.SecretKeySelector } // ConstructContainerArgs returns the container arguments for the Humio pods. We want to grab a UUID from zookeeper @@ -186,9 +191,6 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta } } - // TODO: restart pods when bootstrap token changes? - //attachments.bootstrapTokenSecretReference.Key - if EnvVarHasValue(pod.Spec.Containers[humioIdx].Env, "AUTHENTICATION_METHOD", "saml") { pod.Spec.Containers[humioIdx].Env = append(pod.Spec.Containers[humioIdx].Env, corev1.EnvVar{ Name: "SAML_IDP_CERTIFICATE", @@ -280,11 +282,11 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta }) } - if attachments.bootstrapTokenSecretReference != nil { + if attachments.bootstrapTokenSecretReference.secretReference != nil { pod.Spec.Containers[humioIdx].Env = append(pod.Spec.Containers[humioIdx].Env, corev1.EnvVar{ Name: "BOOTSTRAP_ROOT_TOKEN_HASHED", ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: attachments.bootstrapTokenSecretReference, + SecretKeyRef: attachments.bootstrapTokenSecretReference.secretReference, }, }) } @@ -468,6 +470,11 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta }) } + if attachments.bootstrapTokenSecretReference.hash != "" { + pod.Annotations[bootstrapTokenHashAnnotation] = attachments.bootstrapTokenSecretReference.hash + //pod.Annotations[bootstrapTokenHashAnnotation] = "asdf" + } + //pod.Annotations[bootstrapTokenHashAnnotation] = "asdf" priorityClassName := hnp.GetPriorityClassName() if priorityClassName != "" { pod.Spec.PriorityClassName = priorityClassName @@ -652,6 +659,15 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha return &corev1.Pod{}, r.logErrorAndReturn(err, "unable to find pod name") } + //var bootstrapTokenHash string + //if attachments.bootstrapTokenSecretReference.secretReference != nil { + bootstrapTokenHash, err := r.getDesiredBootstrapTokenHash(ctx, hnp) + if err != nil { + return &corev1.Pod{}, r.logErrorAndReturn(err, "unable to find bootstrap token secret") + } + attachments.bootstrapTokenSecretReference.hash = bootstrapTokenHash + //} + pod, err := ConstructPod(hnp, podNameAndCertHash.podName, attachments) if err != nil { return &corev1.Pod{}, r.logErrorAndReturn(err, "unable to construct pod") @@ -675,6 +691,11 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha pod.Annotations[certHashAnnotation] = podNameAndCertHash.certificateHash } + //if attachments.bootstrapTokenSecretReference.secretReference != nil { + // pod.Annotations[bootstrapTokenHashAnnotation] = bootstrapTokenHash + // //pod.Annotations[bootstrapTokenHashAnnotation] = "asdf2" + //} + _, podRevision := hnp.GetHumioClusterNodePoolRevisionAnnotation() r.setPodRevision(pod, podRevision) @@ -735,6 +756,7 @@ func (r *HumioClusterReconciler) podsMatch(hnp *HumioNodePool, pod corev1.Pod, d var revisionMatches bool var envVarSourceMatches bool var certHasAnnotationMatches bool + var bootstrapTokenAnootationMatches bool desiredPodHash := podSpecAsSHA256(hnp, desiredPod) _, existingPodRevision := hnp.GetHumioClusterNodePoolRevisionAnnotation() @@ -765,6 +787,16 @@ func (r *HumioClusterReconciler) podsMatch(hnp *HumioNodePool, pod corev1.Pod, d certHasAnnotationMatches = true } } + if _, ok := pod.Annotations[bootstrapTokenHashAnnotation]; ok { + if pod.Annotations[bootstrapTokenHashAnnotation] == desiredPod.Annotations[bootstrapTokenHashAnnotation] { + bootstrapTokenAnootationMatches = true + } + } else { + // Ignore bootstrapTokenHashAnnotation if it's not in either the current pod or the desired pod + if _, ok := desiredPod.Annotations[bootstrapTokenHashAnnotation]; !ok { + bootstrapTokenAnootationMatches = true + } + } currentPodCopy := pod.DeepCopy() desiredPodCopy := desiredPod.DeepCopy() @@ -787,6 +819,10 @@ func (r *HumioClusterReconciler) podsMatch(hnp *HumioNodePool, pod corev1.Pod, d r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", certHashAnnotation, pod.Annotations[certHashAnnotation], desiredPod.Annotations[certHashAnnotation]), "podSpecDiff", podSpecDiff) return false, nil } + if !bootstrapTokenAnootationMatches { + r.Log.Info(fmt.Sprintf("pod annotation %s bootstrapTokenAnootationMatches not match desired pod: got %+v, expected %+v", bootstrapTokenHashAnnotation, pod.Annotations[bootstrapTokenHashAnnotation], desiredPod.Annotations[bootstrapTokenHashAnnotation]), "podSpecDiff", podSpecDiff) + return false, nil + } return true, nil } @@ -808,6 +844,10 @@ func (r *HumioClusterReconciler) getPodDesiredLifecycleState(hnp *HumioNodePool, desiredPod.Annotations[certHashAnnotation] = GetDesiredCertHash(hnp) } + if attachments.bootstrapTokenSecretReference.secretReference != nil { + desiredPod.Annotations[bootstrapTokenHashAnnotation] = attachments.bootstrapTokenSecretReference.hash + } + podsMatch, err := r.podsMatch(hnp, pod, *desiredPod) if err != nil { r.Log.Error(err, "failed to check if pods match") @@ -850,6 +890,27 @@ type podNameAndCertificateHash struct { podName, certificateHash string } +func (r *HumioClusterReconciler) getDesiredBootstrapTokenHash(ctx context.Context, hnp *HumioNodePool) (string, error) { + + existingSecret := &corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ + Namespace: hnp.GetNamespace(), + Name: fmt.Sprintf("%s-%s", hnp.GetClusterName(), kubernetes.BootstrapTokenSecretNameSuffix), + }, existingSecret) + + //return fmt.Sprintf("+%v", existingSecret), nil + if err != nil { + return fmt.Sprintf("%v", err), err + } + + if ok := string(existingSecret.Data[BootstrapTokenSecretHashedTokenName]); ok != "" { + return helpers.AsSHA256(string(existingSecret.Data[BootstrapTokenSecretHashedTokenName])), nil + } + + //// TODO: Should we error here? + return fmt.Sprintf("%v", err), fmt.Errorf("secret does not contain key %s", BootstrapTokenSecretHashedTokenName) +} + // findHumioNodeNameAndCertHash looks up the name of a free node certificate to use and the hash of the certificate specification func findHumioNodeNameAndCertHash(ctx context.Context, c client.Client, hnp *HumioNodePool, newlyCreatedPods []corev1.Pod) (podNameAndCertificateHash, error) { // if we do not have TLS enabled, append a random suffix @@ -936,9 +997,11 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum if hnp.InitContainerDisabled() { return &podAttachments{ - dataVolumeSource: volumeSource, - envVarSourceData: envVarSourceData, - bootstrapTokenSecretReference: hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef, + dataVolumeSource: volumeSource, + envVarSourceData: envVarSourceData, + bootstrapTokenSecretReference: bootstrapTokenSecret{ + secretReference: hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef, + }, }, nil } @@ -951,10 +1014,12 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum } return &podAttachments{ - dataVolumeSource: volumeSource, - initServiceAccountSecretName: initSASecretName, - envVarSourceData: envVarSourceData, - bootstrapTokenSecretReference: hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef, + dataVolumeSource: volumeSource, + initServiceAccountSecretName: initSASecretName, + envVarSourceData: envVarSourceData, + bootstrapTokenSecretReference: bootstrapTokenSecret{ + secretReference: hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef, + }, }, nil } diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index efb0b468..44c2b491 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -1276,6 +1276,72 @@ var _ = Describe("HumioCluster Controller", func() { }) }) + Context("Humio Cluster Rotate Bootstrap Token", func() { + It("Update should correctly replace pods to use new bootstrap token", func() { + key := types.NamespacedName{ + Name: "humiocluster-rotate-bootstrap-token", + Namespace: testProcessNamespace, + } + toCreate := suite.ConstructBasicSingleNodeHumioCluster(key, true) + toCreate.Spec.NodeCount = 2 + + suite.UsingClusterBy(key.Name, "Creating a cluster") + ctx := context.Background() + suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + defer suite.CleanupCluster(ctx, k8sClient, toCreate) + + suite.UsingClusterBy(key.Name, "Validating pod bootstrap token annotation hash") + //var bootstrapTokenHash string + Eventually(func() string { + clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) + _ = suite.MarkPodsAsRunning(ctx, k8sClient, clusterPods, key.Name) + + if len(clusterPods) > 0 { + return clusterPods[0].Annotations["humio.com/bootstrap-token-hash"] + } + return "" + }, testTimeout, suite.TestInterval).Should(Not(Equal(""))) + + clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) + bootstrapTokenHashValue := clusterPods[0].Annotations["humio.com/bootstrap-token-hash"] + + suite.UsingClusterBy(key.Name, "Rotating bootstrap token") + var bootstrapTokenSecret corev1.Secret + + bootstrapTokenSecretKey := types.NamespacedName{ + Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), + Namespace: key.Namespace, + } + Expect(k8sClient.Get(ctx, bootstrapTokenSecretKey, &bootstrapTokenSecret)).To(BeNil()) + bootstrapTokenSecret.Data["hashedToken"] = []byte("some new token") + Expect(k8sClient.Update(ctx, &bootstrapTokenSecret)).To(BeNil()) + + var updatedHumioCluster humiov1alpha1.HumioCluster + Expect(k8sClient.Get(ctx, key, &updatedHumioCluster)).To(BeNil()) + + suite.UsingClusterBy(key.Name, "Restarting the cluster in a rolling fashion") + ensurePodsRollingRestart(ctx, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster), 2) + + suite.UsingClusterBy(key.Name, "Validating pod is recreated with the new bootstrap token hash annotation") + Eventually(func() string { + clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) + _ = suite.MarkPodsAsRunning(ctx, k8sClient, clusterPods, key.Name) + + if len(clusterPods) > 0 { + return clusterPods[0].Annotations["humio.com/bootstrap-token-hash"] + } + return "" + }, testTimeout, suite.TestInterval).Should(Not(Equal(bootstrapTokenHashValue))) + + updatedClusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) + + if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { + suite.UsingClusterBy(key.Name, "Ensuring pod names are not changed") + Expect(podNames(clusterPods)).To(Equal(podNames(updatedClusterPods))) + } + }) + }) + Context("Humio Cluster Update Environment Variable", func() { It("Should correctly replace pods to use new environment variable", func() { key := types.NamespacedName{ diff --git a/examples/humiocluster-kind-local.yaml b/examples/humiocluster-kind-local.yaml index 9938d68d..9ad0801c 100644 --- a/examples/humiocluster-kind-local.yaml +++ b/examples/humiocluster-kind-local.yaml @@ -33,4 +33,6 @@ spec: - name: "ZOOKEEPER_URL" value: "humio-cp-zookeeper-0.humio-cp-zookeeper-headless.default:2181" - name: "KAFKA_SERVERS" - value: "humio-cp-kafka-0.humio-cp-kafka-headless.default:9092" \ No newline at end of file + value: "humio-cp-kafka-0.humio-cp-kafka-headless.default:9092" + - name: "AUTHENTICATION_METHOD" + value: "static" From 2a41d47f210c28ce70dcc28595afa85771ebcb71 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 22 Sep 2023 14:59:33 -0700 Subject: [PATCH 09/54] Fix client --- pkg/humio/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/humio/client.go b/pkg/humio/client.go index bc359458..d4092f82 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -989,7 +989,7 @@ func (h *ClientConfig) ExtractExistingHumioAdminUserID(config *humioapi.Config, } func (h *ClientConfig) RotateUserApiTokenAndGet(config *humioapi.Config, req reconcile.Request, userID string) (string, error) { - token, err := h.GetHumioClient(config, req).Users().RotateUserApiTokenAndGet(userID) + token, err := h.GetHumioClient(config, req).Users().RotateToken(userID) if err != nil { return "", fmt.Errorf("could not rotate apiToken for userID %s, err: %w", userID, err) } From 5299760a7f3067f44d2726b97efd01ee9abb74b1 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 22 Sep 2023 15:33:03 -0700 Subject: [PATCH 10/54] Fix go dep --- go.sum | 63 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/go.sum b/go.sum index d606f55e..e545337a 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -34,8 +34,8 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -50,15 +50,12 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240415144954-be81aee2d733 h1:nHRIUuWr4qaFmeHwGBzW5QtiLr3Zy5EXjnRpFG9RarE= +github.com/google/pprof v0.0.0-20240415144954-be81aee2d733/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce h1:WRVLad++Yerg08UcQCzAXY9UwV0P7U1lkOvrdMYUjVY= -github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= +github.com/humio/cli v0.35.1 h1:CwfGI5K79qHzEK51BCdbYUXthVPsUDY+3w1b0tO11S4= +github.com/humio/cli v0.35.1/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -84,10 +81,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -106,6 +103,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -119,52 +117,50 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -173,6 +169,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.29.5 h1:levS+umUigHCfI3riD36pMY1vQEbrzh4r1ivVWAhHaI= From 452c0b3ec2ba2e4ab05225de18aa354463611887 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 22 Sep 2023 15:46:01 -0700 Subject: [PATCH 11/54] Fix helm --- .../crds/core.humio.com_humiobootstraptokens.yaml | 2 +- config/crd/bases/core.humio.com_humiobootstraptokens.yaml | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index d8f1438b..b16b0b0f 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -12,7 +12,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.19.0' + helm.sh/chart: 'humio-operator-0.20.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 97ac2c68..9632d101 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humiobootstraptokens.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.20.0' spec: group: core.humio.com names: From 9f06ef72549474c58c1c3ee29fb040d79f2a1d24 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 28 Sep 2023 10:35:08 -0700 Subject: [PATCH 12/54] some cleanup --- api/v1alpha1/humiobootstraptoken_types.go | 14 +-- api/v1alpha1/zz_generated.deepcopy.go | 8 +- .../core.humio.com_humiobootstraptokens.yaml | 18 ++-- .../core.humio.com_humiobootstraptokens.yaml | 87 ++++++++----------- controllers/humiobootstraptoken_controller.go | 84 ++++++++++-------- controllers/humiobootstraptoken_defaults.go | 22 ++--- controllers/humiocluster_controller.go | 21 +++-- main.go | 5 ++ pkg/helpers/clusterinterface.go | 35 +++++--- 9 files changed, 159 insertions(+), 135 deletions(-) diff --git a/api/v1alpha1/humiobootstraptoken_types.go b/api/v1alpha1/humiobootstraptoken_types.go index 57d0cdd9..d78e72e7 100644 --- a/api/v1alpha1/humiobootstraptoken_types.go +++ b/api/v1alpha1/humiobootstraptoken_types.go @@ -43,22 +43,22 @@ type HumioBootstrapTokenSpec struct { } type HumioTokenSecretSpec struct { - // TODO: we could clean this up by removing the "CreateIfMissing" and in docs explain if you want to use your own secret + // TODO: we could clean this up by removing the "AutoCreate" and in docs explain if you want to use your own secret // then create the secret before the bootstraptoken resource - CreateIfMissing *bool `json:"createIfMissing,omitempty"` - SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` + AutoCreate *bool `json:"autoCreate,omitempty"` + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } type HumioHashedTokenSecretSpec struct { - // TODO: maybe remove CreateIfMissing - CreateIfMissing *bool `json:"createIfMissing,omitempty"` - SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` + // TODO: maybe remove AutoCreate + AutoCreate *bool `json:"autoCreate,omitempty"` + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } type HumioBootstrapTokenStatus struct { // TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec // here as the spec could be empty. Or do we want to - Created bool `json:"created,omitempty"` + //Created bool `json:"created,omitempty"` TokenSecretKeyRef HumioTokenSecretStatus `json:"tokenSecretStatus,omitempty"` HashedTokenSecretKeyRef HumioHashedTokenSecretStatus `json:"hashedTokenSecretStatus,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 62745822..98fa63c5 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -926,8 +926,8 @@ func (in *HumioFilterAlertSpec) DeepCopy() *HumioFilterAlertSpec { ======= func (in *HumioHashedTokenSecretSpec) DeepCopyInto(out *HumioHashedTokenSecretSpec) { *out = *in - if in.CreateIfMissing != nil { - in, out := &in.CreateIfMissing, &out.CreateIfMissing + if in.AutoCreate != nil { + in, out := &in.AutoCreate, &out.AutoCreate *out = new(bool) **out = **in } @@ -1643,8 +1643,8 @@ func (in *HumioRetention) DeepCopy() *HumioRetention { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioTokenSecretSpec) DeepCopyInto(out *HumioTokenSecretSpec) { *out = *in - if in.CreateIfMissing != nil { - in, out := &in.CreateIfMissing, &out.CreateIfMissing + if in.AutoCreate != nil { + in, out := &in.AutoCreate, &out.AutoCreate *out = new(bool) **out = **in } diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index b16b0b0f..870787af 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -56,8 +56,8 @@ spec: type: string hashedTokenSecret: properties: - createIfMissing: - description: 'TODO: maybe remove CreateIfMissing' + autoCreate: + description: 'TODO: maybe remove AutoCreate' type: boolean secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -86,8 +86,8 @@ spec: type: string tokenSecret: properties: - createIfMissing: - description: 'TODO: we could clean this up by removing the "CreateIfMissing" + autoCreate: + description: 'TODO: we could clean this up by removing the "AutoCreate" and in docs explain if you want to use your own secret then create the secret before the bootstraptoken resource' type: boolean @@ -113,12 +113,6 @@ spec: type: object status: properties: - created: - description: TODO set the status. This is used by the HumioCluster - resource to get the secret reference and load the secret. We don't - want to rely on the spec here as the spec could be empty. Or do - we want to - type: boolean hashedTokenSecretStatus: properties: secretKeyRef: @@ -141,6 +135,10 @@ spec: type: object type: object tokenSecretStatus: + description: TODO set the status. This is used by the HumioCluster + resource to get the secret reference and load the secret. We don't + want to rely on the spec here as the spec could be empty. Or do + we want to Created bool `json:"created,omitempty"` properties: secretKeyRef: description: SecretKeySelector selects a key of a Secret. diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 9632d101..870787af 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -1,9 +1,11 @@ + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null name: humiobootstraptokens.core.humio.com labels: app: 'humio-operator' @@ -32,19 +34,14 @@ spec: use to bootstrap authentication properties: apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object @@ -53,14 +50,14 @@ spec: Humio will use to bootstrap authentication properties: externalClusterName: - description: |- - ExternalClusterName refers to an object of type HumioExternalCluster where the Humio resources should be created. - This conflicts with ManagedClusterName. + description: ExternalClusterName refers to an object of type HumioExternalCluster + where the Humio resources should be created. This conflicts with + ManagedClusterName. type: string hashedTokenSecret: properties: - createIfMissing: - description: 'TODO: maybe remove CreateIfMissing' + autoCreate: + description: 'TODO: maybe remove AutoCreate' type: boolean secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -70,10 +67,8 @@ spec: a valid secret key. type: string name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: description: Specify whether the Secret or its key must be @@ -82,21 +77,19 @@ spec: required: - key type: object - x-kubernetes-map-type: atomic type: object image: type: string managedClusterName: - description: |- - TODO: determine if we even want to reference the cluster here - ManagedClusterName + description: 'TODO: determine if we even want to reference the cluster + here ManagedClusterName' type: string tokenSecret: properties: - createIfMissing: - description: |- - TODO: we could clean this up by removing the "CreateIfMissing" and in docs explain if you want to use your own secret - then create the secret before the bootstraptoken resource + autoCreate: + description: 'TODO: we could clean this up by removing the "AutoCreate" + and in docs explain if you want to use your own secret then + create the secret before the bootstraptoken resource' type: boolean secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -106,10 +99,8 @@ spec: a valid secret key. type: string name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: description: Specify whether the Secret or its key must be @@ -118,16 +109,10 @@ spec: required: - key type: object - x-kubernetes-map-type: atomic type: object type: object status: properties: - created: - description: |- - TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec - here as the spec could be empty. Or do we want to - type: boolean hashedTokenSecretStatus: properties: secretKeyRef: @@ -138,10 +123,8 @@ spec: a valid secret key. type: string name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: description: Specify whether the Secret or its key must be @@ -150,9 +133,12 @@ spec: required: - key type: object - x-kubernetes-map-type: atomic type: object tokenSecretStatus: + description: TODO set the status. This is used by the HumioCluster + resource to get the secret reference and load the secret. We don't + want to rely on the spec here as the spec could be empty. Or do + we want to Created bool `json:"created,omitempty"` properties: secretKeyRef: description: SecretKeySelector selects a key of a Secret. @@ -162,10 +148,8 @@ spec: a valid secret key. type: string name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: description: Specify whether the Secret or its key must be @@ -174,7 +158,6 @@ spec: required: - key type: object - x-kubernetes-map-type: atomic type: object type: object type: object @@ -182,3 +165,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index e733d997..923184bc 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -45,8 +45,10 @@ import ( const ( // BootstrapTokenSecretHashedTokenName is the name of the hashed token key inside the bootstrap token secret BootstrapTokenSecretHashedTokenName = "hashedToken" - // BootstrapTokenSecretName is the name of the secret key inside the bootstrap token secret - BootstrapTokenSecretName = "secret" + // BootstrapTokenSecretSecretName is the name of the secret key inside the bootstrap token secret + BootstrapTokenSecretSecretName = "secret" + // BootstrapTokenSecretPassphraseKey is the key name for the passphrase set in the bootstrap token secret + BootstrapTokenSecretPassphraseKey = "passphrase" ) // HumioBootstrapTokenReconciler reconciles a HumioBootstrapToken object @@ -112,36 +114,31 @@ func (r *HumioBootstrapTokenReconciler) Reconcile(ctx context.Context, req ctrl. return reconcile.Result{}, err } - if err := r.Get(ctx, req.NamespacedName, hbt); err != nil { + if err := r.updateStatus(ctx, hbt); err != nil { return reconcile.Result{}, err } - // TODO: rather than status, should we set a default in the spec instead? + return reconcile.Result{RequeueAfter: time.Second * 60}, nil +} + +func (r *HumioBootstrapTokenReconciler) updateStatus(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { hbt.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-bootstrap-token", hbt.Name), + Name: fmt.Sprintf("%s-%s", hbt.Name, kubernetes.BootstrapTokenSecretNameSuffix), }, - Key: "secret", + Key: BootstrapTokenSecretSecretName, }, } hbt.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-bootstrap-token", hbt.Name), + Name: fmt.Sprintf("%s-%s", hbt.Name, kubernetes.BootstrapTokenSecretNameSuffix), }, - Key: "hashedToken", + Key: BootstrapTokenSecretHashedTokenName, }, } - if err := r.Client.Status().Update(ctx, hbt); err != nil { - return reconcile.Result{}, err - } - - // TODO: take code from images/helper/main.go and use "secret" to create an admin user and store the token in a k8s secret. Update the - // HumioBootstrapToken Status to also include the admin token. - // Alternatively, the creation of the admin user could be handled by the humiocluster controller. Perhaps that is a better place for it? - - return reconcile.Result{RequeueAfter: time.Second * 60}, nil + return r.Client.Status().Update(ctx, hbt) } func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []string) (string, error) { @@ -186,7 +183,7 @@ func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []stri return "", err } var stdout, stderr bytes.Buffer - err = exec.Stream(remotecommand.StreamOptions{ + err = exec.StreamWithContext(context.TODO(), remotecommand.StreamOptions{ Stdin: nil, Stdout: &stdout, Stderr: &stderr, @@ -258,35 +255,46 @@ func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humi func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) error { r.Log.Info("ensuring bootstrap token secret") humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, hc) - if !humioBootstrapTokenConfig.tokenSecretCreateIfMissing() { - return nil - } if _, err := r.getBootstrapTokenSecret(ctx, hbt, hc); err != nil { if k8serrors.IsNotFound(err) { - // TODO: something better - //randomPass := kubernetes.RandomString() - secretData := map[string][]byte{ - //"passphrase": []byte(randomPass), - } - // TODO: make passphrase constant + secretData := map[string][]byte{} if hbt.Spec.TokenSecret.SecretKeyRef != nil { secret, err := kubernetes.GetSecret(ctx, r, hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Namespace) if err != nil { return r.logErrorAndReturn(err, fmt.Sprintf("could not get secret %s", hbt.Spec.TokenSecret.SecretKeyRef.Name)) } - if passphrase, ok := secret.Data["passphrase"]; ok { - secretData["passphrase"] = passphrase + if secretValue, ok := secret.Data[hbt.Spec.TokenSecret.SecretKeyRef.Key]; ok { + secretData[BootstrapTokenSecretSecretName] = secretValue + } else { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get value from secret %s. "+ + "secret does not contain value for key \"%s\"", hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Spec.TokenSecret.SecretKeyRef.Key)) } + } - secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) - if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { - return r.logErrorAndReturn(err, "could not set controller reference") + if hbt.Spec.HashedTokenSecret.SecretKeyRef != nil { + secret, err := kubernetes.GetSecret(ctx, r, hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Namespace) + if err != nil { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get secret %s", hbt.Spec.TokenSecret.SecretKeyRef.Name)) + } + if hashedTokenValue, ok := secret.Data[hbt.Spec.HashedTokenSecret.SecretKeyRef.Key]; ok { + secretData[BootstrapTokenSecretHashedTokenName] = hashedTokenValue + } else { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get value from secret %s. "+ + "secret does not contain value for key \"%s\"", hbt.Spec.HashedTokenSecret.SecretKeyRef.Name, hbt.Spec.HashedTokenSecret.SecretKeyRef.Key)) + } } - r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) - if err := r.Create(ctx, secret); err != nil { - return r.logErrorAndReturn(err, "could not create secret") + // TODO: do we really need autocreate option, or just assume create if there is no hbt.Spec.TokenSecret.SecretKeyRef set? + if humioBootstrapTokenConfig.autoCreate() { + secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) + if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { + return r.logErrorAndReturn(err, "could not set controller reference") + } + r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) + if err := r.Create(ctx, secret); err != nil { + return r.logErrorAndReturn(err, "could not create secret") + } + return nil } - return nil } else { return r.logErrorAndReturn(err, "could not get secret") } @@ -314,7 +322,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont commandArgs := []string{"/bin/bash", "/app/humio/humio/bin/humio-run-class.sh", "com.humio.main.TokenHashing", "--json"} - if tokenSecret, ok := bootstrapTokenSecret.Data[BootstrapTokenSecretName]; ok { + if tokenSecret, ok := bootstrapTokenSecret.Data[BootstrapTokenSecretSecretName]; ok { commandArgs = append(commandArgs, string(tokenSecret)) } @@ -359,7 +367,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont return err } // TODO: make tokenHash constant - updatedSecret.Data = map[string][]byte{BootstrapTokenSecretHashedTokenName: []byte(secretData.HashedToken), BootstrapTokenSecretName: []byte(secretData.Secret)} + updatedSecret.Data = map[string][]byte{BootstrapTokenSecretHashedTokenName: []byte(secretData.HashedToken), BootstrapTokenSecretSecretName: []byte(secretData.Secret)} if err = r.Update(ctx, updatedSecret); err != nil { return r.logErrorAndReturn(err, "failed to update secret with hashedToken data") diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index 8a5b9541..735c4a5e 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -8,8 +8,8 @@ import ( ) const ( - BootstrapTokenSuffix = "bootstrap-token" - HashedBootstrapTokenSuffix = "hashed-bootstrap-token" + BootstrapTokenSuffix = "bootstrap-token" + //HashedBootstrapTokenSuffix = "hashed-bootstrap-token" ) type HumioBootstrapTokenConfig struct { @@ -28,17 +28,17 @@ func (b *HumioBootstrapTokenConfig) bootstrapTokenName() string { return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, BootstrapTokenSuffix) } -func (b *HumioBootstrapTokenConfig) hashedBootstrapTokenName() string { - if b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef != nil { - return b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef.Name - } - return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, HashedBootstrapTokenSuffix) -} +//func (b *HumioBootstrapTokenConfig) hashedBootstrapTokenName() string { +// if b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef != nil { +// return b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef.Name +// } +// return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, HashedBootstrapTokenSuffix) +//} // TODO: remove this? -func (b *HumioBootstrapTokenConfig) tokenSecretCreateIfMissing() bool { - if b.BootstrapToken.Spec.TokenSecret.CreateIfMissing != nil { - return *b.BootstrapToken.Spec.TokenSecret.CreateIfMissing +func (b *HumioBootstrapTokenConfig) autoCreate() bool { + if b.BootstrapToken.Spec.TokenSecret.AutoCreate != nil { + return *b.BootstrapToken.Spec.TokenSecret.AutoCreate } return true } diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index e4ad2495..fac1a7ca 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -461,8 +461,19 @@ func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Co Namespace: hc.Namespace, Name: hc.Name, } - hbt := &humiov1alpha1.HumioBootstrapToken{} - err := r.Client.Get(ctx, key, hbt) + //hbt := &humiov1alpha1.HumioBootstrapToken{} + hbtList := &humiov1alpha1.HumioBootstrapTokenList{} + var matchedHbt humiov1alpha1.HumioBootstrapToken + err := r.Client.List(ctx, hbtList) + if err != nil { + return r.logErrorAndReturn(err, "could not list HumioBootstrapToken") + } + for _, hbt := range hbtList.Items { + if hbt.Spec.ManagedClusterName == hc.Name { + matchedHbt = hbt + } + } + err = r.Client.Get(ctx, key, &matchedHbt) if err != nil { if k8serrors.IsNotFound(err) { hbt := &humiov1alpha1.HumioBootstrapToken{ @@ -490,13 +501,13 @@ func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Co // }, }, } + if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { + return r.logErrorAndReturn(err, "could not set controller reference") + } err = r.Create(ctx, hbt) if err != nil { return r.logErrorAndReturn(err, "could not create bootstrap token resource") } - if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { - return r.logErrorAndReturn(err, "could not set controller reference") - } return nil } return r.logErrorAndReturn(err, "could not get bootstrap token resource") diff --git a/main.go b/main.go index f4223af8..e33acf52 100644 --- a/main.go +++ b/main.go @@ -184,6 +184,11 @@ func main() { BaseLogger: log, }).SetupWithManager(mgr); err != nil { ctrl.Log.Error(err, "unable to create controller", "controller", "HumioFilterAlert") + if err = (&controllers.HumioBootstrapTokenReconciler{ + Client: mgr.GetClient(), + BaseLogger: log, + }).SetupWithManager(mgr); err != nil { + ctrl.Log.Error(err, "unable to create controller", "controller", "HumioBootstrapToken") os.Exit(1) } if err = (&controllers.HumioAggregateAlertReconciler{ diff --git a/pkg/helpers/clusterinterface.go b/pkg/helpers/clusterinterface.go index 90c3cdd9..d547ee25 100644 --- a/pkg/helpers/clusterinterface.go +++ b/pkg/helpers/clusterinterface.go @@ -168,20 +168,33 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie var bootstrapToken corev1.Secret if withBootstrapToken { - // Get API token - err = k8sClient.Get(ctx, types.NamespacedName{ - Namespace: c.namespace, - //Name: fmt.Sprintf("%s-%s", c.managedClusterName, kubernetes.ServiceTokenSecretNameSuffix), - // TODO: pass in BootstrapTokenSuffix - Name: fmt.Sprintf("%s-bootstrap-token", c.managedClusterName), - }, &bootstrapToken) + hbtList := &humiov1alpha1.HumioBootstrapTokenList{} + var matchedHbt humiov1alpha1.HumioBootstrapToken + err := k8sClient.List(ctx, hbtList) if err != nil { - return nil, fmt.Errorf("unable to get bootstrap secret containing api token: %w", err) + return nil, fmt.Errorf("unable to get bootstrap token: %w", err) } - if _, ok := bootstrapToken.Data["secret"]; !ok { - return nil, fmt.Errorf("unable to get bootstrap secret containing api token. secret does not contain key named \"secret\"") + for _, hbt := range hbtList.Items { + if hbt.Spec.ManagedClusterName == c.managedClusterName { + matchedHbt = hbt + } + } + + // Get API token + if matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef != nil { + err = k8sClient.Get(ctx, types.NamespacedName{ + Namespace: c.namespace, + Name: matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Name, + }, &bootstrapToken) + if err != nil { + return nil, fmt.Errorf("unable to get bootstrap secret containing api token: %w", err) + } + if _, ok := bootstrapToken.Data[matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Key]; !ok { + return nil, fmt.Errorf("unable to get bootstrap secret containing api token. secret does not contain key named \"%s\"", matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Key) + } + config.Token = fmt.Sprintf("localroot~%s", string(bootstrapToken.Data[matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Key])) } - config.Token = fmt.Sprintf("localroot~%s", string(bootstrapToken.Data["secret"])) + return nil, fmt.Errorf("unable to find bootstrap token with ManagedClusterName %s", c.managedClusterName) } // If we do not use TLS, return a client without CA certificate From 243fc5922ef98e2727f492d94961a6266b1d71f8 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 28 Sep 2023 13:25:23 -0700 Subject: [PATCH 13/54] WIP --- controllers/humiocluster_controller.go | 72 ++++++++++++-------------- examples/humiobootstraptoken.yaml | 10 ++++ pkg/helpers/clusterinterface.go | 12 ++++- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index fac1a7ca..e02706eb 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -461,56 +461,48 @@ func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Co Namespace: hc.Namespace, Name: hc.Name, } - //hbt := &humiov1alpha1.HumioBootstrapToken{} hbtList := &humiov1alpha1.HumioBootstrapTokenList{} - var matchedHbt humiov1alpha1.HumioBootstrapToken err := r.Client.List(ctx, hbtList) if err != nil { return r.logErrorAndReturn(err, "could not list HumioBootstrapToken") } for _, hbt := range hbtList.Items { if hbt.Spec.ManagedClusterName == hc.Name { - matchedHbt = hbt + return nil } } - err = r.Client.Get(ctx, key, &matchedHbt) + + hbt := &humiov1alpha1.HumioBootstrapToken{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + Spec: humiov1alpha1.HumioBootstrapTokenSpec{ + ManagedClusterName: hc.Name, + // TokenSecret: humiov1alpha1.HumioTokenSecretSpec{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), + // }, + // Key: "secret", + // }, + // }, + // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{ + // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), + // }, + // Key: "hashedToken", + // }, + // }, + }, + } + if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { + return r.logErrorAndReturn(err, "could not set controller reference") + } + err = r.Create(ctx, hbt) if err != nil { - if k8serrors.IsNotFound(err) { - hbt := &humiov1alpha1.HumioBootstrapToken{ - ObjectMeta: metav1.ObjectMeta{ - Name: key.Name, - Namespace: key.Namespace, - }, - Spec: humiov1alpha1.HumioBootstrapTokenSpec{ - ManagedClusterName: hc.Name, - // TokenSecret: humiov1alpha1.HumioTokenSecretSpec{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), - // }, - // Key: "secret", - // }, - // }, - // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), - // }, - // Key: "hashedToken", - // }, - // }, - }, - } - if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { - return r.logErrorAndReturn(err, "could not set controller reference") - } - err = r.Create(ctx, hbt) - if err != nil { - return r.logErrorAndReturn(err, "could not create bootstrap token resource") - } - return nil - } - return r.logErrorAndReturn(err, "could not get bootstrap token resource") + return r.logErrorAndReturn(err, "could not create bootstrap token resource") } return nil } diff --git a/examples/humiobootstraptoken.yaml b/examples/humiobootstraptoken.yaml index 93ce328f..e7f02557 100644 --- a/examples/humiobootstraptoken.yaml +++ b/examples/humiobootstraptoken.yaml @@ -4,3 +4,13 @@ metadata: name: example-bootstraptoken spec: managedClusterName: example-humiocluster + tokenSecret: + autoCreate: false + secretKeyRef: + name: example-bootstraptoken-token-secret + key: secret + hashedTokenSecret: + autoCreate: false + secretKeyRef: + name: example-bootstraptoken-token-secret + key: hashedToken diff --git a/pkg/helpers/clusterinterface.go b/pkg/helpers/clusterinterface.go index d547ee25..77ed5b39 100644 --- a/pkg/helpers/clusterinterface.go +++ b/pkg/helpers/clusterinterface.go @@ -166,9 +166,9 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie config.Token = string(apiToken.Data["token"]) } - var bootstrapToken corev1.Secret if withBootstrapToken { hbtList := &humiov1alpha1.HumioBootstrapTokenList{} + var hasMatch bool var matchedHbt humiov1alpha1.HumioBootstrapToken err := k8sClient.List(ctx, hbtList) if err != nil { @@ -176,11 +176,17 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie } for _, hbt := range hbtList.Items { if hbt.Spec.ManagedClusterName == c.managedClusterName { + hasMatch = true matchedHbt = hbt } } + if !hasMatch { + return nil, fmt.Errorf("unable to find bootstrap token with ManagedClusterName %s", c.managedClusterName) + } + // Get API token + var bootstrapToken corev1.Secret if matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef != nil { err = k8sClient.Get(ctx, types.NamespacedName{ Namespace: c.namespace, @@ -193,8 +199,10 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie return nil, fmt.Errorf("unable to get bootstrap secret containing api token. secret does not contain key named \"%s\"", matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Key) } config.Token = fmt.Sprintf("localroot~%s", string(bootstrapToken.Data[matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Key])) + } else { + return nil, fmt.Errorf("unable to get bootstrap secret containing api token: bootstraptoken %s does not have a status for tokenSecretKeyRef", matchedHbt.Name) } - return nil, fmt.Errorf("unable to find bootstrap token with ManagedClusterName %s", c.managedClusterName) + } // If we do not use TLS, return a client without CA certificate From 2239d6fa56516d5569ebae59e2a1226e9a10d659 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 2 Oct 2023 09:51:19 -0700 Subject: [PATCH 14/54] more cleanup --- controllers/humiobootstraptoken_controller.go | 77 ++++++------ controllers/humiocluster_controller.go | 40 +------ controllers/suite/common.go | 110 +----------------- pkg/helpers/clusterinterface.go | 4 +- pkg/kubernetes/humio_bootstrap_tokens.go | 97 +++++++++++++++ pkg/kubernetes/secrets.go | 5 +- 6 files changed, 144 insertions(+), 189 deletions(-) create mode 100644 pkg/kubernetes/humio_bootstrap_tokens.go diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 923184bc..6709f7d9 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -47,8 +47,6 @@ const ( BootstrapTokenSecretHashedTokenName = "hashedToken" // BootstrapTokenSecretSecretName is the name of the secret key inside the bootstrap token secret BootstrapTokenSecretSecretName = "secret" - // BootstrapTokenSecretPassphraseKey is the key name for the passphrase set in the bootstrap token secret - BootstrapTokenSecretPassphraseKey = "passphrase" ) // HumioBootstrapTokenReconciler reconciles a HumioBootstrapToken object @@ -256,50 +254,47 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.C r.Log.Info("ensuring bootstrap token secret") humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, hc) if _, err := r.getBootstrapTokenSecret(ctx, hbt, hc); err != nil { - if k8serrors.IsNotFound(err) { - secretData := map[string][]byte{} - if hbt.Spec.TokenSecret.SecretKeyRef != nil { - secret, err := kubernetes.GetSecret(ctx, r, hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Namespace) - if err != nil { - return r.logErrorAndReturn(err, fmt.Sprintf("could not get secret %s", hbt.Spec.TokenSecret.SecretKeyRef.Name)) - } - if secretValue, ok := secret.Data[hbt.Spec.TokenSecret.SecretKeyRef.Key]; ok { - secretData[BootstrapTokenSecretSecretName] = secretValue - } else { - return r.logErrorAndReturn(err, fmt.Sprintf("could not get value from secret %s. "+ - "secret does not contain value for key \"%s\"", hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Spec.TokenSecret.SecretKeyRef.Key)) - } - + if !k8serrors.IsNotFound(err) { + return r.logErrorAndReturn(err, "could not get secret") + } + secretData := map[string][]byte{} + if hbt.Spec.TokenSecret.SecretKeyRef != nil { + secret, err := kubernetes.GetSecret(ctx, r, hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Namespace) + if err != nil { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get secret %s", hbt.Spec.TokenSecret.SecretKeyRef.Name)) } - if hbt.Spec.HashedTokenSecret.SecretKeyRef != nil { - secret, err := kubernetes.GetSecret(ctx, r, hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Namespace) - if err != nil { - return r.logErrorAndReturn(err, fmt.Sprintf("could not get secret %s", hbt.Spec.TokenSecret.SecretKeyRef.Name)) - } - if hashedTokenValue, ok := secret.Data[hbt.Spec.HashedTokenSecret.SecretKeyRef.Key]; ok { - secretData[BootstrapTokenSecretHashedTokenName] = hashedTokenValue - } else { - return r.logErrorAndReturn(err, fmt.Sprintf("could not get value from secret %s. "+ - "secret does not contain value for key \"%s\"", hbt.Spec.HashedTokenSecret.SecretKeyRef.Name, hbt.Spec.HashedTokenSecret.SecretKeyRef.Key)) - } + if secretValue, ok := secret.Data[hbt.Spec.TokenSecret.SecretKeyRef.Key]; ok { + secretData[BootstrapTokenSecretSecretName] = secretValue + } else { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get value from secret %s. "+ + "secret does not contain value for key \"%s\"", hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Spec.TokenSecret.SecretKeyRef.Key)) } - // TODO: do we really need autocreate option, or just assume create if there is no hbt.Spec.TokenSecret.SecretKeyRef set? - if humioBootstrapTokenConfig.autoCreate() { - secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) - if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { - return r.logErrorAndReturn(err, "could not set controller reference") - } - r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) - if err := r.Create(ctx, secret); err != nil { - return r.logErrorAndReturn(err, "could not create secret") - } - return nil + } + if hbt.Spec.HashedTokenSecret.SecretKeyRef != nil { + secret, err := kubernetes.GetSecret(ctx, r, hbt.Spec.TokenSecret.SecretKeyRef.Name, hbt.Namespace) + if err != nil { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get secret %s", hbt.Spec.TokenSecret.SecretKeyRef.Name)) + } + if hashedTokenValue, ok := secret.Data[hbt.Spec.HashedTokenSecret.SecretKeyRef.Key]; ok { + secretData[BootstrapTokenSecretHashedTokenName] = hashedTokenValue + } else { + return r.logErrorAndReturn(err, fmt.Sprintf("could not get value from secret %s. "+ + "secret does not contain value for key \"%s\"", hbt.Spec.HashedTokenSecret.SecretKeyRef.Name, hbt.Spec.HashedTokenSecret.SecretKeyRef.Key)) + } + } + // TODO: do we really need autocreate option, or just assume create if there is no hbt.Spec.TokenSecret.SecretKeyRef set? + // I think we do since it's confusing if we only have the conditional based on one or both of hbt.Spec.TokenSecret.SecretKeyRef and hbt.Spec.HashedTokenSecret.SecretKeyRef.Key + if humioBootstrapTokenConfig.autoCreate() { + secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) + if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { + return r.logErrorAndReturn(err, "could not set controller reference") + } + r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) + if err := r.Create(ctx, secret); err != nil { + return r.logErrorAndReturn(err, "could not create secret") } - } else { - return r.logErrorAndReturn(err, "could not get secret") } } - return nil } diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index e02706eb..3b786010 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -31,7 +31,6 @@ import ( corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -457,46 +456,15 @@ func (r *HumioClusterReconciler) ensurePodRevisionAnnotation(ctx context.Context return hc.Status.State, nil } func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Context, hc *humiov1alpha1.HumioCluster) error { - key := types.NamespacedName{ - Namespace: hc.Namespace, - Name: hc.Name, - } - hbtList := &humiov1alpha1.HumioBootstrapTokenList{} - err := r.Client.List(ctx, hbtList) + hbtList, err := kubernetes.ListHumioBootstrapTokens(ctx, r.Client, hc.GetNamespace(), kubernetes.LabelsForHumioBootstrapToken(hc.GetName())) if err != nil { return r.logErrorAndReturn(err, "could not list HumioBootstrapToken") } - for _, hbt := range hbtList.Items { - if hbt.Spec.ManagedClusterName == hc.Name { - return nil - } + if len(hbtList) > 0 { + return nil } - hbt := &humiov1alpha1.HumioBootstrapToken{ - ObjectMeta: metav1.ObjectMeta{ - Name: key.Name, - Namespace: key.Namespace, - }, - Spec: humiov1alpha1.HumioBootstrapTokenSpec{ - ManagedClusterName: hc.Name, - // TokenSecret: humiov1alpha1.HumioTokenSecretSpec{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), - // }, - // Key: "secret", - // }, - // }, - // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), - // }, - // Key: "hashedToken", - // }, - // }, - }, - } + hbt := kubernetes.ConstructHumioBootstrapToken(hc.GetName(), hc.GetNamespace()) if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { return r.logErrorAndReturn(err, "could not set controller reference") } diff --git a/controllers/suite/common.go b/controllers/suite/common.go index 01753527..a0af2f2a 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -370,6 +370,9 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Name: key.Name, Namespace: key.Namespace, }, + Spec: humiov1alpha1.HumioBootstrapTokenSpec{ + ManagedClusterName: key.Name, + }, //Spec: humiov1alpha1.HumioBootstrapTokenSpec{ // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ // SecretKeyRef: &corev1.SecretKeySelector{ @@ -406,118 +409,13 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum desiredSecret := kubernetes.ConstructSecret(key.Name, key.Namespace, bootstrapTokenSecretName, secretData, nil) Expect(k8sClient.Create(ctx, desiredSecret)).To(Succeed()) - //UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") - //humioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{ - // ObjectMeta: metav1.ObjectMeta{ - // Name: fmt.Sprintf(key.Name), - // Namespace: key.Namespace, - // }, - // Spec: humiov1alpha1.HumioBootstrapTokenSpec{ - // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token-test", key.Name), - // }, - // Key: "hashedToken", - // }, - // }, - // }, - // //Status: humiov1alpha1.HumioBootstrapTokenStatus{ - // // TokenSecretKeyRef: humiov1alpha1.HumioTokenSecretStatus{&corev1.SecretKeySelector{ - // // LocalObjectReference: corev1.LocalObjectReference{ - // // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // // }, - // // Key: "secret", - // // }, - // // }, - // // HashedTokenSecretKeyRef: humiov1alpha1.HumioHashedTokenSecretStatus{&corev1.SecretKeySelector{ - // // LocalObjectReference: corev1.LocalObjectReference{ - // // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // // }, - // // Key: "hashedToken", - // // }}, - // //}, - //} - - //UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") - //Expect(k8sClient.Create(ctx, humioBootstrapToken)).Should(Succeed()) - - //UsingClusterBy(key.Name, "Updating HumioBootstrapToken status") - //updatedHumioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{} - //humioBootstrapTokenKey := types.NamespacedName{ - // Namespace: humioBootstrapToken.Namespace, - // Name: humioBootstrapToken.Name, - //} - //Expect(k8sClient.Get(ctx, humioBootstrapTokenKey, updatedHumioBootstrapToken)).Should(Succeed()) - // - //updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // }, - // Key: "secret", - // }, - //} - //updatedHumioBootstrapToken.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // }, - // Key: "hashedToken", - // }, - //} - //Expect(k8sClient.Status().Update(ctx, updatedHumioBootstrapToken)).Should(Succeed()) - // - //Expect(k8sClient.Get(ctx, humioBootstrapTokenKey, updatedHumioBootstrapToken)).Should(Succeed()) - // - //updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // }, - // Key: "secret", - // }, - //} - //updatedHumioBootstrapToken.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // }, - // Key: "hashedToken", - // }, - //} - //Expect(k8sClient.Status().Update(ctx, updatedHumioBootstrapToken)).Should(Succeed()) - // - //Expect(k8sClient.Get(ctx, humioBootstrapTokenKey, updatedHumioBootstrapToken)).Should(Succeed()) - // - //updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // }, - // Key: "secret", - // }, - //} - //updatedHumioBootstrapToken.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // }, - // Key: "hashedToken", - // }, - //} - //Expect(k8sClient.Status().Update(ctx, updatedHumioBootstrapToken)).Should(Succeed()) - UsingClusterBy(key.Name, "Creating HumioCluster resource") Expect(k8sClient.Create(ctx, cluster)).Should(Succeed()) UsingClusterBy(key.Name, "Simulating HumioBootstrapToken Controller running and adding the secret and status") Eventually(func() error { var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken - err := k8sClient.Get(ctx, key, &updatedHumioBootstrapToken) - if err != nil && !k8serrors.IsNotFound(err) { - Expect(err).Should(Succeed()) - } + Expect(k8sClient.Get(ctx, key, &updatedHumioBootstrapToken)).Should(Succeed()) updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ diff --git a/pkg/helpers/clusterinterface.go b/pkg/helpers/clusterinterface.go index 77ed5b39..fa02cdb9 100644 --- a/pkg/helpers/clusterinterface.go +++ b/pkg/helpers/clusterinterface.go @@ -166,6 +166,7 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie config.Token = string(apiToken.Data["token"]) } + var bootstrapToken corev1.Secret if withBootstrapToken { hbtList := &humiov1alpha1.HumioBootstrapTokenList{} var hasMatch bool @@ -186,7 +187,6 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie } // Get API token - var bootstrapToken corev1.Secret if matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef != nil { err = k8sClient.Get(ctx, types.NamespacedName{ Namespace: c.namespace, @@ -199,8 +199,6 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie return nil, fmt.Errorf("unable to get bootstrap secret containing api token. secret does not contain key named \"%s\"", matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Key) } config.Token = fmt.Sprintf("localroot~%s", string(bootstrapToken.Data[matchedHbt.Status.TokenSecretKeyRef.SecretKeyRef.Key])) - } else { - return nil, fmt.Errorf("unable to get bootstrap secret containing api token: bootstraptoken %s does not have a status for tokenSecretKeyRef", matchedHbt.Name) } } diff --git a/pkg/kubernetes/humio_bootstrap_tokens.go b/pkg/kubernetes/humio_bootstrap_tokens.go new file mode 100644 index 00000000..4f3cbf74 --- /dev/null +++ b/pkg/kubernetes/humio_bootstrap_tokens.go @@ -0,0 +1,97 @@ +package kubernetes + +import ( + "context" + "fmt" + + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +/* +Copyright 2020 Humio https://humio.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +const ( + BootstrapTokenNameSuffix = "bootstrap-token" + BootstrapTokenSecretNameSuffix = "bootstrap-token" + BootstrapTokenManagedClusterNameLabelName = "managed-cluster-name" +) + +// LabelsForHumioBootstrapToken returns a map of labels which contains a common set of labels and additional user-defined humio bootstrap token labels. +// In case of overlap between the common labels and user-defined labels, the user-defined label will be ignored. +func LabelsForHumioBootstrapToken(clusterName string) map[string]string { + labels := LabelsForHumio(clusterName) + labels[BootstrapTokenManagedClusterNameLabelName] = clusterName + return labels +} + +// ConstructHumioBootstrapToken returns a HumioBootstrapToken +func ConstructHumioBootstrapToken(humioClusterName string, humioClusterNamespace string) *humiov1alpha1.HumioBootstrapToken { + return &humiov1alpha1.HumioBootstrapToken{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s", humioClusterName, BootstrapTokenNameSuffix), + Namespace: humioClusterNamespace, + Labels: LabelsForHumioBootstrapToken(humioClusterName), + }, + Spec: humiov1alpha1.HumioBootstrapTokenSpec{ + ManagedClusterName: humioClusterName, + }, + } +} + +// ListHumioBootstrapTokens returns all HumioBootstrapTokens in a given namespace which matches the label selector +func ListHumioBootstrapTokens(ctx context.Context, c client.Client, humioClusterNamespace string, matchingLabels client.MatchingLabels) ([]humiov1alpha1.HumioBootstrapToken, error) { + var foundHumioBootstrapTokenList humiov1alpha1.HumioBootstrapTokenList + err := c.List(ctx, &foundHumioBootstrapTokenList, client.InNamespace(humioClusterNamespace), matchingLabels) + if err != nil { + return nil, err + } + + // If for some reason the HumioBootstrapToken is not labeled with the managed-cluster-name label, look at the spec + if len(foundHumioBootstrapTokenList.Items) == 0 { + if humioClusterName, ok := matchingLabels[BootstrapTokenManagedClusterNameLabelName]; ok { + var allHumioBootstrapTokensList humiov1alpha1.HumioBootstrapTokenList + err := c.List(ctx, &allHumioBootstrapTokensList, client.InNamespace(humioClusterNamespace)) + if err != nil { + return nil, err + } + for _, hbt := range allHumioBootstrapTokensList.Items { + if hbt.Spec.ManagedClusterName == humioClusterName { + foundHumioBootstrapTokenList.Items = append(foundHumioBootstrapTokenList.Items, hbt) + } + } + } + } + + return foundHumioBootstrapTokenList.Items, nil +} + +// GetHumioBootstrapToken retrieves the HumioBootstrapToken given the humio cluster name and namespace +func GetHumioBootstrapToken(ctx context.Context, c client.Client, humioClusterName string, humioClusterNamespace string) (humiov1alpha1.HumioBootstrapToken, error) { + matchingLabels := LabelsForHumio(humioClusterName) + humioBootstrapTokenList, err := ListHumioBootstrapTokens(ctx, c, humioClusterNamespace, matchingLabels) + if err != nil { + return humiov1alpha1.HumioBootstrapToken{}, err + } + + if len(humioBootstrapTokenList) == 0 { + return humiov1alpha1.HumioBootstrapToken{}, fmt.Errorf("no HumioBootstrapTokens found with name %s in namespace %s", humioClusterName, humioClusterNamespace) + } else if len(humioBootstrapTokenList) > 1 { + return humiov1alpha1.HumioBootstrapToken{}, fmt.Errorf("too many HumioBootstrapTokens found with name %s in namespace %s (count %d)", humioClusterName, humioClusterNamespace, len(humioBootstrapTokenList)) + } + return humioBootstrapTokenList[0], nil +} diff --git a/pkg/kubernetes/secrets.go b/pkg/kubernetes/secrets.go index 7e819a38..e699bacd 100644 --- a/pkg/kubernetes/secrets.go +++ b/pkg/kubernetes/secrets.go @@ -27,9 +27,8 @@ import ( ) const ( - ServiceTokenSecretNameSuffix = "admin-token" - BootstrapTokenSecretNameSuffix = "bootstrap-token" - SecretNameLabelName = "humio.com/secret-identifier" // #nosec G101 + ServiceTokenSecretNameSuffix = "admin-token" + SecretNameLabelName = "humio.com/secret-identifier" // #nosec G101 ) // LabelsForSecret returns a map of labels which contains a common set of labels and additional user-defined secret labels. From 8917f403cba76aefff597290f244da10eec26733 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 4 Oct 2023 14:56:09 -0700 Subject: [PATCH 15/54] more cleanup --- api/v1alpha1/humiobootstraptoken_types.go | 6 ++- .../core.humio.com_humiobootstraptokens.yaml | 5 +- .../core.humio.com_humiobootstraptokens.yaml | 5 +- controllers/humiobootstraptoken_controller.go | 35 ++++++++------ controllers/humiocluster_controller.go | 24 ++++------ controllers/humiocluster_pods.go | 47 +++++++++++++------ controllers/suite/common.go | 2 + pkg/kubernetes/humio_bootstrap_tokens.go | 16 ------- 8 files changed, 76 insertions(+), 64 deletions(-) diff --git a/api/v1alpha1/humiobootstraptoken_types.go b/api/v1alpha1/humiobootstraptoken_types.go index d78e72e7..b88bfffb 100644 --- a/api/v1alpha1/humiobootstraptoken_types.go +++ b/api/v1alpha1/humiobootstraptoken_types.go @@ -22,8 +22,8 @@ import ( ) const ( - // HumioBootstrapTokenStateMissing is the Missing state of the bootstrap token - HumioBootstrapTokenStateMissing = "Missing" + // HumioBootstrapTokenStateNotReady is the NotReady state of the bootstrap token + HumioBootstrapTokenStateNotReady = "NotReady" // HumioBootstrapTokenStateReady is the Ready state of the bootstrap token HumioBootstrapTokenStateReady = "Ready" ) @@ -59,6 +59,8 @@ type HumioBootstrapTokenStatus struct { // TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec // here as the spec could be empty. Or do we want to //Created bool `json:"created,omitempty"` + // State can be "NotReady" or "Ready" + State string `json:"state,omitempty"` TokenSecretKeyRef HumioTokenSecretStatus `json:"tokenSecretStatus,omitempty"` HashedTokenSecretKeyRef HumioHashedTokenSecretStatus `json:"hashedTokenSecretStatus,omitempty"` } diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index 870787af..049ac2fb 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -134,11 +134,14 @@ spec: - key type: object type: object - tokenSecretStatus: + state: description: TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec here as the spec could be empty. Or do we want to Created bool `json:"created,omitempty"` + State can be "NotReady" or "Ready" + type: string + tokenSecretStatus: properties: secretKeyRef: description: SecretKeySelector selects a key of a Secret. diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 870787af..049ac2fb 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -134,11 +134,14 @@ spec: - key type: object type: object - tokenSecretStatus: + state: description: TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec here as the spec could be empty. Or do we want to Created bool `json:"created,omitempty"` + State can be "NotReady" or "Ready" + type: string + tokenSecretStatus: properties: secretKeyRef: description: SecretKeySelector selects a key of a Secret. diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 6709f7d9..2ba4bc80 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -105,36 +105,41 @@ func (r *HumioBootstrapTokenReconciler) Reconcile(ctx context.Context, req ctrl. } if err := r.ensureBootstrapTokenSecret(ctx, hbt, hc); err != nil { + _ = r.updateStatus(ctx, hbt, humiov1alpha1.HumioBootstrapTokenStateNotReady) return reconcile.Result{}, err } if err := r.ensureBootstrapTokenHashedToken(ctx, hbt, hc); err != nil { + _ = r.updateStatus(ctx, hbt, humiov1alpha1.HumioBootstrapTokenStateNotReady) return reconcile.Result{}, err } - if err := r.updateStatus(ctx, hbt); err != nil { + if err := r.updateStatus(ctx, hbt, humiov1alpha1.HumioBootstrapTokenStateReady); err != nil { return reconcile.Result{}, err } return reconcile.Result{RequeueAfter: time.Second * 60}, nil } -func (r *HumioBootstrapTokenReconciler) updateStatus(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken) error { - hbt.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-%s", hbt.Name, kubernetes.BootstrapTokenSecretNameSuffix), +func (r *HumioBootstrapTokenReconciler) updateStatus(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, state string) error { + hbt.Status.State = state + if state == humiov1alpha1.HumioBootstrapTokenStateReady { + hbt.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-%s", hbt.Name, kubernetes.BootstrapTokenSecretNameSuffix), + }, + Key: BootstrapTokenSecretSecretName, }, - Key: BootstrapTokenSecretSecretName, - }, - } - hbt.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-%s", hbt.Name, kubernetes.BootstrapTokenSecretNameSuffix), + } + hbt.Status.HashedTokenSecretKeyRef = humiov1alpha1.HumioHashedTokenSecretStatus{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-%s", hbt.Name, kubernetes.BootstrapTokenSecretNameSuffix), + }, + Key: BootstrapTokenSecretHashedTokenName, }, - Key: BootstrapTokenSecretHashedTokenName, - }, + } } return r.Client.Status().Update(ctx, hbt) } diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index 3b786010..b0e1965a 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -1902,25 +1902,19 @@ func (r *HumioClusterReconciler) ensureMismatchedPodsAreDeleted(ctx context.Cont attachments.envVarSourceData = envVarSourceData } - // asdf - key := types.NamespacedName{ - Namespace: hc.Namespace, - Name: hc.Name, - } - hbt := &humiov1alpha1.HumioBootstrapToken{} - err = r.Client.Get(ctx, key, hbt) + humioBootstrapTokens, err := kubernetes.ListHumioBootstrapTokens(ctx, r.Client, hc.GetNamespace(), kubernetes.LabelsForHumioBootstrapToken(hc.GetName())) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "failed to get bootstrap token") } - - if hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef != nil { - attachments.bootstrapTokenSecretReference.secretReference = hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef - - bootstrapTokenHash, err := r.getDesiredBootstrapTokenHash(ctx, hnp) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "unable to find bootstrap token secret") + if len(humioBootstrapTokens) > 0 { + if humioBootstrapTokens[0].Status.State == humiov1alpha1.HumioBootstrapTokenStateReady { + attachments.bootstrapTokenSecretReference.secretReference = humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef + bootstrapTokenHash, err := r.getDesiredBootstrapTokenHash(ctx, hc) + if err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "unable to find bootstrap token secret") + } + attachments.bootstrapTokenSecretReference.hash = bootstrapTokenHash } - attachments.bootstrapTokenSecretReference.hash = bootstrapTokenHash } // prioritize deleting the pods with errors diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index b44efcdb..a68cfcea 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -661,7 +661,7 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha //var bootstrapTokenHash string //if attachments.bootstrapTokenSecretReference.secretReference != nil { - bootstrapTokenHash, err := r.getDesiredBootstrapTokenHash(ctx, hnp) + bootstrapTokenHash, err := r.getDesiredBootstrapTokenHash(ctx, hc) if err != nil { return &corev1.Pod{}, r.logErrorAndReturn(err, "unable to find bootstrap token secret") } @@ -890,25 +890,44 @@ type podNameAndCertificateHash struct { podName, certificateHash string } -func (r *HumioClusterReconciler) getDesiredBootstrapTokenHash(ctx context.Context, hnp *HumioNodePool) (string, error) { +func (r *HumioClusterReconciler) getDesiredBootstrapTokenHash(ctx context.Context, hc *humiov1alpha1.HumioCluster) (string, error) { + humioBootstrapTokens, err := kubernetes.ListHumioBootstrapTokens(ctx, r.Client, hc.GetNamespace(), kubernetes.LabelsForHumioBootstrapToken(hc.GetName())) + if err != nil { + return "", r.logErrorAndReturn(err, "failed to get bootstrap token") + } - existingSecret := &corev1.Secret{} - err := r.Get(ctx, types.NamespacedName{ - Namespace: hnp.GetNamespace(), - Name: fmt.Sprintf("%s-%s", hnp.GetClusterName(), kubernetes.BootstrapTokenSecretNameSuffix), - }, existingSecret) + if len(humioBootstrapTokens) > 0 { + if humioBootstrapTokens[0].Status.State == humiov1alpha1.HumioBootstrapTokenStateReady { + existingSecret := &corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ + Namespace: hc.GetNamespace(), + Name: humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, + }, existingSecret) + if err != nil { + return "", r.logErrorAndReturn(err, fmt.Sprintf("failed to get bootstrap token secret %s", + humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name)) + } - //return fmt.Sprintf("+%v", existingSecret), nil - if err != nil { - return fmt.Sprintf("%v", err), err + if ok := string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key]); ok != "" { + return helpers.AsSHA256(string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key])), nil + } + } } + return "", r.logErrorAndReturn(err, fmt.Sprintf("could not find bootstrap token secret matching labels %+v", kubernetes.LabelsForHumioBootstrapToken(hc.GetName()))) +} - if ok := string(existingSecret.Data[BootstrapTokenSecretHashedTokenName]); ok != "" { - return helpers.AsSHA256(string(existingSecret.Data[BootstrapTokenSecretHashedTokenName])), nil +func (r *HumioClusterReconciler) bootstrapTokenReady(ctx context.Context, hc *humiov1alpha1.HumioCluster) (bool, error) { + humioBootstrapTokens, err := kubernetes.ListHumioBootstrapTokens(ctx, r.Client, hc.GetNamespace(), kubernetes.LabelsForHumioBootstrapToken(hc.GetName())) + if err != nil { + return false, r.logErrorAndReturn(err, "failed to get bootstrap token") } - //// TODO: Should we error here? - return fmt.Sprintf("%v", err), fmt.Errorf("secret does not contain key %s", BootstrapTokenSecretHashedTokenName) + if len(humioBootstrapTokens) > 0 { + if humioBootstrapTokens[0].Status.State == humiov1alpha1.HumioBootstrapTokenStateReady { + return true, nil + } + } + return false, nil } // findHumioNodeNameAndCertHash looks up the name of a free node certificate to use and the hash of the certificate specification diff --git a/controllers/suite/common.go b/controllers/suite/common.go index a0af2f2a..e68db369 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -384,6 +384,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum // }, //}, Status: humiov1alpha1.HumioBootstrapTokenStatus{ + State: humiov1alpha1.HumioBootstrapTokenStateReady, TokenSecretKeyRef: humiov1alpha1.HumioTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: fmt.Sprintf("%s-bootstrap-token", key.Name), @@ -416,6 +417,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Eventually(func() error { var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken Expect(k8sClient.Get(ctx, key, &updatedHumioBootstrapToken)).Should(Succeed()) + updatedHumioBootstrapToken.Status.State = humiov1alpha1.HumioBootstrapTokenStateReady updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ diff --git a/pkg/kubernetes/humio_bootstrap_tokens.go b/pkg/kubernetes/humio_bootstrap_tokens.go index 4f3cbf74..b04fb06b 100644 --- a/pkg/kubernetes/humio_bootstrap_tokens.go +++ b/pkg/kubernetes/humio_bootstrap_tokens.go @@ -79,19 +79,3 @@ func ListHumioBootstrapTokens(ctx context.Context, c client.Client, humioCluster return foundHumioBootstrapTokenList.Items, nil } - -// GetHumioBootstrapToken retrieves the HumioBootstrapToken given the humio cluster name and namespace -func GetHumioBootstrapToken(ctx context.Context, c client.Client, humioClusterName string, humioClusterNamespace string) (humiov1alpha1.HumioBootstrapToken, error) { - matchingLabels := LabelsForHumio(humioClusterName) - humioBootstrapTokenList, err := ListHumioBootstrapTokens(ctx, c, humioClusterNamespace, matchingLabels) - if err != nil { - return humiov1alpha1.HumioBootstrapToken{}, err - } - - if len(humioBootstrapTokenList) == 0 { - return humiov1alpha1.HumioBootstrapToken{}, fmt.Errorf("no HumioBootstrapTokens found with name %s in namespace %s", humioClusterName, humioClusterNamespace) - } else if len(humioBootstrapTokenList) > 1 { - return humiov1alpha1.HumioBootstrapToken{}, fmt.Errorf("too many HumioBootstrapTokens found with name %s in namespace %s (count %d)", humioClusterName, humioClusterNamespace, len(humioBootstrapTokenList)) - } - return humioBootstrapTokenList[0], nil -} From fe44a4e840a7c18047e86913ad4fff34616692ee Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 9 Oct 2023 15:57:57 -0700 Subject: [PATCH 16/54] more cleanup --- api/v1alpha1/humiobootstraptoken_types.go | 47 ++++--- api/v1alpha1/zz_generated.deepcopy.go | 20 +-- .../core.humio.com_humiobootstraptokens.yaml | 130 ++++++++++++++---- .../core.humio.com_humiobootstraptokens.yaml | 130 ++++++++++++++---- config/rbac/role.yaml | 38 ++--- controllers/humioaction_controller.go | 4 +- controllers/humioalert_controller.go | 4 +- controllers/humiobootstraptoken_controller.go | 31 ++--- controllers/humiobootstraptoken_defaults.go | 66 +++++++-- controllers/humiobootstraptoken_pods.go | 29 +--- controllers/humiocluster_controller.go | 66 ++++----- controllers/humiocluster_permission_tokens.go | 10 +- controllers/humiocluster_pod_status.go | 2 +- controllers/humiocluster_pods.go | 12 +- controllers/humiocluster_secrets.go | 2 +- .../humioexternalcluster_controller.go | 2 +- controllers/humioingesttoken_controller.go | 12 +- controllers/humioparser_controller.go | 10 +- controllers/humiorepository_controller.go | 10 +- controllers/humioview_controller.go | 4 +- 20 files changed, 415 insertions(+), 214 deletions(-) diff --git a/api/v1alpha1/humiobootstraptoken_types.go b/api/v1alpha1/humiobootstraptoken_types.go index b88bfffb..cd18baf6 100644 --- a/api/v1alpha1/humiobootstraptoken_types.go +++ b/api/v1alpha1/humiobootstraptoken_types.go @@ -30,46 +30,61 @@ const ( // HumioBootstrapTokenSpec defines the bootstrap token that Humio will use to bootstrap authentication type HumioBootstrapTokenSpec struct { - // TODO: determine if we even want to reference the cluster here - // ManagedClusterName + // ManagedClusterName refers to the name of the HumioCluster which will use this bootstrap token ManagedClusterName string `json:"managedClusterName,omitempty"` - // ExternalClusterName refers to an object of type HumioExternalCluster where the Humio resources should be created. + // ExternalClusterName refers to the name of the HumioExternalCluster which will use this bootstrap token for authentication // This conflicts with ManagedClusterName. ExternalClusterName string `json:"externalClusterName,omitempty"` - - Image string `json:"image,omitempty"` - TokenSecret HumioTokenSecretSpec `json:"tokenSecret,omitempty"` + // Image can be set to override the image used to run when generating a bootstrap token. This will default to the image + // that is used by either the HumioCluster resource or the first NodePool resource if ManagedClusterName is set on the HumioBootstrapTokenSpec + Image string `json:"bootstrapImage,omitempty"` + // ImagePullSecrets defines the imagepullsecrets for the bootstrap image onetime pod. These secrets are not created by the operator. This will default to the imagePullSecrets + // that are used by either the HumioCluster resource or the first NodePool resource if ManagedClusterName is set on the HumioBootstrapTokenSpec + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` + // Resources is the kubernetes resource limits for the bootstrap onetime pod + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + // TokenSecret is the secret reference that contains the token to use for this HumioBootstrapToken. This is used if one wants to use an existing + // token for the BootstrapToken rather than letting the operator create one by running a bootstrap token onetime pod + TokenSecret HumioTokenSecretSpec `json:"tokenSecret,omitempty"` + // HashedTokenSecret is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is used if one wants to use an existing + // hashed token for the BootstrapToken rather than letting the operator create one by running a bootstrap token onetime pod HashedTokenSecret HumioHashedTokenSecretSpec `json:"hashedTokenSecret,omitempty"` } type HumioTokenSecretSpec struct { - // TODO: we could clean this up by removing the "AutoCreate" and in docs explain if you want to use your own secret - // then create the secret before the bootstraptoken resource - AutoCreate *bool `json:"autoCreate,omitempty"` + // SecretKeyRef is the secret key reference to a kubernetes secret containing the bootstrap token secret SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } type HumioHashedTokenSecretSpec struct { - // TODO: maybe remove AutoCreate - AutoCreate *bool `json:"autoCreate,omitempty"` + // SecretKeyRef is the secret key reference to a kubernetes secret containing the bootstrap hashed token secret SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } type HumioBootstrapTokenStatus struct { - // TODO set the status. This is used by the HumioCluster resource to get the secret reference and load the secret. We don't want to rely on the spec - // here as the spec could be empty. Or do we want to - //Created bool `json:"created,omitempty"` // State can be "NotReady" or "Ready" - State string `json:"state,omitempty"` - TokenSecretKeyRef HumioTokenSecretStatus `json:"tokenSecretStatus,omitempty"` + State string `json:"state,omitempty"` + // TokenSecretKeyRef contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined + // in the spec or automatically created + TokenSecretKeyRef HumioTokenSecretStatus `json:"tokenSecretStatus,omitempty"` + // HashedTokenSecret is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is set regardless of whether it's defined + // in the spec or automatically created HashedTokenSecretKeyRef HumioHashedTokenSecretStatus `json:"hashedTokenSecretStatus,omitempty"` } +// HumioTokenSecretStatus contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined +// in the spec or automatically created type HumioTokenSecretStatus struct { + // SecretKeyRef contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined + // in the spec or automatically created SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } +// HumioTokenSecretStatus contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined +// in the spec or automatically created type HumioHashedTokenSecretStatus struct { + // SecretKeyRef is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is set regardless of whether it's defined + // in the spec or automatically created SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 98fa63c5..5afa3633 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -497,6 +497,16 @@ func (in *HumioBootstrapTokenList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioBootstrapTokenSpec) DeepCopyInto(out *HumioBootstrapTokenSpec) { *out = *in + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]v1.LocalObjectReference, len(*in)) + copy(*out, *in) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } in.TokenSecret.DeepCopyInto(&out.TokenSecret) in.HashedTokenSecret.DeepCopyInto(&out.HashedTokenSecret) } @@ -926,11 +936,6 @@ func (in *HumioFilterAlertSpec) DeepCopy() *HumioFilterAlertSpec { ======= func (in *HumioHashedTokenSecretSpec) DeepCopyInto(out *HumioHashedTokenSecretSpec) { *out = *in - if in.AutoCreate != nil { - in, out := &in.AutoCreate, &out.AutoCreate - *out = new(bool) - **out = **in - } if in.SecretKeyRef != nil { in, out := &in.SecretKeyRef, &out.SecretKeyRef *out = new(v1.SecretKeySelector) @@ -1643,11 +1648,6 @@ func (in *HumioRetention) DeepCopy() *HumioRetention { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioTokenSecretSpec) DeepCopyInto(out *HumioTokenSecretSpec) { *out = *in - if in.AutoCreate != nil { - in, out := &in.AutoCreate, &out.AutoCreate - *out = new(bool) - **out = **in - } if in.SecretKeyRef != nil { in, out := &in.SecretKeyRef, &out.SecretKeyRef *out = new(v1.SecretKeySelector) diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index 049ac2fb..240a630a 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -49,18 +49,27 @@ spec: description: HumioBootstrapTokenSpec defines the bootstrap token that Humio will use to bootstrap authentication properties: + bootstrapImage: + description: Image can be set to override the image used to run when + generating a bootstrap token. This will default to the image that + is used by either the HumioCluster resource or the first NodePool + resource if ManagedClusterName is set on the HumioBootstrapTokenSpec + type: string externalClusterName: - description: ExternalClusterName refers to an object of type HumioExternalCluster - where the Humio resources should be created. This conflicts with - ManagedClusterName. + description: ExternalClusterName refers to the name of the HumioExternalCluster + which will use this bootstrap token for authentication This conflicts + with ManagedClusterName. type: string hashedTokenSecret: + description: HashedTokenSecret is the secret reference that contains + the hashed token to use for this HumioBootstrapToken. This is used + if one wants to use an existing hashed token for the BootstrapToken + rather than letting the operator create one by running a bootstrap + token onetime pod properties: - autoCreate: - description: 'TODO: maybe remove AutoCreate' - type: boolean secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef is the secret key reference to a kubernetes + secret containing the bootstrap hashed token secret properties: key: description: The key of the secret to select from. Must be @@ -78,21 +87,84 @@ spec: - key type: object type: object - image: - type: string + imagePullSecrets: + description: ImagePullSecrets defines the imagepullsecrets for the + bootstrap image onetime pod. These secrets are not created by the + operator. This will default to the imagePullSecrets that are used + by either the HumioCluster resource or the first NodePool resource + if ManagedClusterName is set on the HumioBootstrapTokenSpec + items: + description: LocalObjectReference contains enough information to + let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array managedClusterName: - description: 'TODO: determine if we even want to reference the cluster - here ManagedClusterName' + description: ManagedClusterName refers to the name of the HumioCluster + which will use this bootstrap token type: string + resources: + description: Resources is the kubernetes resource limits for the bootstrap + onetime pod + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object tokenSecret: + description: TokenSecret is the secret reference that contains the + token to use for this HumioBootstrapToken. This is used if one wants + to use an existing token for the BootstrapToken rather than letting + the operator create one by running a bootstrap token onetime pod properties: - autoCreate: - description: 'TODO: we could clean this up by removing the "AutoCreate" - and in docs explain if you want to use your own secret then - create the secret before the bootstraptoken resource' - type: boolean secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef is the secret key reference to a kubernetes + secret containing the bootstrap token secret properties: key: description: The key of the secret to select from. Must be @@ -114,9 +186,16 @@ spec: status: properties: hashedTokenSecretStatus: + description: HashedTokenSecret is the secret reference that contains + the hashed token to use for this HumioBootstrapToken. This is set + regardless of whether it's defined in the spec or automatically + created properties: secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef is the secret reference that contains + the hashed token to use for this HumioBootstrapToken. This is + set regardless of whether it's defined in the spec or automatically + created properties: key: description: The key of the secret to select from. Must be @@ -135,16 +214,19 @@ spec: type: object type: object state: - description: TODO set the status. This is used by the HumioCluster - resource to get the secret reference and load the secret. We don't - want to rely on the spec here as the spec could be empty. Or do - we want to Created bool `json:"created,omitempty"` - State can be "NotReady" or "Ready" + description: State can be "NotReady" or "Ready" type: string tokenSecretStatus: + description: TokenSecretKeyRef contains the secret key reference to + a kubernetes secret containing the bootstrap token secret. This + is set regardless of whether it's defined in the spec or automatically + created properties: secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef contains the secret key reference to + a kubernetes secret containing the bootstrap token secret. This + is set regardless of whether it's defined in the spec or automatically + created properties: key: description: The key of the secret to select from. Must be diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 049ac2fb..240a630a 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -49,18 +49,27 @@ spec: description: HumioBootstrapTokenSpec defines the bootstrap token that Humio will use to bootstrap authentication properties: + bootstrapImage: + description: Image can be set to override the image used to run when + generating a bootstrap token. This will default to the image that + is used by either the HumioCluster resource or the first NodePool + resource if ManagedClusterName is set on the HumioBootstrapTokenSpec + type: string externalClusterName: - description: ExternalClusterName refers to an object of type HumioExternalCluster - where the Humio resources should be created. This conflicts with - ManagedClusterName. + description: ExternalClusterName refers to the name of the HumioExternalCluster + which will use this bootstrap token for authentication This conflicts + with ManagedClusterName. type: string hashedTokenSecret: + description: HashedTokenSecret is the secret reference that contains + the hashed token to use for this HumioBootstrapToken. This is used + if one wants to use an existing hashed token for the BootstrapToken + rather than letting the operator create one by running a bootstrap + token onetime pod properties: - autoCreate: - description: 'TODO: maybe remove AutoCreate' - type: boolean secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef is the secret key reference to a kubernetes + secret containing the bootstrap hashed token secret properties: key: description: The key of the secret to select from. Must be @@ -78,21 +87,84 @@ spec: - key type: object type: object - image: - type: string + imagePullSecrets: + description: ImagePullSecrets defines the imagepullsecrets for the + bootstrap image onetime pod. These secrets are not created by the + operator. This will default to the imagePullSecrets that are used + by either the HumioCluster resource or the first NodePool resource + if ManagedClusterName is set on the HumioBootstrapTokenSpec + items: + description: LocalObjectReference contains enough information to + let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array managedClusterName: - description: 'TODO: determine if we even want to reference the cluster - here ManagedClusterName' + description: ManagedClusterName refers to the name of the HumioCluster + which will use this bootstrap token type: string + resources: + description: Resources is the kubernetes resource limits for the bootstrap + onetime pod + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object tokenSecret: + description: TokenSecret is the secret reference that contains the + token to use for this HumioBootstrapToken. This is used if one wants + to use an existing token for the BootstrapToken rather than letting + the operator create one by running a bootstrap token onetime pod properties: - autoCreate: - description: 'TODO: we could clean this up by removing the "AutoCreate" - and in docs explain if you want to use your own secret then - create the secret before the bootstraptoken resource' - type: boolean secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef is the secret key reference to a kubernetes + secret containing the bootstrap token secret properties: key: description: The key of the secret to select from. Must be @@ -114,9 +186,16 @@ spec: status: properties: hashedTokenSecretStatus: + description: HashedTokenSecret is the secret reference that contains + the hashed token to use for this HumioBootstrapToken. This is set + regardless of whether it's defined in the spec or automatically + created properties: secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef is the secret reference that contains + the hashed token to use for this HumioBootstrapToken. This is + set regardless of whether it's defined in the spec or automatically + created properties: key: description: The key of the secret to select from. Must be @@ -135,16 +214,19 @@ spec: type: object type: object state: - description: TODO set the status. This is used by the HumioCluster - resource to get the secret reference and load the secret. We don't - want to rely on the spec here as the spec could be empty. Or do - we want to Created bool `json:"created,omitempty"` - State can be "NotReady" or "Ready" + description: State can be "NotReady" or "Ready" type: string tokenSecretStatus: + description: TokenSecretKeyRef contains the secret key reference to + a kubernetes secret containing the bootstrap token secret. This + is set regardless of whether it's defined in the spec or automatically + created properties: secretKeyRef: - description: SecretKeySelector selects a key of a Secret. + description: SecretKeyRef contains the secret key reference to + a kubernetes secret containing the bootstrap token secret. This + is set regardless of whether it's defined in the spec or automatically + created properties: key: description: The key of the secret to select from. Must be diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index a538a200..201b7010 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -9,7 +9,7 @@ rules: resources: - configmaps verbs: - - create + - allowsCreate - delete - get - list @@ -21,7 +21,7 @@ rules: resources: - endpoints verbs: - - create + - allowsCreate - delete - get - list @@ -33,7 +33,7 @@ rules: resources: - events verbs: - - create + - allowsCreate - delete - get - list @@ -45,7 +45,7 @@ rules: resources: - persistentvolumeclaims verbs: - - create + - allowsCreate - delete - get - list @@ -57,7 +57,7 @@ rules: resources: - pods verbs: - - create + - allowsCreate - delete - get - list @@ -69,7 +69,7 @@ rules: resources: - secrets verbs: - - create + - allowsCreate - delete - get - list @@ -81,7 +81,7 @@ rules: resources: - serviceaccounts verbs: - - create + - allowsCreate - delete - get - list @@ -93,7 +93,7 @@ rules: resources: - services verbs: - - create + - allowsCreate - delete - get - list @@ -105,7 +105,7 @@ rules: resources: - services/finalizers verbs: - - create + - allowsCreate - delete - get - list @@ -117,7 +117,7 @@ rules: resources: - HumioBootstrapTokens verbs: - - create + - allowsCreate - delete - get - list @@ -169,7 +169,7 @@ rules: resources: - humioactions verbs: - - create + - allowsCreate - delete - get - list @@ -195,7 +195,7 @@ rules: resources: - humioalerts verbs: - - create + - allowsCreate - delete - get - list @@ -221,7 +221,7 @@ rules: resources: - humioclusters verbs: - - create + - allowsCreate - delete - get - list @@ -247,7 +247,7 @@ rules: resources: - humioexternalclusters verbs: - - create + - allowsCreate - delete - get - list @@ -299,7 +299,7 @@ rules: resources: - humioingesttokens verbs: - - create + - allowsCreate - delete - get - list @@ -325,7 +325,7 @@ rules: resources: - humioparsers verbs: - - create + - allowsCreate - delete - get - list @@ -351,7 +351,7 @@ rules: resources: - humiorepositories verbs: - - create + - allowsCreate - delete - get - list @@ -403,7 +403,7 @@ rules: resources: - humioviews verbs: - - create + - allowsCreate - delete - get - list @@ -429,7 +429,7 @@ rules: resources: - ingress verbs: - - create + - allowsCreate - delete - get - list diff --git a/controllers/humioaction_controller.go b/controllers/humioaction_controller.go index 796a6268..7d43a0cc 100644 --- a/controllers/humioaction_controller.go +++ b/controllers/humioaction_controller.go @@ -44,7 +44,7 @@ type HumioActionReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioactions,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioactions,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioactions/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioactions/finalizers,verbs=update @@ -158,7 +158,7 @@ func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, config r.Log.Info("Action doesn't exist. Now adding action") addedAction, err := r.HumioClient.AddAction(config, req, ha) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create action") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate action") } r.Log.Info("Created action", "Action", ha.Spec.Name, "ID", addedAction.ID) return reconcile.Result{Requeue: true}, nil diff --git a/controllers/humioalert_controller.go b/controllers/humioalert_controller.go index 1eded9bf..6199ebf6 100644 --- a/controllers/humioalert_controller.go +++ b/controllers/humioalert_controller.go @@ -48,7 +48,7 @@ type HumioAlertReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts/finalizers,verbs=update @@ -148,7 +148,7 @@ func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, config * r.Log.Info("Alert doesn't exist. Now adding alert") addedAlert, err := r.HumioClient.AddAlert(config, req, ha) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create alert") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate alert") } r.Log.Info("Created alert", "Alert", ha.Spec.Name, "ID", addedAlert.ID) return reconcile.Result{Requeue: true}, nil diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 2ba4bc80..89e9886b 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -62,7 +62,7 @@ type HumioBootstrapTokenSecretData struct { HashedToken string `json:"hashedToken"` } -//+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/finalizers,verbs=update @@ -150,7 +150,7 @@ func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []stri &clientcmd.ConfigOverrides{}, ) - // create the Config object + // allowsCreate the Config object cfg, err := configLoader.ClientConfig() if err != nil { return "", err @@ -161,7 +161,7 @@ func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []stri cfg.GroupVersion = &corev1.SchemeGroupVersion cfg.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - // create a RESTClient + // allowsCreate a RESTClient rc, err := rest.RESTClientFor(cfg) if err != nil { return "", err @@ -210,10 +210,7 @@ func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humi } } humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, humioCluster) - pod, err := ConstructBootstrapPod(&humioBootstrapTokenConfig) - if err != nil { - return &corev1.Pod{}, r.logErrorAndReturn(err, "could not construct pod") - } + pod := ConstructBootstrapPod(&humioBootstrapTokenConfig) if err := r.Get(ctx, types.NamespacedName{ Namespace: pod.Namespace, Name: pod.Name, @@ -224,7 +221,7 @@ func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humi } r.Log.Info("creating onetime pod") if err := r.Create(ctx, pod); err != nil { - return &corev1.Pod{}, r.logErrorAndReturn(err, "could not create pod") + return &corev1.Pod{}, r.logErrorAndReturn(err, "could not allowsCreate pod") } return pod, nil } @@ -235,10 +232,7 @@ func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humi func (r *HumioBootstrapTokenReconciler) deletePod(ctx context.Context, hbt *humiov1alpha1.HumioBootstrapToken, hc *humiov1alpha1.HumioCluster) error { existingPod := &corev1.Pod{} humioBootstrapTokenConfig := NewHumioBootstrapTokenConfig(hbt, hc) - pod, err := ConstructBootstrapPod(&humioBootstrapTokenConfig) - if err != nil { - return r.logErrorAndReturn(err, "could not construct pod") - } + pod := ConstructBootstrapPod(&humioBootstrapTokenConfig) if err := r.Get(ctx, types.NamespacedName{ Namespace: pod.Namespace, Name: pod.Name, @@ -287,16 +281,21 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.C "secret does not contain value for key \"%s\"", hbt.Spec.HashedTokenSecret.SecretKeyRef.Name, hbt.Spec.HashedTokenSecret.SecretKeyRef.Key)) } } - // TODO: do we really need autocreate option, or just assume create if there is no hbt.Spec.TokenSecret.SecretKeyRef set? - // I think we do since it's confusing if we only have the conditional based on one or both of hbt.Spec.TokenSecret.SecretKeyRef and hbt.Spec.HashedTokenSecret.SecretKeyRef.Key - if humioBootstrapTokenConfig.autoCreate() { + if err := humioBootstrapTokenConfig.validate(); err != nil { + return r.logErrorAndReturn(err, fmt.Sprintf("could not validate bootstrap config for %s", hbt.Name)) + } + okayToCreate, err := humioBootstrapTokenConfig.allowsCreate() + if err != nil { + return r.logErrorAndReturn(err, "cannot allowsCreate bootstrap token") + } + if okayToCreate { secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { return r.logErrorAndReturn(err, "could not set controller reference") } r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) if err := r.Create(ctx, secret); err != nil { - return r.logErrorAndReturn(err, "could not create secret") + return r.logErrorAndReturn(err, "could not allowsCreate secret") } } } diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index 735c4a5e..b9cff5ea 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -3,13 +3,17 @@ package controllers import ( "fmt" + "k8s.io/apimachinery/pkg/api/resource" + + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + "github.com/humio/humio-operator/api/v1alpha1" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" ) const ( BootstrapTokenSuffix = "bootstrap-token" - //HashedBootstrapTokenSuffix = "hashed-bootstrap-token" ) type HumioBootstrapTokenConfig struct { @@ -28,19 +32,24 @@ func (b *HumioBootstrapTokenConfig) bootstrapTokenName() string { return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, BootstrapTokenSuffix) } -//func (b *HumioBootstrapTokenConfig) hashedBootstrapTokenName() string { -// if b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef != nil { -// return b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef.Name -// } -// return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, HashedBootstrapTokenSuffix) -//} +func (b *HumioBootstrapTokenConfig) allowsCreate() (bool, error) { + if err := b.validate(); err != nil { + return false, err + } + if b.BootstrapToken.Spec.TokenSecret.SecretKeyRef == nil && b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef == nil { + return true, nil + } + return false, nil +} -// TODO: remove this? -func (b *HumioBootstrapTokenConfig) autoCreate() bool { - if b.BootstrapToken.Spec.TokenSecret.AutoCreate != nil { - return *b.BootstrapToken.Spec.TokenSecret.AutoCreate +func (b *HumioBootstrapTokenConfig) validate() error { + if b.BootstrapToken.Spec.TokenSecret.SecretKeyRef == nil && b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef == nil { + return nil } - return true + if b.BootstrapToken.Spec.TokenSecret.SecretKeyRef != nil && b.BootstrapToken.Spec.HashedTokenSecret.SecretKeyRef != nil { + return nil + } + return fmt.Errorf("must set both tokenSecret.secretKeyRef as well as hashedTokenSecret.secretKeyRef") } func (b *HumioBootstrapTokenConfig) image() string { @@ -58,6 +67,39 @@ func (b *HumioBootstrapTokenConfig) image() string { return Image } +func (b *HumioBootstrapTokenConfig) imagePullSecrets() []v1.LocalObjectReference { + if len(b.BootstrapToken.Spec.ImagePullSecrets) > 0 { + return b.BootstrapToken.Spec.ImagePullSecrets + } + if len(b.ManagedHumioCluster.Spec.ImagePullSecrets) > 0 { + return b.ManagedHumioCluster.Spec.ImagePullSecrets + } + if b.ManagedHumioCluster != nil { + if len(b.ManagedHumioCluster.Spec.NodePools) > 0 { + if len(b.ManagedHumioCluster.Spec.NodePools[0].ImagePullSecrets) > 0 { + return b.ManagedHumioCluster.Spec.NodePools[0].ImagePullSecrets + } + } + } + return []v1.LocalObjectReference{} +} + +func (b *HumioBootstrapTokenConfig) resources() corev1.ResourceRequirements { + if b.BootstrapToken.Spec.Resources != nil { + return *b.BootstrapToken.Spec.Resources + } + return corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(50*1024*1024, resource.BinarySI), + }, + Requests: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(50*1024*1024, resource.BinarySI), + }, + } +} + func (b *HumioBootstrapTokenConfig) name() string { return b.BootstrapToken.Name } diff --git a/controllers/humiobootstraptoken_pods.go b/controllers/humiobootstraptoken_pods.go index 512fd6ff..de0d24fa 100644 --- a/controllers/humiobootstraptoken_pods.go +++ b/controllers/humiobootstraptoken_pods.go @@ -8,30 +8,19 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func ConstructBootstrapPod(bootstrapConfig *HumioBootstrapTokenConfig) (*corev1.Pod, error) { - //var pod corev1.Pod - //productVersion := "unknown" - //imageSplit := strings.SplitN(bootstrapConfig.image(), ":", 2) - //if len(imageSplit) == 2 { - // productVersion = imageSplit[1] - //} +func ConstructBootstrapPod(bootstrapConfig *HumioBootstrapTokenConfig) *corev1.Pod { userID := int64(65534) - return &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%s-bootstrap-token-onetime", bootstrapConfig.name()), Namespace: bootstrapConfig.namespace(), }, Spec: corev1.PodSpec{ - //ShareProcessNamespace: hnp.GetShareProcessNamespace(), - //ServiceAccountName: hnp.GetHumioServiceAccountName(), - ////ImagePullSecrets: hnp.GetImagePullSecrets(), + ImagePullSecrets: bootstrapConfig.imagePullSecrets(), Containers: []corev1.Container{ { - Name: HumioContainerName, - Image: bootstrapConfig.image(), - ////ImagePullPolicy: hnp.GetImagePullPolicy(), - //Command: []string{"/bin/sh"}, + Name: HumioContainerName, + Image: bootstrapConfig.image(), Command: []string{"/bin/sleep", "900"}, Env: []corev1.EnvVar{ { @@ -39,7 +28,7 @@ func ConstructBootstrapPod(bootstrapConfig *HumioBootstrapTokenConfig) (*corev1. Value: "log4j2-json-stdout.xml", }, }, - //Resources: hnp.GetResources(), + Resources: bootstrapConfig.resources(), SecurityContext: &corev1.SecurityContext{ Privileged: helpers.BoolPtr(false), AllowPrivilegeEscalation: helpers.BoolPtr(false), @@ -53,12 +42,6 @@ func ConstructBootstrapPod(bootstrapConfig *HumioBootstrapTokenConfig) (*corev1. }, }, }, - //Affinity: hnp.GetAffinity(), - //Tolerations: hnp.GetTolerations(), - //TopologySpreadConstraints: hnp.GetTopologySpreadConstraints(), - //SecurityContext: hnp.GetPodSecurityContext(), - //TerminationGracePeriodSeconds: hnp.GetTerminationGracePeriodSeconds(), }, - }, nil - + } } diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index b0e1965a..ad57d578 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -61,19 +61,19 @@ const ( MaximumMinReadyRequeue = time.Second * 300 ) -//+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters/finalizers,verbs=update -//+kubebuilder:rbac:groups=core,resources=pods,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=services,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=services/finalizers,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=endpoints,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=events,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=secrets,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=create;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingress,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=pods,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=services,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=services/finalizers,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=endpoints,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=events,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=secrets,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingress,verbs=allowsCreate;delete;get;list;patch;update;watch func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { if r.Namespace != "" { @@ -470,7 +470,7 @@ func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Co } err = r.Create(ctx, hbt) if err != nil { - return r.logErrorAndReturn(err, "could not create bootstrap token resource") + return r.logErrorAndReturn(err, "could not allowsCreate bootstrap token resource") } return nil } @@ -516,7 +516,7 @@ func (r *HumioClusterReconciler) ensureExtraKafkaConfigsConfigMap(ctx context.Co } r.Log.Info(fmt.Sprintf("creating configMap: %s", configMap.Name)) if err = r.Create(ctx, configMap); err != nil { - return r.logErrorAndReturn(err, "unable to create extra kafka configs configmap") + return r.logErrorAndReturn(err, "unable to allowsCreate extra kafka configs configmap") } r.Log.Info(fmt.Sprintf("successfully created extra kafka configs configmap name %s", configMap.Name)) humioClusterPrometheusMetrics.Counters.ConfigMapsCreated.Inc() @@ -611,7 +611,7 @@ func (r *HumioClusterReconciler) ensureViewGroupPermissionsConfigMap(ctx context r.Log.Info(fmt.Sprintf("creating configMap: %s", configMap.Name)) if err = r.Create(ctx, configMap); err != nil { - return r.logErrorAndReturn(err, "unable to create view group permissions configmap") + return r.logErrorAndReturn(err, "unable to allowsCreate view group permissions configmap") } r.Log.Info(fmt.Sprintf("successfully created view group permissions configmap name %s", configMap.Name)) humioClusterPrometheusMetrics.Counters.ConfigMapsCreated.Inc() @@ -649,7 +649,7 @@ func (r *HumioClusterReconciler) ensureRolePermissionsConfigMap(ctx context.Cont r.Log.Info(fmt.Sprintf("creating configMap: %s", configMap.Name)) if err = r.Create(ctx, configMap); err != nil { - return r.logErrorAndReturn(err, "unable to create role permissions configmap") + return r.logErrorAndReturn(err, "unable to allowsCreate role permissions configmap") } r.Log.Info(fmt.Sprintf("successfully created role permissions configmap name %s", configMap.Name)) humioClusterPrometheusMetrics.Counters.ConfigMapsCreated.Inc() @@ -775,7 +775,7 @@ func (r *HumioClusterReconciler) ensureNginxIngress(ctx context.Context, hc *hum return r.logErrorAndReturn(err, "could not get hostnames for ingress resources") } - // Due to ingress-ingress relying on ingress object annotations to enable/disable/adjust certain features we create multiple ingress objects. + // Due to ingress-ingress relying on ingress object annotations to enable/disable/adjust certain features we allowsCreate multiple ingress objects. ingresses := []*networkingv1.Ingress{ ConstructGeneralIngress(hc, hostname), ConstructStreamingQueryIngress(hc, hostname), @@ -785,7 +785,7 @@ func (r *HumioClusterReconciler) ensureNginxIngress(ctx context.Context, hc *hum for _, desiredIngress := range ingresses { // After constructing ingress objects, the rule's host attribute should be set to that which is defined in // the humiocluster spec. If the rule host is not set, then it means the hostname or esHostname was not set in - // the spec, so we do not create the ingress resource + // the spec, so we do not allowsCreate the ingress resource var createIngress bool for _, rule := range desiredIngress.Spec.Rules { if rule.Host != "" { @@ -803,7 +803,7 @@ func (r *HumioClusterReconciler) ensureNginxIngress(ctx context.Context, hc *hum r.Log.Info(fmt.Sprintf("creating ingress: %s", desiredIngress.Name)) err = r.Create(ctx, desiredIngress) if err != nil { - return r.logErrorAndReturn(err, "unable to create ingress") + return r.logErrorAndReturn(err, "unable to allowsCreate ingress") } r.Log.Info(fmt.Sprintf("successfully created ingress with name %s", desiredIngress.Name)) humioClusterPrometheusMetrics.Counters.IngressesCreated.Inc() @@ -926,10 +926,10 @@ func (r *HumioClusterReconciler) ensureValidCAIssuer(ctx context.Context, hc *hu if err := controllerutil.SetControllerReference(hc, &caIssuer, r.Scheme()); err != nil { return r.logErrorAndReturn(err, "could not set controller reference") } - // should only create it if it doesn't exist + // should only allowsCreate it if it doesn't exist r.Log.Info(fmt.Sprintf("creating CA Issuer: %s", caIssuer.Name)) if err = r.Create(ctx, &caIssuer); err != nil { - return r.logErrorAndReturn(err, "could not create CA Issuer") + return r.logErrorAndReturn(err, "could not allowsCreate CA Issuer") } return nil } @@ -980,7 +980,7 @@ func (r *HumioClusterReconciler) ensureValidCASecret(ctx context.Context, hc *hu r.Log.Info(fmt.Sprintf("creating CA secret: %s", caSecret.Name)) err = r.Create(ctx, caSecret) if err != nil { - return r.logErrorAndReturn(err, "could not create secret with CA") + return r.logErrorAndReturn(err, "could not allowsCreate secret with CA") } return nil @@ -1007,7 +1007,7 @@ func (r *HumioClusterReconciler) ensureHumioClusterKeystoreSecret(ctx context.Co } r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) if err := r.Create(ctx, secret); err != nil { - return r.logErrorAndReturn(err, "could not create secret") + return r.logErrorAndReturn(err, "could not allowsCreate secret") } return nil } else { @@ -1040,7 +1040,7 @@ func (r *HumioClusterReconciler) ensureHumioClusterCACertBundle(ctx context.Cont } r.Log.Info(fmt.Sprintf("creating certificate: %s", cert.Name)) if err := r.Create(ctx, &cert); err != nil { - return r.logErrorAndReturn(err, "could not create certificate") + return r.logErrorAndReturn(err, "could not allowsCreate certificate") } return nil } @@ -1070,7 +1070,7 @@ func (r *HumioClusterReconciler) ensureHumioNodeCertificates(ctx context.Context } r.Log.Info(fmt.Sprintf("creating node certificate: %s", certificate.Name)) if err = r.Create(ctx, &certificate); err != nil { - return r.logErrorAndReturn(err, "could create node certificate") + return r.logErrorAndReturn(err, "could allowsCreate node certificate") } if err = r.waitForNewNodeCertificate(ctx, hc, hnp, existingNodeCertCount+1); err != nil { @@ -1091,7 +1091,7 @@ func (r *HumioClusterReconciler) ensureInitClusterRole(ctx context.Context, hnp r.Log.Info(fmt.Sprintf("creating cluster role: %s", clusterRole.Name)) err = r.Create(ctx, clusterRole) if err != nil { - return r.logErrorAndReturn(err, "unable to create init cluster role") + return r.logErrorAndReturn(err, "unable to allowsCreate init cluster role") } r.Log.Info(fmt.Sprintf("successfully created init cluster role %s", clusterRoleName)) humioClusterPrometheusMetrics.Counters.ClusterRolesCreated.Inc() @@ -1117,7 +1117,7 @@ func (r *HumioClusterReconciler) ensureInitClusterRoleBinding(ctx context.Contex r.Log.Info(fmt.Sprintf("creating cluster role: %s", clusterRole.Name)) err = r.Create(ctx, clusterRole) if err != nil { - return r.logErrorAndReturn(err, "unable to create init cluster role binding") + return r.logErrorAndReturn(err, "unable to allowsCreate init cluster role binding") } r.Log.Info(fmt.Sprintf("successfully created init cluster role binding %s", clusterRoleBindingName)) humioClusterPrometheusMetrics.Counters.ClusterRoleBindingsCreated.Inc() @@ -1164,7 +1164,7 @@ func (r *HumioClusterReconciler) ensureServiceAccountExists(ctx context.Context, r.Log.Info(fmt.Sprintf("creating service account: %s", serviceAccount.Name)) err = r.Create(ctx, serviceAccount) if err != nil { - return r.logErrorAndReturn(err, fmt.Sprintf("unable to create service account %s", serviceAccount.Name)) + return r.logErrorAndReturn(err, fmt.Sprintf("unable to allowsCreate service account %s", serviceAccount.Name)) } r.Log.Info(fmt.Sprintf("successfully created service account %s", serviceAccount.Name)) humioClusterPrometheusMetrics.Counters.ServiceAccountsCreated.Inc() @@ -1194,7 +1194,7 @@ func (r *HumioClusterReconciler) ensureServiceAccountSecretExists(ctx context.Co r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) err = r.Create(ctx, secret) if err != nil { - return r.logErrorAndReturn(err, fmt.Sprintf("unable to create service account secret %s", secret.Name)) + return r.logErrorAndReturn(err, fmt.Sprintf("unable to allowsCreate service account secret %s", secret.Name)) } // check that we can list the new secret // this is to avoid issues where the requeue is faster than kubernetes @@ -1437,7 +1437,7 @@ func (r *HumioClusterReconciler) ensureService(ctx context.Context, hc *humiov1a } r.Log.Info(fmt.Sprintf("creating service %s of type %s with Humio port %d and ES port %d", service.Name, service.Spec.Type, hnp.GetHumioServicePort(), hnp.GetHumioESServicePort())) if err = r.Create(ctx, service); err != nil { - return r.logErrorAndReturn(err, "unable to create service for HumioCluster") + return r.logErrorAndReturn(err, "unable to allowsCreate service for HumioCluster") } return nil } @@ -1462,7 +1462,7 @@ func (r *HumioClusterReconciler) ensureHeadlessServiceExists(ctx context.Context } err = r.Create(ctx, service) if err != nil { - return r.logErrorAndReturn(err, "unable to create headless service for HumioCluster") + return r.logErrorAndReturn(err, "unable to allowsCreate headless service for HumioCluster") } return nil } @@ -2092,7 +2092,7 @@ func (r *HumioClusterReconciler) ensurePodsExist(ctx context.Context, hc *humiov } pod, err := r.createPod(ctx, hc, hnp, attachments, expectedPodsList) if err != nil { - return reconcile.Result{RequeueAfter: time.Second * 5}, r.logErrorAndReturn(err, "unable to create pod") + return reconcile.Result{RequeueAfter: time.Second * 5}, r.logErrorAndReturn(err, "unable to allowsCreate pod") } expectedPodsList = append(expectedPodsList, *pod) humioClusterPrometheusMetrics.Counters.PodsCreated.Inc() @@ -2134,13 +2134,13 @@ func (r *HumioClusterReconciler) ensurePersistentVolumeClaimsExist(ctx context.C } r.Log.Info(fmt.Sprintf("creating pvc: %s", pvc.Name)) if err = r.Create(ctx, pvc); err != nil { - return r.logErrorAndReturn(err, "unable to create pvc") + return r.logErrorAndReturn(err, "unable to allowsCreate pvc") } r.Log.Info(fmt.Sprintf("successfully created pvc %s for HumioCluster %s", pvc.Name, hnp.GetNodePoolName())) humioClusterPrometheusMetrics.Counters.PvcsCreated.Inc() if err = r.waitForNewPvc(ctx, hnp, pvc); err != nil { - return r.logErrorAndReturn(err, "unable to create pvc") + return r.logErrorAndReturn(err, "unable to allowsCreate pvc") } return nil } diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go index 54a009bb..9b1ee32a 100644 --- a/controllers/humiocluster_permission_tokens.go +++ b/controllers/humiocluster_permission_tokens.go @@ -158,7 +158,7 @@ func (r *HumioClusterReconciler) createAndGetAdminAccountUserID(ctx context.Cont return userID, nil } - // If we didn't find a user ID, create a user, extract the user ID and return it + // If we didn't find a user ID, allowsCreate a user, extract the user ID and return it user, err := r.HumioClient.AddUser(config, req, username, true) if err != nil { return "", err @@ -231,7 +231,7 @@ func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, h err := r.Client.Get(ctx, key, adminSecret) if err != nil { if k8serrors.IsNotFound(err) { - // If the secret doesn't exist, create it + // If the secret doesn't exist, allowsCreate it desiredSecret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: key.Name, @@ -244,7 +244,7 @@ func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, h Type: corev1.SecretTypeOpaque, } if err := r.Client.Create(ctx, &desiredSecret); err != nil { - return r.logErrorAndReturn(err, "unable to create secret") + return r.logErrorAndReturn(err, "unable to allowsCreate secret") } return nil } @@ -314,12 +314,12 @@ func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, conf //for { // // Check required files exist before we continue // if !fileExists(localAdminTokenFile) { - // fmt.Printf("Waiting on the Humio container to create the files %s. Retrying in 5 seconds.\n", localAdminTokenFile) + // fmt.Printf("Waiting on the Humio container to allowsCreate the files %s. Retrying in 5 seconds.\n", localAdminTokenFile) // time.Sleep(5 * time.Second) // continue // } // - // // Get local admin token and create humio client with it + // // Get local admin token and allowsCreate humio client with it // localAdminToken := getFileContent(localAdminTokenFile) // if localAdminToken == "" { // fmt.Printf("Local admin token file is empty. This might be due to Humio not being fully started up yet. Retrying in 5 seconds.\n") diff --git a/controllers/humiocluster_pod_status.go b/controllers/humiocluster_pod_status.go index 0f36b6d6..b40b5c87 100644 --- a/controllers/humiocluster_pod_status.go +++ b/controllers/humiocluster_pod_status.go @@ -59,7 +59,7 @@ func (r *HumioClusterReconciler) getPodsStatus(ctx context.Context, hc *humiov1a // pods that were just deleted may still have a status of Ready, but we should not consider them ready if pod.DeletionTimestamp == nil { // If a pod is evicted, we don't want to wait for a new pod spec since the eviction could happen for a - // number of reasons. If we delete the pod then we will re-create it on the next reconcile. Adding the pod + // number of reasons. If we delete the pod then we will re-allowsCreate it on the next reconcile. Adding the pod // to the podsRequiringDeletion list will cause it to be deleted. if pod.Status.Phase == corev1.PodFailed && pod.Status.Reason == podConditionReasonEvicted { r.Log.Info(fmt.Sprintf("pod %s has errors, pod phase: %s, reason: %s", pod.Name, pod.Status.Phase, pod.Status.Reason)) diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index a68cfcea..eeba7077 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -472,9 +472,7 @@ func ConstructPod(hnp *HumioNodePool, humioNodeName string, attachments *podAtta if attachments.bootstrapTokenSecretReference.hash != "" { pod.Annotations[bootstrapTokenHashAnnotation] = attachments.bootstrapTokenSecretReference.hash - //pod.Annotations[bootstrapTokenHashAnnotation] = "asdf" } - //pod.Annotations[bootstrapTokenHashAnnotation] = "asdf" priorityClassName := hnp.GetPriorityClassName() if priorityClassName != "" { pod.Spec.PriorityClassName = priorityClassName @@ -708,7 +706,7 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha return pod, nil } -// waitForNewPods can be used to wait for new pods to be created after the create call is issued. It is important that +// waitForNewPods can be used to wait for new pods to be created after the allowsCreate call is issued. It is important that // the previousPodList contains the list of pods prior to when the new pods were created func (r *HumioClusterReconciler) waitForNewPods(ctx context.Context, hnp *HumioNodePool, previousPodList []corev1.Pod, expectedPods []corev1.Pod) error { // We must check only pods that were running prior to the new pod being created, and we must only include pods that @@ -997,7 +995,7 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum envVarSourceData, err := r.getEnvVarSource(ctx, hnp) if err != nil { - return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", err) + return &podAttachments{}, fmt.Errorf("unable to allowsCreate Pod for HumioCluster: %w", err) } key := types.NamespacedName{ @@ -1007,11 +1005,11 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum hbt := &humiov1alpha1.HumioBootstrapToken{} err = r.Client.Get(ctx, key, hbt) if err != nil { - return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster. could not find HumioBootstrapToken: %w", err) + return &podAttachments{}, fmt.Errorf("unable to allowsCreate Pod for HumioCluster. could not find HumioBootstrapToken: %w", err) } if hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef == nil { - return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", fmt.Errorf("bootstraptoken %s does not contain a status for the hashed token secret reference", hnp.GetBootstrapTokenName())) + return &podAttachments{}, fmt.Errorf("unable to allowsCreate Pod for HumioCluster: %w", fmt.Errorf("bootstraptoken %s does not contain a status for the hashed token secret reference", hnp.GetBootstrapTokenName())) } if hnp.InitContainerDisabled() { @@ -1029,7 +1027,7 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum return &podAttachments{}, fmt.Errorf("unable get init service account secret for HumioCluster: %w", err) } if initSASecretName == "" { - return &podAttachments{}, errors.New("unable to create Pod for HumioCluster: the init service account secret does not exist") + return &podAttachments{}, errors.New("unable to allowsCreate Pod for HumioCluster: the init service account secret does not exist") } return &podAttachments{ diff --git a/controllers/humiocluster_secrets.go b/controllers/humiocluster_secrets.go index 939f0c8d..53089949 100644 --- a/controllers/humiocluster_secrets.go +++ b/controllers/humiocluster_secrets.go @@ -13,7 +13,7 @@ const ( waitForSecretTimeoutSeconds = 30 ) -// waitForNewSecret can be used to wait for a new secret to be created after the create call is issued. It is important +// waitForNewSecret can be used to wait for a new secret to be created after the allowsCreate call is issued. It is important // that the previousSecretList contains the list of secrets prior to when the new secret was created func (r *HumioClusterReconciler) waitForNewSecret(ctx context.Context, hnp *HumioNodePool, previousSecretList []corev1.Secret, expectedSecretName string) error { // We must check only secrets that existed prior to the new secret being created diff --git a/controllers/humioexternalcluster_controller.go b/controllers/humioexternalcluster_controller.go index c27b5dec..4eb7e8a8 100644 --- a/controllers/humioexternalcluster_controller.go +++ b/controllers/humioexternalcluster_controller.go @@ -43,7 +43,7 @@ type HumioExternalClusterReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters/finalizers,verbs=update diff --git a/controllers/humioingesttoken_controller.go b/controllers/humioingesttoken_controller.go index f9bba373..eda19359 100644 --- a/controllers/humioingesttoken_controller.go +++ b/controllers/humioingesttoken_controller.go @@ -48,7 +48,7 @@ type HumioIngestTokenReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens/finalizers,verbs=update @@ -141,10 +141,10 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req curToken, err := r.HumioClient.GetIngestToken(cluster.Config(), req, hit) if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("ingest token doesn't exist. Now adding ingest token") - // create token + // allowsCreate token _, err := r.HumioClient.AddIngestToken(cluster.Config(), req, hit) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create ingest token") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate ingest token") } r.Log.Info("created ingest token") return reconcile.Result{Requeue: true}, nil @@ -167,10 +167,10 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req return reconcile.Result{}, fmt.Errorf("could not ensure token secret exists: %w", err) } - // TODO: handle updates to ingest token name and repositoryName. Right now we just create the new ingest token, + // TODO: handle updates to ingest token name and repositoryName. Right now we just allowsCreate the new ingest token, // and "leak/leave behind" the old token. // A solution could be to add an annotation that includes the "old name" so we can see if it was changed. - // A workaround for now is to delete the ingest token CR and create it again. + // A workaround for now is to delete the ingest token CR and allowsCreate it again. r.Log.Info("done reconciling, will requeue after 15 seconds") return reconcile.Result{RequeueAfter: time.Second * 15}, nil @@ -229,7 +229,7 @@ func (r *HumioIngestTokenReconciler) ensureTokenSecretExists(ctx context.Context if k8serrors.IsNotFound(err) { err = r.Create(ctx, desiredSecret) if err != nil { - return fmt.Errorf("unable to create ingest token secret for HumioIngestToken: %w", err) + return fmt.Errorf("unable to allowsCreate ingest token secret for HumioIngestToken: %w", err) } r.Log.Info("successfully created ingest token secret", "TokenSecretName", hit.Spec.TokenSecretName) humioIngestTokenPrometheusMetrics.Counters.ServiceAccountSecretsCreated.Inc() diff --git a/controllers/humioparser_controller.go b/controllers/humioparser_controller.go index cc257d5a..4267dbd2 100644 --- a/controllers/humioparser_controller.go +++ b/controllers/humioparser_controller.go @@ -47,7 +47,7 @@ type HumioParserReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers/finalizers,verbs=update @@ -140,10 +140,10 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) curParser, err := r.HumioClient.GetParser(cluster.Config(), req, hp) if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("parser doesn't exist. Now adding parser") - // create parser + // allowsCreate parser _, err := r.HumioClient.AddParser(cluster.Config(), req, hp) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create parser") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate parser") } r.Log.Info("created parser") return reconcile.Result{Requeue: true}, nil @@ -184,10 +184,10 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) } } - // TODO: handle updates to parser name and repositoryName. Right now we just create the new parser, + // TODO: handle updates to parser name and repositoryName. Right now we just allowsCreate the new parser, // and "leak/leave behind" the old parser. // A solution could be to add an annotation that includes the "old name" so we can see if it was changed. - // A workaround for now is to delete the parser CR and create it again. + // A workaround for now is to delete the parser CR and allowsCreate it again. r.Log.Info("done reconciling, will requeue after 15 seconds") return reconcile.Result{RequeueAfter: time.Second * 15}, nil diff --git a/controllers/humiorepository_controller.go b/controllers/humiorepository_controller.go index 72299cfb..972cb3da 100644 --- a/controllers/humiorepository_controller.go +++ b/controllers/humiorepository_controller.go @@ -45,7 +45,7 @@ type HumioRepositoryReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories/finalizers,verbs=update @@ -142,10 +142,10 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ curRepository, err := r.HumioClient.GetRepository(cluster.Config(), req, hr) if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("repository doesn't exist. Now adding repository") - // create repository + // allowsCreate repository _, err := r.HumioClient.AddRepository(cluster.Config(), req, hr) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create repository") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate repository") } r.Log.Info("created repository", "RepositoryName", hr.Spec.Name) return reconcile.Result{Requeue: true}, nil @@ -176,10 +176,10 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ } } - // TODO: handle updates to repositoryName. Right now we just create the new repository, + // TODO: handle updates to repositoryName. Right now we just allowsCreate the new repository, // and "leak/leave behind" the old repository. // A solution could be to add an annotation that includes the "old name" so we can see if it was changed. - // A workaround for now is to delete the repository CR and create it again. + // A workaround for now is to delete the repository CR and allowsCreate it again. r.Log.Info("done reconciling, will requeue after 15 seconds") return reconcile.Result{RequeueAfter: time.Second * 15}, nil diff --git a/controllers/humioview_controller.go b/controllers/humioview_controller.go index 898fbbec..e3dd17a7 100644 --- a/controllers/humioview_controller.go +++ b/controllers/humioview_controller.go @@ -45,7 +45,7 @@ type HumioViewReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioviews,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioviews,verbs=get;list;watch;allowsCreate;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioviews/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioviews/finalizers,verbs=update @@ -144,7 +144,7 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( r.Log.Info("View doesn't exist. Now adding view") _, err := r.HumioClient.AddView(cluster.Config(), req, hv) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create view") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate view") } r.Log.Info("created view", "ViewName", hv.Spec.Name) return reconcile.Result{Requeue: true}, nil From 14215715657cbedc669cc671b3c4b018d9ba6752 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 9 Oct 2023 16:20:10 -0700 Subject: [PATCH 17/54] more cleanup --- controllers/humiocluster_permission_tokens.go | 164 +----------------- 1 file changed, 1 insertion(+), 163 deletions(-) diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go index 9b1ee32a..656a4ffc 100644 --- a/controllers/humiocluster_permission_tokens.go +++ b/controllers/humiocluster_permission_tokens.go @@ -3,7 +3,6 @@ package controllers import ( "context" "fmt" - "os" "github.com/humio/humio-operator/pkg/helpers" @@ -21,94 +20,6 @@ import ( corev1 "k8s.io/api/core/v1" ) -const ( - // apiTokenMethodAnnotationName is used to signal what mechanism was used to obtain the API token - apiTokenMethodAnnotationName = "humio.com/api-token-method" // #nosec G101 - // apiTokenMethodFromAPI is used to indicate that the API token was obtained using an API call - apiTokenMethodFromAPI = "api" -) - -// getFileContent returns the content of a file as a string -func getFileContent(filePath string) string { - data, err := os.ReadFile(filePath) // #nosec G304 - if err != nil { - fmt.Printf("Got an error while trying to read file %s: %s\n", filePath, err) - return "" - } - return string(data) -} - -//// createNewAdminUser creates a new Humio admin user -//func (r *HumioClusterReconciler) createNewAdminUser(ctx context.Context, config *humioapi.Config, req reconcile.Request,, username string) error { -// isRoot := true -// return r.HumioClient.AddAdminUser(config, req) -// -//} - -// getApiTokenForUserID returns the API token for the given user ID -//func (r *HumioClusterReconciler) getApiTokenForUserID(config *humioapi.Config, req reconcile.Request, userID string) (string, string, error) { -// // Try using the API to rotate and get the API token -// r.HumioClient.RotateUserApiTokenAndGet(userID) -// if err == nil { -// // If API works, return the token -// fmt.Printf("Successfully rotated and extracted API token using the API.\n") -// return token, apiTokenMethodFromAPI, nil -// } -// -// return "", "", fmt.Errorf("could not rotate apiToken for userID %s, err: %w", userID, err) -//} - -//type user struct { -// Id string -// Username string -//} - -// listAllHumioUsersSingleOrg returns a list of all Humio users when running in single org mode with user ID and username -//func listAllHumioUsersSingleOrg(client *humio.Client) ([]user, error) { -// var q struct { -// Users []user `graphql:"users"` -// } -// err := client.Query(&q, nil) -// return q.Users, err -//} - -type OrganizationSearchResultEntry struct { - EntityId string `graphql:"entityId"` - SearchMatch string `graphql:"searchMatch"` - OrganizationName string `graphql:"organizationName"` -} - -type OrganizationSearchResultSet struct { - Results []OrganizationSearchResultEntry `graphql:"results"` -} - -// listAllHumioUsersMultiOrg returns a list of all Humio users when running in multi org mode with user ID and username -// TODO: move this to client api -//func listAllHumioUsersMultiOrg(username string, organization string, client *humio.Client) ([]OrganizationSearchResultEntry, error) { -// var q struct { -// OrganizationSearchResultSet `graphql:"searchOrganizations(searchFilter: $username, typeFilter: User, sortBy: Name, orderBy: ASC, limit: 1000000, skip: 0)"` -// } -// -// variables := map[string]interface{}{ -// "username": username, -// } -// -// err := client.Query(&q, variables) -// if err != nil { -// return []OrganizationSearchResultEntry{}, err -// } -// -// var allUserResultEntries []OrganizationSearchResultEntry -// for _, result := range q.OrganizationSearchResultSet.Results { -// //if result.OrganizationName == "RecoveryRootOrg" { -// if result.OrganizationName == organization { -// allUserResultEntries = append(allUserResultEntries, result) -// } -// } -// -// return allUserResultEntries, nil -//} - // extractExistingHumioAdminUserID finds the user ID of the Humio user for the admin account, and returns // empty string and no error if the user doesn't exist func (r *HumioClusterReconciler) extractExistingHumioAdminUserID(config *humioapi.Config, req reconcile.Request, organizationMode string, username string, organization string) (string, error) { @@ -262,43 +173,9 @@ func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, h return nil } -// labelsForHumio returns the set of common labels for Humio resources. -// NB: There is a copy of this function in pkg/kubernetes/kubernetes.go to work around helper depending on main project. -//func labelsForHumio(clusterName string) map[string]string { -// labels := map[string]string{ -// "app.kubernetes.io/instance": clusterName, -// "app.kubernetes.io/managed-by": "humio-operator", -// "app.kubernetes.io/name": "humio", -// } -// return labels -//} - -// fileExists returns true if the specified path exists and is not a directory -func fileExists(path string) bool { - fileInfo, err := os.Stat(path) - if err != nil { - return false - } - return !fileInfo.IsDir() -} - -//func newKubernetesClientset() *k8s.Clientset { -// config, err := rest.InClusterConfig() -// if err != nil { -// panic(err.Error()) -// } -// -// clientset, err := k8s.NewForConfig(config) -// if err != nil { -// panic(err.Error()) -// } -// return clientset -//} - func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, config *humioapi.Config, req reconcile.Request, hc *v1alpha1.HumioCluster, username string, organization string) error { - //adminSecretNameSuffix := "admin-token" + r.Log.Info("ensuring admin user") - // TODO: contstant? Run this in a separate function? organizationMode := "single" if EnvVarHasKey(hc.Spec.EnvironmentVariables, "ORGANIZATION_MODE") { organizationMode = EnvVarValue(hc.Spec.EnvironmentVariables, "ORGANIZATION_MODE") @@ -308,45 +185,6 @@ func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, conf organizationMode = EnvVarValue(pool.EnvironmentVariables, "ORGANIZATION_MODE") } } - - // kubernetesClient := r.Client - - //for { - // // Check required files exist before we continue - // if !fileExists(localAdminTokenFile) { - // fmt.Printf("Waiting on the Humio container to allowsCreate the files %s. Retrying in 5 seconds.\n", localAdminTokenFile) - // time.Sleep(5 * time.Second) - // continue - // } - // - // // Get local admin token and allowsCreate humio client with it - // localAdminToken := getFileContent(localAdminTokenFile) - // if localAdminToken == "" { - // fmt.Printf("Local admin token file is empty. This might be due to Humio not being fully started up yet. Retrying in 5 seconds.\n") - // time.Sleep(5 * time.Second) - // continue - // } - // - // nodeURL, err := url.Parse(humioNodeURL) - // if err != nil { - // fmt.Printf("Unable to parse URL %s: %s\n", humioNodeURL, err) - // time.Sleep(5 * time.Second) - // continue - // } - - //humioClient := r.HumioClient.GetHumioClient(cluster.Config(), req) - //r.HumioClient.ListAllHumioUsersSingleOrg(config, req) - - //err := r.validateAdminSecretContent(ctx, config, req, namespace, clusterName, adminSecretNameSuffix) - //if err == nil { - // fmt.Printf("Existing token is still valid, thus no changes required. Will confirm again in 30 seconds.\n") - // time.Sleep(30 * time.Second) - // continue - //} - - //fmt.Printf("Could not validate existing admin secret: %s\n", err) - r.Log.Info("ensuring admin user") - // Get user ID of admin account userID, err := r.createAndGetAdminAccountUserID(ctx, config, req, organizationMode, username, organization) if err != nil { From e9bf3daaedae00c98566e18940b4ab9308260daf Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 10 Oct 2023 08:11:02 -0700 Subject: [PATCH 18/54] more cleanup --- .../humioexternalcluster_controller.go | 2 +- controllers/suite/common.go | 65 +------------------ 2 files changed, 4 insertions(+), 63 deletions(-) diff --git a/controllers/humioexternalcluster_controller.go b/controllers/humioexternalcluster_controller.go index 4eb7e8a8..e4f85016 100644 --- a/controllers/humioexternalcluster_controller.go +++ b/controllers/humioexternalcluster_controller.go @@ -87,7 +87,7 @@ func (r *HumioExternalClusterReconciler) Reconcile(ctx context.Context, req ctrl err = r.HumioClient.TestAPIToken(cluster.Config(), req) if err != nil { - r.Log.Error(err, fmt.Sprintf("unable to test if the API token is works. client: %+v", cluster.Config())) + r.Log.Error(err, "unable to test if the API token is works") err = r.Client.Get(ctx, req.NamespacedName, hec) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "unable to get cluster state") diff --git a/controllers/suite/common.go b/controllers/suite/common.go index e68db369..0fe716d5 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -10,8 +10,6 @@ import ( "strings" "time" - ginkgotypes "github.com/onsi/ginkgo/v2/types" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" "github.com/humio/humio-operator/controllers" "github.com/humio/humio-operator/pkg/helpers" @@ -359,9 +357,9 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { // Simulate sidecar creating the secret which contains the admin token used to authenticate with humio secretData := map[string][]byte{"token": []byte("")} - authTokenSecretName := fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix) - UsingClusterBy(key.Name, "Simulating the auth token secret containing the API token") - desiredSecret := kubernetes.ConstructSecret(key.Name, key.Namespace, authTokenSecretName, secretData, nil) + adminTokenSecretName := fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix) + UsingClusterBy(key.Name, "Simulating the admin token secret containing the API token") + desiredSecret := kubernetes.ConstructSecret(key.Name, key.Namespace, adminTokenSecretName, secretData, nil) Expect(k8sClient.Create(ctx, desiredSecret)).To(Succeed()) UsingClusterBy(key.Name, "Simulating the creation of the HumioBootstrapToken resource") @@ -373,16 +371,6 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Spec: humiov1alpha1.HumioBootstrapTokenSpec{ ManagedClusterName: key.Name, }, - //Spec: humiov1alpha1.HumioBootstrapTokenSpec{ - // HashedTokenSecret: humiov1alpha1.HumioHashedTokenSecretSpec{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{ - // Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - // }, - // Key: "hashedToken", - // }, - // }, - //}, Status: humiov1alpha1.HumioBootstrapTokenStatus{ State: humiov1alpha1.HumioBootstrapTokenStateReady, TokenSecretKeyRef: humiov1alpha1.HumioTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ @@ -525,19 +513,6 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum }, testTimeout, TestInterval).Should(HaveKeyWithValue(revisionKey, "1")) } - //UsingClusterBy(key.Name, "Waiting for the bootstrap token controller to populate the secret containing the bootstrap token") - //Eventually(func() error { - // clusterPods, _ = kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster).GetCommonClusterLabels()) - // for idx := range clusterPods { - // UsingClusterBy(key.Name, fmt.Sprintf("Pod status %s status: %v", clusterPods[idx].Name, clusterPods[idx].Status)) - // } - // - // return k8sClient.Get(ctx, types.NamespacedName{ - // Namespace: key.Namespace, - // Name: fmt.Sprintf("%s-%s", key.Name, kubernetes.BootstrapTokenSecretNameSuffix), - // }, &corev1.Secret{}) - //}, testTimeout, TestInterval).Should(Succeed()) - UsingClusterBy(key.Name, "Waiting for the controller to populate the secret containing the admin token") Eventually(func() error { clusterPods, _ = kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster).GetCommonClusterLabels()) @@ -560,10 +535,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Expect(clusterConfig).ToNot(BeNil()) Expect(clusterConfig.Config()).ToNot(BeNil()) - //Expect(fmt.Sprintf("%+v", clusterConfig.Config())).To(Equal("")) - cluster, err := humioClient.GetClusters(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) - UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v, config: %v", cluster, err, clusterConfig.Config())) if err != nil { return []string{fmt.Sprintf("got err: %s", err)} } @@ -590,9 +562,6 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Expect(clusterConfig.Config()).ToNot(BeNil()) cluster, err := humioClient.GetClusters(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) - //UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v", cluster, err)) - UsingClusterBy(key.Name, fmt.Sprintf("Obtained the following cluster details: %#+v, err: %v, config: %v", cluster, err, clusterConfig.Config())) - if err != nil || len(cluster.Nodes) < 1 { return []string{} } @@ -664,34 +633,6 @@ func WaitForReconcileToSync(ctx context.Context, key types.NamespacedName, k8sCl }, testTimeout, TestInterval).Should(BeNumerically("==", beforeGeneration)) } -type stdoutErrLine struct { - // We reuse the same names as Ginkgo so when we print out the relevant log lines we have a common field and value to jump from the test result to the relevant log lines by simply searching for the ID shown in the result. - CapturedGinkgoWriterOutput, CapturedStdOutErr string - - // Line contains either the CapturedGinkgoWriterOutput or CapturedStdOutErr we get in the spec/suite report. - Line string - - // LineNumber represents the index of line in the provided slice of lines. This may help to understand what order things were output in case two lines mention the same timestamp. - LineNumber int - - // State includes information about if a given report passed or failed - State ginkgotypes.SpecState -} - -func PrintLinesWithRunID(runID string, lines []string, specState ginkgotypes.SpecState) { - for idx, line := range lines { - output := stdoutErrLine{ - CapturedGinkgoWriterOutput: runID, - CapturedStdOutErr: runID, - Line: line, - LineNumber: idx, - State: specState, - } - u, _ := json.Marshal(output) - fmt.Println(string(u)) - } -} - func useDockerCredentials() bool { return os.Getenv(dockerUsernameEnvVar) != "" && os.Getenv(dockerPasswordEnvVar) != "" && os.Getenv(dockerUsernameEnvVar) != "none" && os.Getenv(dockerPasswordEnvVar) != "none" From 009a9c1dddad97e7d02c2c195b644934a40284b4 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 10 Oct 2023 08:51:40 -0700 Subject: [PATCH 19/54] fix allowsCreate mistake --- config/rbac/role.yaml | 38 +++++------ controllers/humioaction_controller.go | 4 +- controllers/humioalert_controller.go | 4 +- controllers/humiobootstraptoken_controller.go | 14 ++-- controllers/humiobootstraptoken_defaults.go | 2 +- controllers/humiocluster_controller.go | 66 +++++++++---------- controllers/humiocluster_permission_tokens.go | 6 +- controllers/humiocluster_pod_status.go | 2 +- controllers/humiocluster_pods.go | 10 +-- controllers/humiocluster_secrets.go | 2 +- .../humioexternalcluster_controller.go | 2 +- controllers/humioingesttoken_controller.go | 12 ++-- controllers/humioparser_controller.go | 10 +-- controllers/humiorepository_controller.go | 10 +-- controllers/humioview_controller.go | 4 +- examples/humiobootstraptoken.yaml | 2 - 16 files changed, 93 insertions(+), 95 deletions(-) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 201b7010..a538a200 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -9,7 +9,7 @@ rules: resources: - configmaps verbs: - - allowsCreate + - create - delete - get - list @@ -21,7 +21,7 @@ rules: resources: - endpoints verbs: - - allowsCreate + - create - delete - get - list @@ -33,7 +33,7 @@ rules: resources: - events verbs: - - allowsCreate + - create - delete - get - list @@ -45,7 +45,7 @@ rules: resources: - persistentvolumeclaims verbs: - - allowsCreate + - create - delete - get - list @@ -57,7 +57,7 @@ rules: resources: - pods verbs: - - allowsCreate + - create - delete - get - list @@ -69,7 +69,7 @@ rules: resources: - secrets verbs: - - allowsCreate + - create - delete - get - list @@ -81,7 +81,7 @@ rules: resources: - serviceaccounts verbs: - - allowsCreate + - create - delete - get - list @@ -93,7 +93,7 @@ rules: resources: - services verbs: - - allowsCreate + - create - delete - get - list @@ -105,7 +105,7 @@ rules: resources: - services/finalizers verbs: - - allowsCreate + - create - delete - get - list @@ -117,7 +117,7 @@ rules: resources: - HumioBootstrapTokens verbs: - - allowsCreate + - create - delete - get - list @@ -169,7 +169,7 @@ rules: resources: - humioactions verbs: - - allowsCreate + - create - delete - get - list @@ -195,7 +195,7 @@ rules: resources: - humioalerts verbs: - - allowsCreate + - create - delete - get - list @@ -221,7 +221,7 @@ rules: resources: - humioclusters verbs: - - allowsCreate + - create - delete - get - list @@ -247,7 +247,7 @@ rules: resources: - humioexternalclusters verbs: - - allowsCreate + - create - delete - get - list @@ -299,7 +299,7 @@ rules: resources: - humioingesttokens verbs: - - allowsCreate + - create - delete - get - list @@ -325,7 +325,7 @@ rules: resources: - humioparsers verbs: - - allowsCreate + - create - delete - get - list @@ -351,7 +351,7 @@ rules: resources: - humiorepositories verbs: - - allowsCreate + - create - delete - get - list @@ -403,7 +403,7 @@ rules: resources: - humioviews verbs: - - allowsCreate + - create - delete - get - list @@ -429,7 +429,7 @@ rules: resources: - ingress verbs: - - allowsCreate + - create - delete - get - list diff --git a/controllers/humioaction_controller.go b/controllers/humioaction_controller.go index 7d43a0cc..796a6268 100644 --- a/controllers/humioaction_controller.go +++ b/controllers/humioaction_controller.go @@ -44,7 +44,7 @@ type HumioActionReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioactions,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioactions,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioactions/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioactions/finalizers,verbs=update @@ -158,7 +158,7 @@ func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, config r.Log.Info("Action doesn't exist. Now adding action") addedAction, err := r.HumioClient.AddAction(config, req, ha) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate action") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not create action") } r.Log.Info("Created action", "Action", ha.Spec.Name, "ID", addedAction.ID) return reconcile.Result{Requeue: true}, nil diff --git a/controllers/humioalert_controller.go b/controllers/humioalert_controller.go index 6199ebf6..1eded9bf 100644 --- a/controllers/humioalert_controller.go +++ b/controllers/humioalert_controller.go @@ -48,7 +48,7 @@ type HumioAlertReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioalerts/finalizers,verbs=update @@ -148,7 +148,7 @@ func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, config * r.Log.Info("Alert doesn't exist. Now adding alert") addedAlert, err := r.HumioClient.AddAlert(config, req, ha) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate alert") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not create alert") } r.Log.Info("Created alert", "Alert", ha.Spec.Name, "ID", addedAlert.ID) return reconcile.Result{Requeue: true}, nil diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 89e9886b..93393db3 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -62,7 +62,7 @@ type HumioBootstrapTokenSecretData struct { HashedToken string `json:"hashedToken"` } -//+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=HumioBootstrapTokens/finalizers,verbs=update @@ -150,7 +150,7 @@ func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []stri &clientcmd.ConfigOverrides{}, ) - // allowsCreate the Config object + // create the Config object cfg, err := configLoader.ClientConfig() if err != nil { return "", err @@ -161,7 +161,7 @@ func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []stri cfg.GroupVersion = &corev1.SchemeGroupVersion cfg.NegotiatedSerializer = scheme.Codecs.WithoutConversion() - // allowsCreate a RESTClient + // create a RESTClient rc, err := rest.RESTClientFor(cfg) if err != nil { return "", err @@ -221,7 +221,7 @@ func (r *HumioBootstrapTokenReconciler) createPod(ctx context.Context, hbt *humi } r.Log.Info("creating onetime pod") if err := r.Create(ctx, pod); err != nil { - return &corev1.Pod{}, r.logErrorAndReturn(err, "could not allowsCreate pod") + return &corev1.Pod{}, r.logErrorAndReturn(err, "could not create pod") } return pod, nil } @@ -284,9 +284,9 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.C if err := humioBootstrapTokenConfig.validate(); err != nil { return r.logErrorAndReturn(err, fmt.Sprintf("could not validate bootstrap config for %s", hbt.Name)) } - okayToCreate, err := humioBootstrapTokenConfig.allowsCreate() + okayToCreate, err := humioBootstrapTokenConfig.create() if err != nil { - return r.logErrorAndReturn(err, "cannot allowsCreate bootstrap token") + return r.logErrorAndReturn(err, "cannot create bootstrap token") } if okayToCreate { secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) @@ -295,7 +295,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.C } r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) if err := r.Create(ctx, secret); err != nil { - return r.logErrorAndReturn(err, "could not allowsCreate secret") + return r.logErrorAndReturn(err, "could not create secret") } } } diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index b9cff5ea..2b3cfbb2 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -32,7 +32,7 @@ func (b *HumioBootstrapTokenConfig) bootstrapTokenName() string { return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, BootstrapTokenSuffix) } -func (b *HumioBootstrapTokenConfig) allowsCreate() (bool, error) { +func (b *HumioBootstrapTokenConfig) create() (bool, error) { if err := b.validate(); err != nil { return false, err } diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index ad57d578..b0e1965a 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -61,19 +61,19 @@ const ( MaximumMinReadyRequeue = time.Second * 300 ) -//+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioclusters/finalizers,verbs=update -//+kubebuilder:rbac:groups=core,resources=pods,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=services,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=services/finalizers,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=endpoints,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=events,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=secrets,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=allowsCreate;delete;get;list;patch;update;watch -//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingress,verbs=allowsCreate;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=pods,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=services,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=services/finalizers,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=endpoints,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=events,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=secrets,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=create;delete;get;list;patch;update;watch +//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingress,verbs=create;delete;get;list;patch;update;watch func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { if r.Namespace != "" { @@ -470,7 +470,7 @@ func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Co } err = r.Create(ctx, hbt) if err != nil { - return r.logErrorAndReturn(err, "could not allowsCreate bootstrap token resource") + return r.logErrorAndReturn(err, "could not create bootstrap token resource") } return nil } @@ -516,7 +516,7 @@ func (r *HumioClusterReconciler) ensureExtraKafkaConfigsConfigMap(ctx context.Co } r.Log.Info(fmt.Sprintf("creating configMap: %s", configMap.Name)) if err = r.Create(ctx, configMap); err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate extra kafka configs configmap") + return r.logErrorAndReturn(err, "unable to create extra kafka configs configmap") } r.Log.Info(fmt.Sprintf("successfully created extra kafka configs configmap name %s", configMap.Name)) humioClusterPrometheusMetrics.Counters.ConfigMapsCreated.Inc() @@ -611,7 +611,7 @@ func (r *HumioClusterReconciler) ensureViewGroupPermissionsConfigMap(ctx context r.Log.Info(fmt.Sprintf("creating configMap: %s", configMap.Name)) if err = r.Create(ctx, configMap); err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate view group permissions configmap") + return r.logErrorAndReturn(err, "unable to create view group permissions configmap") } r.Log.Info(fmt.Sprintf("successfully created view group permissions configmap name %s", configMap.Name)) humioClusterPrometheusMetrics.Counters.ConfigMapsCreated.Inc() @@ -649,7 +649,7 @@ func (r *HumioClusterReconciler) ensureRolePermissionsConfigMap(ctx context.Cont r.Log.Info(fmt.Sprintf("creating configMap: %s", configMap.Name)) if err = r.Create(ctx, configMap); err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate role permissions configmap") + return r.logErrorAndReturn(err, "unable to create role permissions configmap") } r.Log.Info(fmt.Sprintf("successfully created role permissions configmap name %s", configMap.Name)) humioClusterPrometheusMetrics.Counters.ConfigMapsCreated.Inc() @@ -775,7 +775,7 @@ func (r *HumioClusterReconciler) ensureNginxIngress(ctx context.Context, hc *hum return r.logErrorAndReturn(err, "could not get hostnames for ingress resources") } - // Due to ingress-ingress relying on ingress object annotations to enable/disable/adjust certain features we allowsCreate multiple ingress objects. + // Due to ingress-ingress relying on ingress object annotations to enable/disable/adjust certain features we create multiple ingress objects. ingresses := []*networkingv1.Ingress{ ConstructGeneralIngress(hc, hostname), ConstructStreamingQueryIngress(hc, hostname), @@ -785,7 +785,7 @@ func (r *HumioClusterReconciler) ensureNginxIngress(ctx context.Context, hc *hum for _, desiredIngress := range ingresses { // After constructing ingress objects, the rule's host attribute should be set to that which is defined in // the humiocluster spec. If the rule host is not set, then it means the hostname or esHostname was not set in - // the spec, so we do not allowsCreate the ingress resource + // the spec, so we do not create the ingress resource var createIngress bool for _, rule := range desiredIngress.Spec.Rules { if rule.Host != "" { @@ -803,7 +803,7 @@ func (r *HumioClusterReconciler) ensureNginxIngress(ctx context.Context, hc *hum r.Log.Info(fmt.Sprintf("creating ingress: %s", desiredIngress.Name)) err = r.Create(ctx, desiredIngress) if err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate ingress") + return r.logErrorAndReturn(err, "unable to create ingress") } r.Log.Info(fmt.Sprintf("successfully created ingress with name %s", desiredIngress.Name)) humioClusterPrometheusMetrics.Counters.IngressesCreated.Inc() @@ -926,10 +926,10 @@ func (r *HumioClusterReconciler) ensureValidCAIssuer(ctx context.Context, hc *hu if err := controllerutil.SetControllerReference(hc, &caIssuer, r.Scheme()); err != nil { return r.logErrorAndReturn(err, "could not set controller reference") } - // should only allowsCreate it if it doesn't exist + // should only create it if it doesn't exist r.Log.Info(fmt.Sprintf("creating CA Issuer: %s", caIssuer.Name)) if err = r.Create(ctx, &caIssuer); err != nil { - return r.logErrorAndReturn(err, "could not allowsCreate CA Issuer") + return r.logErrorAndReturn(err, "could not create CA Issuer") } return nil } @@ -980,7 +980,7 @@ func (r *HumioClusterReconciler) ensureValidCASecret(ctx context.Context, hc *hu r.Log.Info(fmt.Sprintf("creating CA secret: %s", caSecret.Name)) err = r.Create(ctx, caSecret) if err != nil { - return r.logErrorAndReturn(err, "could not allowsCreate secret with CA") + return r.logErrorAndReturn(err, "could not create secret with CA") } return nil @@ -1007,7 +1007,7 @@ func (r *HumioClusterReconciler) ensureHumioClusterKeystoreSecret(ctx context.Co } r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) if err := r.Create(ctx, secret); err != nil { - return r.logErrorAndReturn(err, "could not allowsCreate secret") + return r.logErrorAndReturn(err, "could not create secret") } return nil } else { @@ -1040,7 +1040,7 @@ func (r *HumioClusterReconciler) ensureHumioClusterCACertBundle(ctx context.Cont } r.Log.Info(fmt.Sprintf("creating certificate: %s", cert.Name)) if err := r.Create(ctx, &cert); err != nil { - return r.logErrorAndReturn(err, "could not allowsCreate certificate") + return r.logErrorAndReturn(err, "could not create certificate") } return nil } @@ -1070,7 +1070,7 @@ func (r *HumioClusterReconciler) ensureHumioNodeCertificates(ctx context.Context } r.Log.Info(fmt.Sprintf("creating node certificate: %s", certificate.Name)) if err = r.Create(ctx, &certificate); err != nil { - return r.logErrorAndReturn(err, "could allowsCreate node certificate") + return r.logErrorAndReturn(err, "could create node certificate") } if err = r.waitForNewNodeCertificate(ctx, hc, hnp, existingNodeCertCount+1); err != nil { @@ -1091,7 +1091,7 @@ func (r *HumioClusterReconciler) ensureInitClusterRole(ctx context.Context, hnp r.Log.Info(fmt.Sprintf("creating cluster role: %s", clusterRole.Name)) err = r.Create(ctx, clusterRole) if err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate init cluster role") + return r.logErrorAndReturn(err, "unable to create init cluster role") } r.Log.Info(fmt.Sprintf("successfully created init cluster role %s", clusterRoleName)) humioClusterPrometheusMetrics.Counters.ClusterRolesCreated.Inc() @@ -1117,7 +1117,7 @@ func (r *HumioClusterReconciler) ensureInitClusterRoleBinding(ctx context.Contex r.Log.Info(fmt.Sprintf("creating cluster role: %s", clusterRole.Name)) err = r.Create(ctx, clusterRole) if err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate init cluster role binding") + return r.logErrorAndReturn(err, "unable to create init cluster role binding") } r.Log.Info(fmt.Sprintf("successfully created init cluster role binding %s", clusterRoleBindingName)) humioClusterPrometheusMetrics.Counters.ClusterRoleBindingsCreated.Inc() @@ -1164,7 +1164,7 @@ func (r *HumioClusterReconciler) ensureServiceAccountExists(ctx context.Context, r.Log.Info(fmt.Sprintf("creating service account: %s", serviceAccount.Name)) err = r.Create(ctx, serviceAccount) if err != nil { - return r.logErrorAndReturn(err, fmt.Sprintf("unable to allowsCreate service account %s", serviceAccount.Name)) + return r.logErrorAndReturn(err, fmt.Sprintf("unable to create service account %s", serviceAccount.Name)) } r.Log.Info(fmt.Sprintf("successfully created service account %s", serviceAccount.Name)) humioClusterPrometheusMetrics.Counters.ServiceAccountsCreated.Inc() @@ -1194,7 +1194,7 @@ func (r *HumioClusterReconciler) ensureServiceAccountSecretExists(ctx context.Co r.Log.Info(fmt.Sprintf("creating secret: %s", secret.Name)) err = r.Create(ctx, secret) if err != nil { - return r.logErrorAndReturn(err, fmt.Sprintf("unable to allowsCreate service account secret %s", secret.Name)) + return r.logErrorAndReturn(err, fmt.Sprintf("unable to create service account secret %s", secret.Name)) } // check that we can list the new secret // this is to avoid issues where the requeue is faster than kubernetes @@ -1437,7 +1437,7 @@ func (r *HumioClusterReconciler) ensureService(ctx context.Context, hc *humiov1a } r.Log.Info(fmt.Sprintf("creating service %s of type %s with Humio port %d and ES port %d", service.Name, service.Spec.Type, hnp.GetHumioServicePort(), hnp.GetHumioESServicePort())) if err = r.Create(ctx, service); err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate service for HumioCluster") + return r.logErrorAndReturn(err, "unable to create service for HumioCluster") } return nil } @@ -1462,7 +1462,7 @@ func (r *HumioClusterReconciler) ensureHeadlessServiceExists(ctx context.Context } err = r.Create(ctx, service) if err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate headless service for HumioCluster") + return r.logErrorAndReturn(err, "unable to create headless service for HumioCluster") } return nil } @@ -2092,7 +2092,7 @@ func (r *HumioClusterReconciler) ensurePodsExist(ctx context.Context, hc *humiov } pod, err := r.createPod(ctx, hc, hnp, attachments, expectedPodsList) if err != nil { - return reconcile.Result{RequeueAfter: time.Second * 5}, r.logErrorAndReturn(err, "unable to allowsCreate pod") + return reconcile.Result{RequeueAfter: time.Second * 5}, r.logErrorAndReturn(err, "unable to create pod") } expectedPodsList = append(expectedPodsList, *pod) humioClusterPrometheusMetrics.Counters.PodsCreated.Inc() @@ -2134,13 +2134,13 @@ func (r *HumioClusterReconciler) ensurePersistentVolumeClaimsExist(ctx context.C } r.Log.Info(fmt.Sprintf("creating pvc: %s", pvc.Name)) if err = r.Create(ctx, pvc); err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate pvc") + return r.logErrorAndReturn(err, "unable to create pvc") } r.Log.Info(fmt.Sprintf("successfully created pvc %s for HumioCluster %s", pvc.Name, hnp.GetNodePoolName())) humioClusterPrometheusMetrics.Counters.PvcsCreated.Inc() if err = r.waitForNewPvc(ctx, hnp, pvc); err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate pvc") + return r.logErrorAndReturn(err, "unable to create pvc") } return nil } diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go index 656a4ffc..f6625da3 100644 --- a/controllers/humiocluster_permission_tokens.go +++ b/controllers/humiocluster_permission_tokens.go @@ -69,7 +69,7 @@ func (r *HumioClusterReconciler) createAndGetAdminAccountUserID(ctx context.Cont return userID, nil } - // If we didn't find a user ID, allowsCreate a user, extract the user ID and return it + // If we didn't find a user ID, create a user, extract the user ID and return it user, err := r.HumioClient.AddUser(config, req, username, true) if err != nil { return "", err @@ -142,7 +142,7 @@ func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, h err := r.Client.Get(ctx, key, adminSecret) if err != nil { if k8serrors.IsNotFound(err) { - // If the secret doesn't exist, allowsCreate it + // If the secret doesn't exist, create it desiredSecret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: key.Name, @@ -155,7 +155,7 @@ func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, h Type: corev1.SecretTypeOpaque, } if err := r.Client.Create(ctx, &desiredSecret); err != nil { - return r.logErrorAndReturn(err, "unable to allowsCreate secret") + return r.logErrorAndReturn(err, "unable to create secret") } return nil } diff --git a/controllers/humiocluster_pod_status.go b/controllers/humiocluster_pod_status.go index b40b5c87..0f36b6d6 100644 --- a/controllers/humiocluster_pod_status.go +++ b/controllers/humiocluster_pod_status.go @@ -59,7 +59,7 @@ func (r *HumioClusterReconciler) getPodsStatus(ctx context.Context, hc *humiov1a // pods that were just deleted may still have a status of Ready, but we should not consider them ready if pod.DeletionTimestamp == nil { // If a pod is evicted, we don't want to wait for a new pod spec since the eviction could happen for a - // number of reasons. If we delete the pod then we will re-allowsCreate it on the next reconcile. Adding the pod + // number of reasons. If we delete the pod then we will re-create it on the next reconcile. Adding the pod // to the podsRequiringDeletion list will cause it to be deleted. if pod.Status.Phase == corev1.PodFailed && pod.Status.Reason == podConditionReasonEvicted { r.Log.Info(fmt.Sprintf("pod %s has errors, pod phase: %s, reason: %s", pod.Name, pod.Status.Phase, pod.Status.Reason)) diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index eeba7077..e7c02f4f 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -706,7 +706,7 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha return pod, nil } -// waitForNewPods can be used to wait for new pods to be created after the allowsCreate call is issued. It is important that +// waitForNewPods can be used to wait for new pods to be created after the create call is issued. It is important that // the previousPodList contains the list of pods prior to when the new pods were created func (r *HumioClusterReconciler) waitForNewPods(ctx context.Context, hnp *HumioNodePool, previousPodList []corev1.Pod, expectedPods []corev1.Pod) error { // We must check only pods that were running prior to the new pod being created, and we must only include pods that @@ -995,7 +995,7 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum envVarSourceData, err := r.getEnvVarSource(ctx, hnp) if err != nil { - return &podAttachments{}, fmt.Errorf("unable to allowsCreate Pod for HumioCluster: %w", err) + return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", err) } key := types.NamespacedName{ @@ -1005,11 +1005,11 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum hbt := &humiov1alpha1.HumioBootstrapToken{} err = r.Client.Get(ctx, key, hbt) if err != nil { - return &podAttachments{}, fmt.Errorf("unable to allowsCreate Pod for HumioCluster. could not find HumioBootstrapToken: %w", err) + return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster. could not find HumioBootstrapToken: %w", err) } if hbt.Status.HashedTokenSecretKeyRef.SecretKeyRef == nil { - return &podAttachments{}, fmt.Errorf("unable to allowsCreate Pod for HumioCluster: %w", fmt.Errorf("bootstraptoken %s does not contain a status for the hashed token secret reference", hnp.GetBootstrapTokenName())) + return &podAttachments{}, fmt.Errorf("unable to create Pod for HumioCluster: %w", fmt.Errorf("bootstraptoken %s does not contain a status for the hashed token secret reference", hnp.GetBootstrapTokenName())) } if hnp.InitContainerDisabled() { @@ -1027,7 +1027,7 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum return &podAttachments{}, fmt.Errorf("unable get init service account secret for HumioCluster: %w", err) } if initSASecretName == "" { - return &podAttachments{}, errors.New("unable to allowsCreate Pod for HumioCluster: the init service account secret does not exist") + return &podAttachments{}, errors.New("unable to create Pod for HumioCluster: the init service account secret does not exist") } return &podAttachments{ diff --git a/controllers/humiocluster_secrets.go b/controllers/humiocluster_secrets.go index 53089949..939f0c8d 100644 --- a/controllers/humiocluster_secrets.go +++ b/controllers/humiocluster_secrets.go @@ -13,7 +13,7 @@ const ( waitForSecretTimeoutSeconds = 30 ) -// waitForNewSecret can be used to wait for a new secret to be created after the allowsCreate call is issued. It is important +// waitForNewSecret can be used to wait for a new secret to be created after the create call is issued. It is important // that the previousSecretList contains the list of secrets prior to when the new secret was created func (r *HumioClusterReconciler) waitForNewSecret(ctx context.Context, hnp *HumioNodePool, previousSecretList []corev1.Secret, expectedSecretName string) error { // We must check only secrets that existed prior to the new secret being created diff --git a/controllers/humioexternalcluster_controller.go b/controllers/humioexternalcluster_controller.go index e4f85016..f7497bcd 100644 --- a/controllers/humioexternalcluster_controller.go +++ b/controllers/humioexternalcluster_controller.go @@ -43,7 +43,7 @@ type HumioExternalClusterReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioexternalclusters/finalizers,verbs=update diff --git a/controllers/humioingesttoken_controller.go b/controllers/humioingesttoken_controller.go index eda19359..f9bba373 100644 --- a/controllers/humioingesttoken_controller.go +++ b/controllers/humioingesttoken_controller.go @@ -48,7 +48,7 @@ type HumioIngestTokenReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioingesttokens/finalizers,verbs=update @@ -141,10 +141,10 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req curToken, err := r.HumioClient.GetIngestToken(cluster.Config(), req, hit) if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("ingest token doesn't exist. Now adding ingest token") - // allowsCreate token + // create token _, err := r.HumioClient.AddIngestToken(cluster.Config(), req, hit) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate ingest token") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not create ingest token") } r.Log.Info("created ingest token") return reconcile.Result{Requeue: true}, nil @@ -167,10 +167,10 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req return reconcile.Result{}, fmt.Errorf("could not ensure token secret exists: %w", err) } - // TODO: handle updates to ingest token name and repositoryName. Right now we just allowsCreate the new ingest token, + // TODO: handle updates to ingest token name and repositoryName. Right now we just create the new ingest token, // and "leak/leave behind" the old token. // A solution could be to add an annotation that includes the "old name" so we can see if it was changed. - // A workaround for now is to delete the ingest token CR and allowsCreate it again. + // A workaround for now is to delete the ingest token CR and create it again. r.Log.Info("done reconciling, will requeue after 15 seconds") return reconcile.Result{RequeueAfter: time.Second * 15}, nil @@ -229,7 +229,7 @@ func (r *HumioIngestTokenReconciler) ensureTokenSecretExists(ctx context.Context if k8serrors.IsNotFound(err) { err = r.Create(ctx, desiredSecret) if err != nil { - return fmt.Errorf("unable to allowsCreate ingest token secret for HumioIngestToken: %w", err) + return fmt.Errorf("unable to create ingest token secret for HumioIngestToken: %w", err) } r.Log.Info("successfully created ingest token secret", "TokenSecretName", hit.Spec.TokenSecretName) humioIngestTokenPrometheusMetrics.Counters.ServiceAccountSecretsCreated.Inc() diff --git a/controllers/humioparser_controller.go b/controllers/humioparser_controller.go index 4267dbd2..cc257d5a 100644 --- a/controllers/humioparser_controller.go +++ b/controllers/humioparser_controller.go @@ -47,7 +47,7 @@ type HumioParserReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioparsers/finalizers,verbs=update @@ -140,10 +140,10 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) curParser, err := r.HumioClient.GetParser(cluster.Config(), req, hp) if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("parser doesn't exist. Now adding parser") - // allowsCreate parser + // create parser _, err := r.HumioClient.AddParser(cluster.Config(), req, hp) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate parser") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not create parser") } r.Log.Info("created parser") return reconcile.Result{Requeue: true}, nil @@ -184,10 +184,10 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) } } - // TODO: handle updates to parser name and repositoryName. Right now we just allowsCreate the new parser, + // TODO: handle updates to parser name and repositoryName. Right now we just create the new parser, // and "leak/leave behind" the old parser. // A solution could be to add an annotation that includes the "old name" so we can see if it was changed. - // A workaround for now is to delete the parser CR and allowsCreate it again. + // A workaround for now is to delete the parser CR and create it again. r.Log.Info("done reconciling, will requeue after 15 seconds") return reconcile.Result{RequeueAfter: time.Second * 15}, nil diff --git a/controllers/humiorepository_controller.go b/controllers/humiorepository_controller.go index 972cb3da..72299cfb 100644 --- a/controllers/humiorepository_controller.go +++ b/controllers/humiorepository_controller.go @@ -45,7 +45,7 @@ type HumioRepositoryReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humiorepositories/finalizers,verbs=update @@ -142,10 +142,10 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ curRepository, err := r.HumioClient.GetRepository(cluster.Config(), req, hr) if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("repository doesn't exist. Now adding repository") - // allowsCreate repository + // create repository _, err := r.HumioClient.AddRepository(cluster.Config(), req, hr) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate repository") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not create repository") } r.Log.Info("created repository", "RepositoryName", hr.Spec.Name) return reconcile.Result{Requeue: true}, nil @@ -176,10 +176,10 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ } } - // TODO: handle updates to repositoryName. Right now we just allowsCreate the new repository, + // TODO: handle updates to repositoryName. Right now we just create the new repository, // and "leak/leave behind" the old repository. // A solution could be to add an annotation that includes the "old name" so we can see if it was changed. - // A workaround for now is to delete the repository CR and allowsCreate it again. + // A workaround for now is to delete the repository CR and create it again. r.Log.Info("done reconciling, will requeue after 15 seconds") return reconcile.Result{RequeueAfter: time.Second * 15}, nil diff --git a/controllers/humioview_controller.go b/controllers/humioview_controller.go index e3dd17a7..898fbbec 100644 --- a/controllers/humioview_controller.go +++ b/controllers/humioview_controller.go @@ -45,7 +45,7 @@ type HumioViewReconciler struct { Namespace string } -//+kubebuilder:rbac:groups=core.humio.com,resources=humioviews,verbs=get;list;watch;allowsCreate;update;patch;delete +//+kubebuilder:rbac:groups=core.humio.com,resources=humioviews,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core.humio.com,resources=humioviews/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core.humio.com,resources=humioviews/finalizers,verbs=update @@ -144,7 +144,7 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( r.Log.Info("View doesn't exist. Now adding view") _, err := r.HumioClient.AddView(cluster.Config(), req, hv) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not allowsCreate view") + return reconcile.Result{}, r.logErrorAndReturn(err, "could not create view") } r.Log.Info("created view", "ViewName", hv.Spec.Name) return reconcile.Result{Requeue: true}, nil diff --git a/examples/humiobootstraptoken.yaml b/examples/humiobootstraptoken.yaml index e7f02557..ef175b3d 100644 --- a/examples/humiobootstraptoken.yaml +++ b/examples/humiobootstraptoken.yaml @@ -5,12 +5,10 @@ metadata: spec: managedClusterName: example-humiocluster tokenSecret: - autoCreate: false secretKeyRef: name: example-bootstraptoken-token-secret key: secret hashedTokenSecret: - autoCreate: false secretKeyRef: name: example-bootstraptoken-token-secret key: hashedToken From a1e318afa45bc1d89582a4cb7fea80ebbafad02c Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 17 Nov 2023 14:52:53 -0800 Subject: [PATCH 20/54] refactor --- controllers/humiobootstraptoken_defaults.go | 9 +++++---- controllers/humiobootstraptoken_pods.go | 4 +--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index 2b3cfbb2..cf201cff 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -13,7 +13,8 @@ import ( ) const ( - BootstrapTokenSuffix = "bootstrap-token" + bootstrapTokenSuffix = "bootstrap-token" + bootstrapTokenPodNameSuffix = "bootstrap-token-onetime" ) type HumioBootstrapTokenConfig struct { @@ -29,7 +30,7 @@ func (b *HumioBootstrapTokenConfig) bootstrapTokenName() string { if b.BootstrapToken.Spec.TokenSecret.SecretKeyRef != nil { return b.BootstrapToken.Spec.TokenSecret.SecretKeyRef.Name } - return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, BootstrapTokenSuffix) + return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, bootstrapTokenSuffix) } func (b *HumioBootstrapTokenConfig) create() (bool, error) { @@ -100,8 +101,8 @@ func (b *HumioBootstrapTokenConfig) resources() corev1.ResourceRequirements { } } -func (b *HumioBootstrapTokenConfig) name() string { - return b.BootstrapToken.Name +func (b *HumioBootstrapTokenConfig) podName() string { + return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, bootstrapTokenPodNameSuffix) } func (b *HumioBootstrapTokenConfig) namespace() string { diff --git a/controllers/humiobootstraptoken_pods.go b/controllers/humiobootstraptoken_pods.go index de0d24fa..f963bbb8 100644 --- a/controllers/humiobootstraptoken_pods.go +++ b/controllers/humiobootstraptoken_pods.go @@ -1,8 +1,6 @@ package controllers import ( - "fmt" - "github.com/humio/humio-operator/pkg/helpers" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -12,7 +10,7 @@ func ConstructBootstrapPod(bootstrapConfig *HumioBootstrapTokenConfig) *corev1.P userID := int64(65534) return &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-bootstrap-token-onetime", bootstrapConfig.name()), + Name: bootstrapConfig.podName(), Namespace: bootstrapConfig.namespace(), }, Spec: corev1.PodSpec{ From 115889e837383e07631b8b85eae9c81a8584a7d6 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 17 Nov 2023 15:15:50 -0800 Subject: [PATCH 21/54] fix version --- .../crds/core.humio.com_humiobootstraptokens.yaml | 2 +- config/crd/bases/core.humio.com_humiobootstraptokens.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index 240a630a..2d8894f3 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -12,7 +12,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.20.0' + helm.sh/chart: 'humio-operator-0.20.1' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 240a630a..2d8894f3 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -12,7 +12,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.20.0' + helm.sh/chart: 'humio-operator-0.20.1' spec: group: core.humio.com names: From dfa9fdbbf80ccbad3f4f53c9109d71d83ba6dbea Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 17 Nov 2023 15:19:24 -0800 Subject: [PATCH 22/54] refactor --- ...a1_humiocluster_shared_serviceaccount.yaml | 1 - pkg/kubernetes/roles.go | 55 ------------------- 2 files changed, 56 deletions(-) delete mode 100644 pkg/kubernetes/roles.go diff --git a/config/samples/core_v1alpha1_humiocluster_shared_serviceaccount.yaml b/config/samples/core_v1alpha1_humiocluster_shared_serviceaccount.yaml index e1a4c49a..5eeddcbb 100644 --- a/config/samples/core_v1alpha1_humiocluster_shared_serviceaccount.yaml +++ b/config/samples/core_v1alpha1_humiocluster_shared_serviceaccount.yaml @@ -14,7 +14,6 @@ spec: image: "humio/humio-core:1.82.1" humioServiceAccountName: humio initServiceAccountName: humio - authServiceAccountName: humio podAnnotations: linkerd.io/inject: enabled config.linkerd.io/skip-outbound-ports: "2181" diff --git a/pkg/kubernetes/roles.go b/pkg/kubernetes/roles.go deleted file mode 100644 index 84522a24..00000000 --- a/pkg/kubernetes/roles.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2020 Humio https://humio.com - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package kubernetes - -import ( - "context" - - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// ConstructAuthRole returns the role used by the auth sidecar container to make an API token available for the -// humio-operator. This API token can be used to obtain insights into the health of the Humio cluster and make changes. -func ConstructAuthRole(roleName string, humioClusterNamespace string, labels map[string]string) *rbacv1.Role { - return &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: roleName, - Namespace: humioClusterNamespace, - Labels: labels, - }, - Rules: []rbacv1.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"secrets"}, - Verbs: []string{"get", "list", "watch", "create", "update", "delete"}, - }, - }, - } -} - -// GetRole returns the given role if it exists -func GetRole(ctx context.Context, c client.Client, roleName, roleNamespace string) (*rbacv1.Role, error) { - var existingRole rbacv1.Role - err := c.Get(ctx, types.NamespacedName{ - Name: roleName, - Namespace: roleNamespace, - }, &existingRole) - return &existingRole, err -} From e26572b4aa197af95b2b10b898a103a12ff2c3a8 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 17 Nov 2023 15:47:39 -0800 Subject: [PATCH 23/54] rename bootstrap token --- pkg/kubernetes/humio_bootstrap_tokens.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/kubernetes/humio_bootstrap_tokens.go b/pkg/kubernetes/humio_bootstrap_tokens.go index b04fb06b..764be88a 100644 --- a/pkg/kubernetes/humio_bootstrap_tokens.go +++ b/pkg/kubernetes/humio_bootstrap_tokens.go @@ -2,7 +2,6 @@ package kubernetes import ( "context" - "fmt" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -43,7 +42,7 @@ func LabelsForHumioBootstrapToken(clusterName string) map[string]string { func ConstructHumioBootstrapToken(humioClusterName string, humioClusterNamespace string) *humiov1alpha1.HumioBootstrapToken { return &humiov1alpha1.HumioBootstrapToken{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("%s-%s", humioClusterName, BootstrapTokenNameSuffix), + Name: humioClusterName, Namespace: humioClusterNamespace, Labels: LabelsForHumioBootstrapToken(humioClusterName), }, From 776ac2f97edb7fb2f32fa81cd955c20ae47dbf51 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 17 Nov 2023 16:08:33 -0800 Subject: [PATCH 24/54] rename bootstrap token --- controllers/humiocluster_pods.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index e7c02f4f..58de9b05 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -999,8 +999,8 @@ func (r *HumioClusterReconciler) newPodAttachments(ctx context.Context, hnp *Hum } key := types.NamespacedName{ + Name: hnp.GetClusterName(), Namespace: hnp.GetNamespace(), - Name: hnp.GetBootstrapTokenName(), } hbt := &humiov1alpha1.HumioBootstrapToken{} err = r.Client.Get(ctx, key, hbt) From d98db23ea4de1e3391cd35358a91886719110a47 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 29 Nov 2023 10:35:03 -0800 Subject: [PATCH 25/54] fix bootstrap token pod --- controllers/humiobootstraptoken_controller.go | 15 ++++++++------- controllers/humiobootstraptoken_defaults.go | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 93393db3..ce2c3627 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -331,13 +331,14 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont } var podRunning bool + var foundPod corev1.Pod for i := 0; i < waitForPodTimeoutSeconds; i++ { - latestPodList, err := kubernetes.ListPods(ctx, r, hbt.GetNamespace(), hbt.GetLabels()) - if err != nil { - return err - } - for _, pod := range latestPodList { - if pod.Status.Phase == corev1.PodRunning { + err := r.Get(ctx, types.NamespacedName{ + Namespace: pod.Namespace, + Name: pod.Name, + }, &foundPod) + if err == nil { + if foundPod.Status.Phase == corev1.PodRunning { podRunning = true break } @@ -350,7 +351,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont } r.Log.Info("execing onetime pod") - output, err := r.execCommand(pod, commandArgs) + output, err := r.execCommand(&foundPod, commandArgs) if err != nil { return r.logErrorAndReturn(err, "failed to exec pod") } diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index cf201cff..62edfb98 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -92,7 +92,7 @@ func (b *HumioBootstrapTokenConfig) resources() corev1.ResourceRequirements { return corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), - corev1.ResourceMemory: *resource.NewQuantity(50*1024*1024, resource.BinarySI), + corev1.ResourceMemory: *resource.NewQuantity(500*1024*1024, resource.BinarySI), }, Requests: corev1.ResourceList{ corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), From d05b7829ba539bd4e22ed9c5c246c11c8086fa2b Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 29 Nov 2023 11:12:10 -0800 Subject: [PATCH 26/54] fix tests --- controllers/suite/common.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/controllers/suite/common.go b/controllers/suite/common.go index 0fe716d5..8080601f 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -354,6 +354,12 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum } } + bootstrapToken := kubernetes.ConstructHumioBootstrapToken(key.Name, key.Namespace) + bootstrapTokenKey := types.NamespacedName{ + Namespace: bootstrapToken.Namespace, + Name: bootstrapToken.Name, + } + if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { // Simulate sidecar creating the secret which contains the admin token used to authenticate with humio secretData := map[string][]byte{"token": []byte("")} @@ -365,8 +371,8 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum UsingClusterBy(key.Name, "Simulating the creation of the HumioBootstrapToken resource") humioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{ ObjectMeta: metav1.ObjectMeta{ - Name: key.Name, - Namespace: key.Namespace, + Name: bootstrapTokenKey.Name, + Namespace: bootstrapTokenKey.Namespace, }, Spec: humiov1alpha1.HumioBootstrapTokenSpec{ ManagedClusterName: key.Name, @@ -404,7 +410,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum UsingClusterBy(key.Name, "Simulating HumioBootstrapToken Controller running and adding the secret and status") Eventually(func() error { var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken - Expect(k8sClient.Get(ctx, key, &updatedHumioBootstrapToken)).Should(Succeed()) + Expect(k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken)).Should(Succeed()) updatedHumioBootstrapToken.Status.State = humiov1alpha1.HumioBootstrapTokenStateReady updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ SecretKeyRef: &corev1.SecretKeySelector{ From 8b51ebdcf739cd34335f699c075a3cdfd3f8248b Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 29 Nov 2023 11:35:18 -0800 Subject: [PATCH 27/54] fix tests --- controllers/suite/common.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/controllers/suite/common.go b/controllers/suite/common.go index 8080601f..24743a04 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -410,7 +410,10 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum UsingClusterBy(key.Name, "Simulating HumioBootstrapToken Controller running and adding the secret and status") Eventually(func() error { var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken - Expect(k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken)).Should(Succeed()) + err := k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken) + if err != nil { + return err + } updatedHumioBootstrapToken.Status.State = humiov1alpha1.HumioBootstrapTokenStateReady updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ SecretKeyRef: &corev1.SecretKeySelector{ From d5b6873306ad2a3532e66fdfcba7c46374c6e406 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 29 Nov 2023 16:18:05 -0800 Subject: [PATCH 28/54] fix tests --- controllers/suite/common.go | 45 +++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/controllers/suite/common.go b/controllers/suite/common.go index 24743a04..52b1e83e 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -360,7 +360,13 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Name: bootstrapToken.Name, } - if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { + if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { + UsingClusterBy(key.Name, "Wait for HumioCluster Controller to create the HumioBootstrapToken") + Eventually(func() error { + var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken + return k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken) + }, testTimeout, TestInterval).Should(Succeed()) + } else { // Simulate sidecar creating the secret which contains the admin token used to authenticate with humio secretData := map[string][]byte{"token": []byte("")} adminTokenSecretName := fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix) @@ -369,30 +375,25 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Expect(k8sClient.Create(ctx, desiredSecret)).To(Succeed()) UsingClusterBy(key.Name, "Simulating the creation of the HumioBootstrapToken resource") - humioBootstrapToken := &humiov1alpha1.HumioBootstrapToken{ - ObjectMeta: metav1.ObjectMeta{ - Name: bootstrapTokenKey.Name, - Namespace: bootstrapTokenKey.Namespace, + humioBootstrapToken := kubernetes.ConstructHumioBootstrapToken(key.Name, key.Namespace) + humioBootstrapToken.Spec = humiov1alpha1.HumioBootstrapTokenSpec{ + ManagedClusterName: key.Name, + } + humioBootstrapToken.Status = humiov1alpha1.HumioBootstrapTokenStatus{ + State: humiov1alpha1.HumioBootstrapTokenStateReady, + TokenSecretKeyRef: humiov1alpha1.HumioTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", key.Name), + }, + Key: "secret", }, - Spec: humiov1alpha1.HumioBootstrapTokenSpec{ - ManagedClusterName: key.Name, }, - Status: humiov1alpha1.HumioBootstrapTokenStatus{ - State: humiov1alpha1.HumioBootstrapTokenStateReady, - TokenSecretKeyRef: humiov1alpha1.HumioTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - }, - Key: "secret", - }, + HashedTokenSecretKeyRef: humiov1alpha1.HumioHashedTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: fmt.Sprintf("%s-bootstrap-token", key.Name), }, - HashedTokenSecretKeyRef: humiov1alpha1.HumioHashedTokenSecretStatus{SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-bootstrap-token", key.Name), - }, - Key: "hashedToken", - }}, - }, + Key: "hashedToken", + }}, } UsingClusterBy(key.Name, "Creating HumioBootstrapToken resource") Expect(k8sClient.Create(ctx, humioBootstrapToken)).Should(Succeed()) From 89fa20dedf14d74323375d1a739edfccc1dfc5b3 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 29 Nov 2023 16:37:29 -0800 Subject: [PATCH 29/54] fix tests --- controllers/humiocluster_controller.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index b0e1965a..361945ac 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -456,11 +456,13 @@ func (r *HumioClusterReconciler) ensurePodRevisionAnnotation(ctx context.Context return hc.Status.State, nil } func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Context, hc *humiov1alpha1.HumioCluster) error { + r.Log.Info("ensuring humiobootstraptoken") hbtList, err := kubernetes.ListHumioBootstrapTokens(ctx, r.Client, hc.GetNamespace(), kubernetes.LabelsForHumioBootstrapToken(hc.GetName())) if err != nil { return r.logErrorAndReturn(err, "could not list HumioBootstrapToken") } if len(hbtList) > 0 { + r.Log.Info("humiobootstraptoken already exists") return nil } @@ -468,6 +470,7 @@ func (r *HumioClusterReconciler) ensureHumioClusterBootstrapToken(ctx context.Co if err := controllerutil.SetControllerReference(hc, hbt, r.Scheme()); err != nil { return r.logErrorAndReturn(err, "could not set controller reference") } + r.Log.Info(fmt.Sprintf("creating humiobootstraptoken %s", hbt.Name)) err = r.Create(ctx, hbt) if err != nil { return r.logErrorAndReturn(err, "could not create bootstrap token resource") From 5fbdecc6e41d158578c2d5d784ff402357443649 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 30 Nov 2023 08:04:46 -0800 Subject: [PATCH 30/54] fix tests --- controllers/suite/common.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/controllers/suite/common.go b/controllers/suite/common.go index 52b1e83e..0330c595 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -363,8 +363,14 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { UsingClusterBy(key.Name, "Wait for HumioCluster Controller to create the HumioBootstrapToken") Eventually(func() error { - var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken - return k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken) + hbtList, err := kubernetes.ListHumioBootstrapTokens(ctx, k8sClient, key.Namespace, kubernetes.LabelsForHumioBootstrapToken(key.Name)) + if err != nil { + return err + } + if len(hbtList) > 0 { + return nil + } + return fmt.Errorf("no humiobootstraptokens for cluster %s", key.Name) }, testTimeout, TestInterval).Should(Succeed()) } else { // Simulate sidecar creating the secret which contains the admin token used to authenticate with humio @@ -410,8 +416,16 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum UsingClusterBy(key.Name, "Simulating HumioBootstrapToken Controller running and adding the secret and status") Eventually(func() error { - var updatedHumioBootstrapToken humiov1alpha1.HumioBootstrapToken - err := k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken) + hbtList, err := kubernetes.ListHumioBootstrapTokens(ctx, k8sClient, key.Namespace, kubernetes.LabelsForHumioBootstrapToken(key.Name)) + if err != nil { + return err + } + if len(hbtList) == 0 { + return fmt.Errorf("no humiobootstraptokens for cluster %s", key.Name) + } + + updatedHumioBootstrapToken := hbtList[0] + err = k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken) if err != nil { return err } From 61b41726ba69f4d74606392982495d8cfd21441d Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 30 Nov 2023 08:19:40 -0800 Subject: [PATCH 31/54] fix tests --- controllers/suite/common.go | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/controllers/suite/common.go b/controllers/suite/common.go index 0330c595..be698e46 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -360,19 +360,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Name: bootstrapToken.Name, } - if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { - UsingClusterBy(key.Name, "Wait for HumioCluster Controller to create the HumioBootstrapToken") - Eventually(func() error { - hbtList, err := kubernetes.ListHumioBootstrapTokens(ctx, k8sClient, key.Namespace, kubernetes.LabelsForHumioBootstrapToken(key.Name)) - if err != nil { - return err - } - if len(hbtList) > 0 { - return nil - } - return fmt.Errorf("no humiobootstraptokens for cluster %s", key.Name) - }, testTimeout, TestInterval).Should(Succeed()) - } else { + if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { // Simulate sidecar creating the secret which contains the admin token used to authenticate with humio secretData := map[string][]byte{"token": []byte("")} adminTokenSecretName := fmt.Sprintf("%s-%s", key.Name, kubernetes.ServiceTokenSecretNameSuffix) @@ -423,12 +411,11 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum if len(hbtList) == 0 { return fmt.Errorf("no humiobootstraptokens for cluster %s", key.Name) } + if len(hbtList) > 0 { + return fmt.Errorf("too many humiobootstraptokens for cluster %s. found list : %+v", key.Name, hbtList) + } updatedHumioBootstrapToken := hbtList[0] - err = k8sClient.Get(ctx, bootstrapTokenKey, &updatedHumioBootstrapToken) - if err != nil { - return err - } updatedHumioBootstrapToken.Status.State = humiov1alpha1.HumioBootstrapTokenStateReady updatedHumioBootstrapToken.Status.TokenSecretKeyRef = humiov1alpha1.HumioTokenSecretStatus{ SecretKeyRef: &corev1.SecretKeySelector{ From d6c6daed72b1210c8e27999be2c0b9fb10fc080e Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 30 Nov 2023 09:11:37 -0800 Subject: [PATCH 32/54] fix tests --- controllers/suite/common.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/controllers/suite/common.go b/controllers/suite/common.go index be698e46..88514c20 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -354,12 +354,6 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum } } - bootstrapToken := kubernetes.ConstructHumioBootstrapToken(key.Name, key.Namespace) - bootstrapTokenKey := types.NamespacedName{ - Namespace: bootstrapToken.Namespace, - Name: bootstrapToken.Name, - } - if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { // Simulate sidecar creating the secret which contains the admin token used to authenticate with humio secretData := map[string][]byte{"token": []byte("")} @@ -411,7 +405,7 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum if len(hbtList) == 0 { return fmt.Errorf("no humiobootstraptokens for cluster %s", key.Name) } - if len(hbtList) > 0 { + if len(hbtList) > 1 { return fmt.Errorf("too many humiobootstraptokens for cluster %s. found list : %+v", key.Name, hbtList) } From ce8238898e4baa1e3392a34dfee659e03a965c22 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 30 Nov 2023 11:22:15 -0800 Subject: [PATCH 33/54] Switch tests to multiv2 --- controllers/suite/clusters/humiocluster_controller_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index 44c2b491..effac919 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -182,7 +182,7 @@ var _ = Describe("HumioCluster Controller", func() { }) toCreate.Spec.EnvironmentVariables = append(toCreate.Spec.EnvironmentVariables, corev1.EnvVar{ Name: "ORGANIZATION_MODE", - Value: "multi", + Value: "multiv2", }) suite.UsingClusterBy(key.Name, "Creating the cluster successfully") From 3b855d5662039c81c7e1ed93f3c6761e18969ffa Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 6 Dec 2023 13:54:45 -0800 Subject: [PATCH 34/54] more cleanup --- controllers/humiocluster_controller.go | 2 -- controllers/humiocluster_permission_tokens.go | 7 ++----- controllers/humiocluster_pods.go | 8 -------- examples/humiocluster-multi-nodepool-kind-local.yaml | 10 +++++----- 4 files changed, 7 insertions(+), 20 deletions(-) diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index 361945ac..cd85fdd4 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -1394,8 +1394,6 @@ func (r *HumioClusterReconciler) ensureLicense(ctx context.Context, hc *humiov1a // TODO: ensureLicense should be broken into multiple steps if err = r.ensurePermissionTokens(ctx, cluster.Config(), req, hc); err != nil { - // It's failing here due to: Got err trying to obtain user ID of admin user: Message: License does not allow adding users. Please contact Humio support - // I'm thinking the user may need to be added to the org, or if single org is enabled then we need to do something differently? return reconcile.Result{}, r.logErrorAndReturn(err, fmt.Sprintf("config: %+v", cluster.Config())) } diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go index f6625da3..c3165273 100644 --- a/controllers/humiocluster_permission_tokens.go +++ b/controllers/humiocluster_permission_tokens.go @@ -23,15 +23,12 @@ import ( // extractExistingHumioAdminUserID finds the user ID of the Humio user for the admin account, and returns // empty string and no error if the user doesn't exist func (r *HumioClusterReconciler) extractExistingHumioAdminUserID(config *humioapi.Config, req reconcile.Request, organizationMode string, username string, organization string) (string, error) { - if organizationMode == "multi" { - //var allUserResults []OrganizationSearchResultEntry - - allUserResults, err := r.HumioClient.ListAllHumioUsersMultiOrg(config, req, username, organization) // client.Users().List(username, organization, client) + if organizationMode == "multi" || organizationMode == "multiv2" { + allUserResults, err := r.HumioClient.ListAllHumioUsersMultiOrg(config, req, username, organization) if err != nil { // unable to list all users return "", err } - // TODO: cleanup/remove duplicate code for _, userResult := range allUserResults { if userResult.OrganizationName == "RecoveryRootOrg" { if userResult.SearchMatch == fmt.Sprintf(" | %s () ()", username) { diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index 58de9b05..f58c0c7a 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -657,14 +657,11 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha return &corev1.Pod{}, r.logErrorAndReturn(err, "unable to find pod name") } - //var bootstrapTokenHash string - //if attachments.bootstrapTokenSecretReference.secretReference != nil { bootstrapTokenHash, err := r.getDesiredBootstrapTokenHash(ctx, hc) if err != nil { return &corev1.Pod{}, r.logErrorAndReturn(err, "unable to find bootstrap token secret") } attachments.bootstrapTokenSecretReference.hash = bootstrapTokenHash - //} pod, err := ConstructPod(hnp, podNameAndCertHash.podName, attachments) if err != nil { @@ -689,11 +686,6 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha pod.Annotations[certHashAnnotation] = podNameAndCertHash.certificateHash } - //if attachments.bootstrapTokenSecretReference.secretReference != nil { - // pod.Annotations[bootstrapTokenHashAnnotation] = bootstrapTokenHash - // //pod.Annotations[bootstrapTokenHashAnnotation] = "asdf2" - //} - _, podRevision := hnp.GetHumioClusterNodePoolRevisionAnnotation() r.setPodRevision(pod, podRevision) diff --git a/examples/humiocluster-multi-nodepool-kind-local.yaml b/examples/humiocluster-multi-nodepool-kind-local.yaml index 61094fa3..dd4b2cee 100644 --- a/examples/humiocluster-multi-nodepool-kind-local.yaml +++ b/examples/humiocluster-multi-nodepool-kind-local.yaml @@ -30,16 +30,12 @@ spec: value: "humio-cp-zookeeper-0.humio-cp-zookeeper-headless.default:2181" - name: "KAFKA_SERVERS" value: "humio-cp-kafka-0.humio-cp-kafka-headless.default:9092" - # - name: "STATIC_USERS" - # value: "user:user" - - name: "AUTHENTICATION_METHOD" - value: "static" license: secretKeyRef: name: example-humiocluster-license key: data image: "humio/humio-core:1.82.1" - nodeCount: 0 + nodeCount: 1 tls: enabled: false targetReplicationFactor: 1 @@ -65,3 +61,7 @@ spec: value: "humio-cp-zookeeper-0.humio-cp-zookeeper-headless.default:2181" - name: "KAFKA_SERVERS" value: "humio-cp-kafka-0.humio-cp-kafka-headless.default:9092" + - name: "STATIC_USERS" + value: "user:user" + - name: "AUTHENTICATION_METHOD" + value: "static" \ No newline at end of file From d922363946c03262004d0116aa36fe36db12b7a8 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 6 Dec 2023 15:35:13 -0800 Subject: [PATCH 35/54] fix multi auth --- pkg/humio/client.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/humio/client.go b/pkg/humio/client.go index d4092f82..738ff504 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -937,7 +937,7 @@ func (h *ClientConfig) ListAllHumioUsersMultiOrg(config *humioapi.Config, req re } variables := map[string]interface{}{ - "username": username, + "username": graphql.String(username), } err := h.GetHumioClient(config, req).Query(&q, variables) @@ -947,7 +947,6 @@ func (h *ClientConfig) ListAllHumioUsersMultiOrg(config *humioapi.Config, req re var allUserResultEntries []OrganizationSearchResultEntry for _, result := range q.OrganizationSearchResultSet.Results { - //if result.OrganizationName == "RecoveryRootOrg" { if result.OrganizationName == organization { allUserResultEntries = append(allUserResultEntries, result) } @@ -957,7 +956,7 @@ func (h *ClientConfig) ListAllHumioUsersMultiOrg(config *humioapi.Config, req re } func (h *ClientConfig) ExtractExistingHumioAdminUserID(config *humioapi.Config, req reconcile.Request, organizationMode string, username string, organization string) (string, error) { - if organizationMode == "multi" { + if organizationMode == "multi" || organizationMode == "multiv2" { var allUserResults []OrganizationSearchResultEntry allUserResults, err := h.ListAllHumioUsersMultiOrg(config, req, username, organization) if err != nil { @@ -965,7 +964,7 @@ func (h *ClientConfig) ExtractExistingHumioAdminUserID(config *humioapi.Config, return "", err } for _, userResult := range allUserResults { - if userResult.OrganizationName == "RecoveryRootOrg" { + if userResult.OrganizationName == organization { if userResult.SearchMatch == fmt.Sprintf(" | %s () ()", username) { fmt.Printf("Found user ID using multi-organization query.\n") return userResult.EntityId, nil From d2e8c60ec7b64eaa3149bc05f4f64e131c9a8309 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 3 Jun 2024 15:45:26 -0700 Subject: [PATCH 36/54] cleanup --- api/v1alpha1/zz_generated.deepcopy.go | 1 + .../core.humio.com_humiobootstraptokens.yaml | 170 +++++++++--------- .../core.humio.com_humiobootstraptokens.yaml | 170 +++++++++--------- controllers/humiorepository_controller.go | 12 +- controllers/humioview_controller.go | 4 - 5 files changed, 182 insertions(+), 175 deletions(-) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 5afa3633..f7db95b6 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1,4 +1,5 @@ //go:build !ignore_autogenerated +// +build !ignore_autogenerated /* Copyright 2020 Humio https://humio.com diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index 2d8894f3..0e10015e 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -1,18 +1,16 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 name: humiobootstraptokens.core.humio.com labels: app: 'humio-operator' app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.20.1' + helm.sh/chart: 'humio-operator-0.21.0' spec: group: core.humio.com names: @@ -34,14 +32,19 @@ spec: use to bootstrap authentication properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -50,22 +53,19 @@ spec: Humio will use to bootstrap authentication properties: bootstrapImage: - description: Image can be set to override the image used to run when - generating a bootstrap token. This will default to the image that - is used by either the HumioCluster resource or the first NodePool - resource if ManagedClusterName is set on the HumioBootstrapTokenSpec + description: |- + Image can be set to override the image used to run when generating a bootstrap token. This will default to the image + that is used by either the HumioCluster resource or the first NodePool resource if ManagedClusterName is set on the HumioBootstrapTokenSpec type: string externalClusterName: - description: ExternalClusterName refers to the name of the HumioExternalCluster - which will use this bootstrap token for authentication This conflicts - with ManagedClusterName. + description: |- + ExternalClusterName refers to the name of the HumioExternalCluster which will use this bootstrap token for authentication + This conflicts with ManagedClusterName. type: string hashedTokenSecret: - description: HashedTokenSecret is the secret reference that contains - the hashed token to use for this HumioBootstrapToken. This is used - if one wants to use an existing hashed token for the BootstrapToken - rather than letting the operator create one by running a bootstrap - token onetime pod + description: |- + HashedTokenSecret is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is used if one wants to use an existing + hashed token for the BootstrapToken rather than letting the operator create one by running a bootstrap token onetime pod properties: secretKeyRef: description: SecretKeyRef is the secret key reference to a kubernetes @@ -76,8 +76,10 @@ spec: a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -86,22 +88,25 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object imagePullSecrets: - description: ImagePullSecrets defines the imagepullsecrets for the - bootstrap image onetime pod. These secrets are not created by the - operator. This will default to the imagePullSecrets that are used - by either the HumioCluster resource or the first NodePool resource - if ManagedClusterName is set on the HumioBootstrapTokenSpec + description: |- + ImagePullSecrets defines the imagepullsecrets for the bootstrap image onetime pod. These secrets are not created by the operator. This will default to the imagePullSecrets + that are used by either the HumioCluster resource or the first NodePool resource if ManagedClusterName is set on the HumioBootstrapTokenSpec items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array managedClusterName: description: ManagedClusterName refers to the name of the HumioCluster @@ -112,18 +117,24 @@ spec: onetime pod properties: claims: - description: "Claims lists the names of resources, defined in - spec.resourceClaims, that are used by this container. \n This - is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be set - for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry in pod.spec.resourceClaims - of the Pod where this field is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -139,8 +150,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -149,18 +161,17 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object tokenSecret: - description: TokenSecret is the secret reference that contains the - token to use for this HumioBootstrapToken. This is used if one wants - to use an existing token for the BootstrapToken rather than letting - the operator create one by running a bootstrap token onetime pod + description: |- + TokenSecret is the secret reference that contains the token to use for this HumioBootstrapToken. This is used if one wants to use an existing + token for the BootstrapToken rather than letting the operator create one by running a bootstrap token onetime pod properties: secretKeyRef: description: SecretKeyRef is the secret key reference to a kubernetes @@ -171,8 +182,10 @@ spec: a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -181,29 +194,30 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object type: object status: properties: hashedTokenSecretStatus: - description: HashedTokenSecret is the secret reference that contains - the hashed token to use for this HumioBootstrapToken. This is set - regardless of whether it's defined in the spec or automatically - created + description: |- + HashedTokenSecret is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is set regardless of whether it's defined + in the spec or automatically created properties: secretKeyRef: - description: SecretKeyRef is the secret reference that contains - the hashed token to use for this HumioBootstrapToken. This is - set regardless of whether it's defined in the spec or automatically - created + description: |- + SecretKeyRef is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is set regardless of whether it's defined + in the spec or automatically created properties: key: description: The key of the secret to select from. Must be a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -212,29 +226,30 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object state: description: State can be "NotReady" or "Ready" type: string tokenSecretStatus: - description: TokenSecretKeyRef contains the secret key reference to - a kubernetes secret containing the bootstrap token secret. This - is set regardless of whether it's defined in the spec or automatically - created + description: |- + TokenSecretKeyRef contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined + in the spec or automatically created properties: secretKeyRef: - description: SecretKeyRef contains the secret key reference to - a kubernetes secret containing the bootstrap token secret. This - is set regardless of whether it's defined in the spec or automatically - created + description: |- + SecretKeyRef contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined + in the spec or automatically created properties: key: description: The key of the secret to select from. Must be a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -243,6 +258,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object type: object type: object @@ -250,9 +266,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 2d8894f3..0e10015e 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -1,18 +1,16 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.2 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 name: humiobootstraptokens.core.humio.com labels: app: 'humio-operator' app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.20.1' + helm.sh/chart: 'humio-operator-0.21.0' spec: group: core.humio.com names: @@ -34,14 +32,19 @@ spec: use to bootstrap authentication properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -50,22 +53,19 @@ spec: Humio will use to bootstrap authentication properties: bootstrapImage: - description: Image can be set to override the image used to run when - generating a bootstrap token. This will default to the image that - is used by either the HumioCluster resource or the first NodePool - resource if ManagedClusterName is set on the HumioBootstrapTokenSpec + description: |- + Image can be set to override the image used to run when generating a bootstrap token. This will default to the image + that is used by either the HumioCluster resource or the first NodePool resource if ManagedClusterName is set on the HumioBootstrapTokenSpec type: string externalClusterName: - description: ExternalClusterName refers to the name of the HumioExternalCluster - which will use this bootstrap token for authentication This conflicts - with ManagedClusterName. + description: |- + ExternalClusterName refers to the name of the HumioExternalCluster which will use this bootstrap token for authentication + This conflicts with ManagedClusterName. type: string hashedTokenSecret: - description: HashedTokenSecret is the secret reference that contains - the hashed token to use for this HumioBootstrapToken. This is used - if one wants to use an existing hashed token for the BootstrapToken - rather than letting the operator create one by running a bootstrap - token onetime pod + description: |- + HashedTokenSecret is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is used if one wants to use an existing + hashed token for the BootstrapToken rather than letting the operator create one by running a bootstrap token onetime pod properties: secretKeyRef: description: SecretKeyRef is the secret key reference to a kubernetes @@ -76,8 +76,10 @@ spec: a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -86,22 +88,25 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object imagePullSecrets: - description: ImagePullSecrets defines the imagepullsecrets for the - bootstrap image onetime pod. These secrets are not created by the - operator. This will default to the imagePullSecrets that are used - by either the HumioCluster resource or the first NodePool resource - if ManagedClusterName is set on the HumioBootstrapTokenSpec + description: |- + ImagePullSecrets defines the imagepullsecrets for the bootstrap image onetime pod. These secrets are not created by the operator. This will default to the imagePullSecrets + that are used by either the HumioCluster resource or the first NodePool resource if ManagedClusterName is set on the HumioBootstrapTokenSpec items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array managedClusterName: description: ManagedClusterName refers to the name of the HumioCluster @@ -112,18 +117,24 @@ spec: onetime pod properties: claims: - description: "Claims lists the names of resources, defined in - spec.resourceClaims, that are used by this container. \n This - is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be set - for containers." + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. items: description: ResourceClaim references one entry in PodSpec.ResourceClaims. properties: name: - description: Name must match the name of one entry in pod.spec.resourceClaims - of the Pod where this field is used. It makes that resource - available inside a container. + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. type: string required: - name @@ -139,8 +150,9 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object requests: additionalProperties: @@ -149,18 +161,17 @@ spec: - type: string pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ type: object type: object tokenSecret: - description: TokenSecret is the secret reference that contains the - token to use for this HumioBootstrapToken. This is used if one wants - to use an existing token for the BootstrapToken rather than letting - the operator create one by running a bootstrap token onetime pod + description: |- + TokenSecret is the secret reference that contains the token to use for this HumioBootstrapToken. This is used if one wants to use an existing + token for the BootstrapToken rather than letting the operator create one by running a bootstrap token onetime pod properties: secretKeyRef: description: SecretKeyRef is the secret key reference to a kubernetes @@ -171,8 +182,10 @@ spec: a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -181,29 +194,30 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object type: object status: properties: hashedTokenSecretStatus: - description: HashedTokenSecret is the secret reference that contains - the hashed token to use for this HumioBootstrapToken. This is set - regardless of whether it's defined in the spec or automatically - created + description: |- + HashedTokenSecret is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is set regardless of whether it's defined + in the spec or automatically created properties: secretKeyRef: - description: SecretKeyRef is the secret reference that contains - the hashed token to use for this HumioBootstrapToken. This is - set regardless of whether it's defined in the spec or automatically - created + description: |- + SecretKeyRef is the secret reference that contains the hashed token to use for this HumioBootstrapToken. This is set regardless of whether it's defined + in the spec or automatically created properties: key: description: The key of the secret to select from. Must be a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -212,29 +226,30 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object state: description: State can be "NotReady" or "Ready" type: string tokenSecretStatus: - description: TokenSecretKeyRef contains the secret key reference to - a kubernetes secret containing the bootstrap token secret. This - is set regardless of whether it's defined in the spec or automatically - created + description: |- + TokenSecretKeyRef contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined + in the spec or automatically created properties: secretKeyRef: - description: SecretKeyRef contains the secret key reference to - a kubernetes secret containing the bootstrap token secret. This - is set regardless of whether it's defined in the spec or automatically - created + description: |- + SecretKeyRef contains the secret key reference to a kubernetes secret containing the bootstrap token secret. This is set regardless of whether it's defined + in the spec or automatically created properties: key: description: The key of the secret to select from. Must be a valid secret key. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key must be @@ -243,6 +258,7 @@ spec: required: - key type: object + x-kubernetes-map-type: atomic type: object type: object type: object @@ -250,9 +266,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/controllers/humiorepository_controller.go b/controllers/humiorepository_controller.go index 72299cfb..3d6829bb 100644 --- a/controllers/humiorepository_controller.go +++ b/controllers/humiorepository_controller.go @@ -73,13 +73,9 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ return reconcile.Result{}, err } -<<<<<<< HEAD r.Log = r.Log.WithValues("Request.UID", hr.UID) - cluster, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true) -======= cluster, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true, false) ->>>>>>> 2e2b16a (wip) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioRepositoryStateConfigError, hr) if setStateErr != nil { @@ -193,18 +189,12 @@ func (r *HumioRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *HumioRepositoryReconciler) finalize(ctx context.Context, config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { -<<<<<<< HEAD - _, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true) + _, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true, false) if err != nil { if k8serrors.IsNotFound(err) { return nil } return err -======= - _, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true, false) - if k8serrors.IsNotFound(err) { - return nil ->>>>>>> 2e2b16a (wip) } return r.HumioClient.DeleteRepository(config, req, hr) diff --git a/controllers/humioview_controller.go b/controllers/humioview_controller.go index 898fbbec..d5a70d29 100644 --- a/controllers/humioview_controller.go +++ b/controllers/humioview_controller.go @@ -73,13 +73,9 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return reconcile.Result{}, err } -<<<<<<< HEAD r.Log = r.Log.WithValues("Request.UID", hv.UID) - cluster, err := helpers.NewCluster(ctx, r, hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName, hv.Namespace, helpers.UseCertManager(), true) -======= cluster, err := helpers.NewCluster(ctx, r, hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName, hv.Namespace, helpers.UseCertManager(), true, false) ->>>>>>> 2e2b16a (wip) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioParserStateConfigError, hv) if setStateErr != nil { From 22037c479817940745130776aa3922f8156b1e85 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 3 Jun 2024 15:49:25 -0700 Subject: [PATCH 37/54] cleanup --- api/v1alpha1/zz_generated.deepcopy.go | 1 - 1 file changed, 1 deletion(-) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index f7db95b6..5afa3633 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* Copyright 2020 Humio https://humio.com From 3845754690f9d784a941dba0d420236a5a08239f Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 21 Jun 2024 14:23:20 -0700 Subject: [PATCH 38/54] cleanup --- controllers/humiobootstraptoken_defaults.go | 15 ++++++--------- controllers/humiocluster_permission_tokens.go | 4 ++-- controllers/humiocluster_pods.go | 14 -------------- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index 62edfb98..5b5bbdb4 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -5,11 +5,8 @@ import ( "k8s.io/apimachinery/pkg/api/resource" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" - - "github.com/humio/humio-operator/api/v1alpha1" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" + corev1 "k8s.io/api/core/v1" ) const ( @@ -18,11 +15,11 @@ const ( ) type HumioBootstrapTokenConfig struct { - BootstrapToken *v1alpha1.HumioBootstrapToken - ManagedHumioCluster *v1alpha1.HumioCluster + BootstrapToken *humiov1alpha1.HumioBootstrapToken + ManagedHumioCluster *humiov1alpha1.HumioCluster } -func NewHumioBootstrapTokenConfig(bootstrapToken *humiov1alpha1.HumioBootstrapToken, managedHumioCluster *v1alpha1.HumioCluster) HumioBootstrapTokenConfig { +func NewHumioBootstrapTokenConfig(bootstrapToken *humiov1alpha1.HumioBootstrapToken, managedHumioCluster *humiov1alpha1.HumioCluster) HumioBootstrapTokenConfig { return HumioBootstrapTokenConfig{BootstrapToken: bootstrapToken, ManagedHumioCluster: managedHumioCluster} } @@ -68,7 +65,7 @@ func (b *HumioBootstrapTokenConfig) image() string { return Image } -func (b *HumioBootstrapTokenConfig) imagePullSecrets() []v1.LocalObjectReference { +func (b *HumioBootstrapTokenConfig) imagePullSecrets() []corev1.LocalObjectReference { if len(b.BootstrapToken.Spec.ImagePullSecrets) > 0 { return b.BootstrapToken.Spec.ImagePullSecrets } @@ -82,7 +79,7 @@ func (b *HumioBootstrapTokenConfig) imagePullSecrets() []v1.LocalObjectReference } } } - return []v1.LocalObjectReference{} + return []corev1.LocalObjectReference{} } func (b *HumioBootstrapTokenConfig) resources() corev1.ResourceRequirements { diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go index c3165273..7ade00fe 100644 --- a/controllers/humiocluster_permission_tokens.go +++ b/controllers/humiocluster_permission_tokens.go @@ -124,7 +124,7 @@ func (r *HumioClusterReconciler) validateAdminSecretContent(ctx context.Context, // We could successfully get information about the cluster, so the token must be valid return nil } - return fmt.Errorf("Unable to validate if kubernetes secret %s holds a valid humio API token", adminSecretName) + return fmt.Errorf("unable to validate if kubernetes secret %s holds a valid humio API token", adminSecretName) } // ensureAdminSecretContent ensures the target Kubernetes secret contains the desired API token @@ -185,7 +185,7 @@ func (r *HumioClusterReconciler) createPermissionToken(ctx context.Context, conf // Get user ID of admin account userID, err := r.createAndGetAdminAccountUserID(ctx, config, req, organizationMode, username, organization) if err != nil { - return fmt.Errorf("Got err trying to obtain user ID of admin user: %s\n", err) + return fmt.Errorf("got err trying to obtain user ID of admin user: %s", err) } if err := r.validateAdminSecretContent(ctx, hc, req); err == nil { diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index f58c0c7a..d2b8c54b 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -906,20 +906,6 @@ func (r *HumioClusterReconciler) getDesiredBootstrapTokenHash(ctx context.Contex return "", r.logErrorAndReturn(err, fmt.Sprintf("could not find bootstrap token secret matching labels %+v", kubernetes.LabelsForHumioBootstrapToken(hc.GetName()))) } -func (r *HumioClusterReconciler) bootstrapTokenReady(ctx context.Context, hc *humiov1alpha1.HumioCluster) (bool, error) { - humioBootstrapTokens, err := kubernetes.ListHumioBootstrapTokens(ctx, r.Client, hc.GetNamespace(), kubernetes.LabelsForHumioBootstrapToken(hc.GetName())) - if err != nil { - return false, r.logErrorAndReturn(err, "failed to get bootstrap token") - } - - if len(humioBootstrapTokens) > 0 { - if humioBootstrapTokens[0].Status.State == humiov1alpha1.HumioBootstrapTokenStateReady { - return true, nil - } - } - return false, nil -} - // findHumioNodeNameAndCertHash looks up the name of a free node certificate to use and the hash of the certificate specification func findHumioNodeNameAndCertHash(ctx context.Context, c client.Client, hnp *HumioNodePool, newlyCreatedPods []corev1.Pod) (podNameAndCertificateHash, error) { // if we do not have TLS enabled, append a random suffix From 3d8637585237270e7ad752b5736d31e5ee7d038e Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 3 Jul 2024 11:37:28 -0700 Subject: [PATCH 39/54] deprecate AuthServiceAccountName --- api/v1alpha1/humiocluster_types.go | 3 +++ .../humio-operator/crds/core.humio.com_humioclusters.yaml | 8 ++++++++ config/crd/bases/core.humio.com_humioclusters.yaml | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/api/v1alpha1/humiocluster_types.go b/api/v1alpha1/humiocluster_types.go index 7c71b1fc..1fbdaabd 100644 --- a/api/v1alpha1/humiocluster_types.go +++ b/api/v1alpha1/humiocluster_types.go @@ -118,6 +118,9 @@ type HumioNodeSpec struct { // DataVolumeSource is the volume that is mounted on the humio pods. This conflicts with DataVolumePersistentVolumeClaimSpecTemplate. DataVolumeSource corev1.VolumeSource `json:"dataVolumeSource,omitempty"` + // *Deprecated: AuthServiceAccountName is no longer used as the auth sidecar container has been removed.* + AuthServiceAccountName string `json:"authServiceAccountName,omitempty"` + // DisableInitContainer is used to disable the init container completely which collects the availability zone from the Kubernetes worker node. // This is not recommended, unless you are using auto rebalancing partitions and are running in a single availability zone. DisableInitContainer bool `json:"disableInitContainer,omitempty"` diff --git a/charts/humio-operator/crds/core.humio.com_humioclusters.yaml b/charts/humio-operator/crds/core.humio.com_humioclusters.yaml index 4c4bbe8a..7b4a9316 100644 --- a/charts/humio-operator/crds/core.humio.com_humioclusters.yaml +++ b/charts/humio-operator/crds/core.humio.com_humioclusters.yaml @@ -945,6 +945,10 @@ spec: type: array type: object type: object + authServiceAccountName: + description: '*Deprecated: AuthServiceAccountName is no longer used + as the auth sidecar container has been removed.*' + type: string autoRebalancePartitions: description: |- AutoRebalancePartitions will enable auto-rebalancing of both digest and storage partitions assigned to humio cluster nodes. @@ -6634,6 +6638,10 @@ spec: type: array type: object type: object + authServiceAccountName: + description: '*Deprecated: AuthServiceAccountName is no + longer used as the auth sidecar container has been removed.*' + type: string containerLivenessProbe: description: |- ContainerLivenessProbe is the liveness probe applied to the Humio container diff --git a/config/crd/bases/core.humio.com_humioclusters.yaml b/config/crd/bases/core.humio.com_humioclusters.yaml index 479b88e2..072eae1c 100644 --- a/config/crd/bases/core.humio.com_humioclusters.yaml +++ b/config/crd/bases/core.humio.com_humioclusters.yaml @@ -939,6 +939,10 @@ spec: type: array type: object type: object + authServiceAccountName: + description: '*Deprecated: AuthServiceAccountName is no longer used + as the auth sidecar container has been removed.*' + type: string autoRebalancePartitions: description: |- AutoRebalancePartitions will enable auto-rebalancing of both digest and storage partitions assigned to humio cluster nodes. @@ -6628,6 +6632,10 @@ spec: type: array type: object type: object + authServiceAccountName: + description: '*Deprecated: AuthServiceAccountName is no + longer used as the auth sidecar container has been removed.*' + type: string containerLivenessProbe: description: |- ContainerLivenessProbe is the liveness probe applied to the Humio container From 6bba1ba2002606bd0b7d82176ed9c7899e3d88d4 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Wed, 3 Jul 2024 13:39:46 -0700 Subject: [PATCH 40/54] update crds --- .../crds/core.humio.com_humiobootstraptokens.yaml | 2 +- config/crd/bases/core.humio.com_humiobootstraptokens.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index 0e10015e..e064ef4b 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -10,7 +10,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.21.0' + helm.sh/chart: 'humio-operator-0.22.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 0e10015e..e064ef4b 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -10,7 +10,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.21.0' + helm.sh/chart: 'humio-operator-0.22.0' spec: group: core.humio.com names: From 28be699e2fc0def341ce45e41d06c4ba3e59a9f2 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 9 Jul 2024 09:55:48 -0700 Subject: [PATCH 41/54] update --- controllers/suite/clusters/humiocluster_controller_test.go | 1 - go.mod | 6 ++++++ go.sum | 7 +++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index effac919..e67b58dd 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -1291,7 +1291,6 @@ var _ = Describe("HumioCluster Controller", func() { defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Validating pod bootstrap token annotation hash") - //var bootstrapTokenHash string Eventually(func() string { clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) _ = suite.MarkPodsAsRunning(ctx, k8sClient, clusterPods, key.Name) diff --git a/go.mod b/go.mod index 83e3d1a4..623a4f89 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,15 @@ require ( github.com/go-logr/logr v1.4.2 github.com/go-logr/zapr v1.3.0 github.com/google/go-cmp v0.6.0 +<<<<<<< HEAD github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce github.com/onsi/ginkgo/v2 v2.20.0 github.com/onsi/gomega v1.34.1 +======= + github.com/humio/cli v0.35.0 + github.com/onsi/ginkgo/v2 v2.17.1 + github.com/onsi/gomega v1.32.0 +>>>>>>> 6a2e02f (update) github.com/prometheus/client_golang v1.19.0 go.uber.org/zap v1.27.0 k8s.io/api v0.29.5 diff --git a/go.sum b/go.sum index e545337a..717690fc 100644 --- a/go.sum +++ b/go.sum @@ -54,8 +54,11 @@ github.com/google/pprof v0.0.0-20240415144954-be81aee2d733 h1:nHRIUuWr4qaFmeHwGB github.com/google/pprof v0.0.0-20240415144954-be81aee2d733/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/humio/cli v0.35.1 h1:CwfGI5K79qHzEK51BCdbYUXthVPsUDY+3w1b0tO11S4= -github.com/humio/cli v0.35.1/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/humio/cli v0.35.0 h1:3OpfGp3FXu8obkjs7edvKdNCnPzxuboUxDMbuYzdAwc= +github.com/humio/cli v0.35.0/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= From 2298899a2f6e650cb1b20425043f3cb7a7a27aaf Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 5 Aug 2024 09:33:44 -0700 Subject: [PATCH 42/54] rebase cleanup --- .../crds/core.humio.com_humiobootstraptokens.yaml | 2 +- config/crd/bases/core.humio.com_humiobootstraptokens.yaml | 2 +- main.go | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index e064ef4b..9c19ec1b 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -10,7 +10,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.22.0' + helm.sh/chart: 'humio-operator-0.23.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index e064ef4b..9c19ec1b 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -10,7 +10,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.22.0' + helm.sh/chart: 'humio-operator-0.23.0' spec: group: core.humio.com names: diff --git a/main.go b/main.go index e33acf52..f309e0f4 100644 --- a/main.go +++ b/main.go @@ -184,6 +184,7 @@ func main() { BaseLogger: log, }).SetupWithManager(mgr); err != nil { ctrl.Log.Error(err, "unable to create controller", "controller", "HumioFilterAlert") + } if err = (&controllers.HumioBootstrapTokenReconciler{ Client: mgr.GetClient(), BaseLogger: log, From 667607a0b8f965aedf868323310c65ee42213f99 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 5 Aug 2024 09:36:10 -0700 Subject: [PATCH 43/54] rebase cleanup --- api/v1alpha1/zz_generated.deepcopy.go | 36 ++++++++++++---------- controllers/humiofilteralert_controller.go | 2 +- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 5afa3633..e48dd9ab 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -853,7 +853,6 @@ func (in *HumioExternalClusterStatus) DeepCopy() *HumioExternalClusterStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -<<<<<<< HEAD func (in *HumioFilterAlert) DeepCopyInto(out *HumioFilterAlert) { *out = *in out.TypeMeta = in.TypeMeta @@ -933,7 +932,26 @@ func (in *HumioFilterAlertSpec) DeepCopy() *HumioFilterAlertSpec { return nil } out := new(HumioFilterAlertSpec) -======= + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioFilterAlertStatus) DeepCopyInto(out *HumioFilterAlertStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioFilterAlertStatus. +func (in *HumioFilterAlertStatus) DeepCopy() *HumioFilterAlertStatus { + if in == nil { + return nil + } + out := new(HumioFilterAlertStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioHashedTokenSecretSpec) DeepCopyInto(out *HumioHashedTokenSecretSpec) { *out = *in if in.SecretKeyRef != nil { @@ -949,24 +967,11 @@ func (in *HumioHashedTokenSecretSpec) DeepCopy() *HumioHashedTokenSecretSpec { return nil } out := new(HumioHashedTokenSecretSpec) ->>>>>>> d88f334 (wip) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -<<<<<<< HEAD -func (in *HumioFilterAlertStatus) DeepCopyInto(out *HumioFilterAlertStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioFilterAlertStatus. -func (in *HumioFilterAlertStatus) DeepCopy() *HumioFilterAlertStatus { - if in == nil { - return nil - } - out := new(HumioFilterAlertStatus) -======= func (in *HumioHashedTokenSecretStatus) DeepCopyInto(out *HumioHashedTokenSecretStatus) { *out = *in if in.SecretKeyRef != nil { @@ -982,7 +987,6 @@ func (in *HumioHashedTokenSecretStatus) DeepCopy() *HumioHashedTokenSecretStatus return nil } out := new(HumioHashedTokenSecretStatus) ->>>>>>> d88f334 (wip) in.DeepCopyInto(out) return out } diff --git a/controllers/humiofilteralert_controller.go b/controllers/humiofilteralert_controller.go index d620b438..4b202d00 100644 --- a/controllers/humiofilteralert_controller.go +++ b/controllers/humiofilteralert_controller.go @@ -77,7 +77,7 @@ func (r *HumioFilterAlertReconciler) Reconcile(ctx context.Context, req ctrl.Req r.Log = r.Log.WithValues("Request.UID", hfa.UID) - cluster, err := helpers.NewCluster(ctx, r, hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName, hfa.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName, hfa.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioFilterAlertStateConfigError, hfa) if setStateErr != nil { From 244cd16cec76ecc98bad7d951188cc942b29240f Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Mon, 5 Aug 2024 13:43:46 -0700 Subject: [PATCH 44/54] rebase cleanup --- go.mod | 31 ++++++++++++------------------- go.sum | 4 ++-- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 623a4f89..1ee19245 100644 --- a/go.mod +++ b/go.mod @@ -7,18 +7,12 @@ require ( github.com/cert-manager/cert-manager v1.12.12 github.com/cli/shurcooL-graphql v0.0.4 github.com/go-jose/go-jose/v4 v4.0.1 - github.com/go-logr/logr v1.4.2 + github.com/go-logr/logr v1.4.1 github.com/go-logr/zapr v1.3.0 github.com/google/go-cmp v0.6.0 -<<<<<<< HEAD - github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce - github.com/onsi/ginkgo/v2 v2.20.0 - github.com/onsi/gomega v1.34.1 -======= - github.com/humio/cli v0.35.0 + github.com/humio/cli v0.36.0 github.com/onsi/ginkgo/v2 v2.17.1 github.com/onsi/gomega v1.32.0 ->>>>>>> 6a2e02f (update) github.com/prometheus/client_golang v1.19.0 go.uber.org/zap v1.27.0 k8s.io/api v0.29.5 @@ -38,13 +32,13 @@ require ( github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/pprof v0.0.0-20240415144954-be81aee2d733 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/imdario/mergo v0.3.16 // indirect @@ -62,18 +56,17 @@ require ( github.com/prometheus/procfs v0.13.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 717690fc..44bb7d03 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/humio/cli v0.35.0 h1:3OpfGp3FXu8obkjs7edvKdNCnPzxuboUxDMbuYzdAwc= -github.com/humio/cli v0.35.0/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= +github.com/humio/cli v0.36.0 h1:KAF4natLsnYNp2zyS1xCjDd6TB/pUz0wGootorBjjbA= +github.com/humio/cli v0.36.0/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= From a9d3160f35c64d32e89301d6561998194b9e15a8 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 3 Sep 2024 13:36:29 -0700 Subject: [PATCH 45/54] fix up manifests --- .../crds/core.humio.com_humiobootstraptokens.yaml | 2 +- config/crd/bases/core.humio.com_humioactions.yaml | 6 ++++++ config/crd/bases/core.humio.com_humioaggregatealerts.yaml | 6 ++++++ config/crd/bases/core.humio.com_humioalerts.yaml | 6 ++++++ config/crd/bases/core.humio.com_humiobootstraptokens.yaml | 2 +- config/crd/bases/core.humio.com_humioclusters.yaml | 6 ++++++ config/crd/bases/core.humio.com_humioexternalclusters.yaml | 6 ++++++ config/crd/bases/core.humio.com_humiofilteralerts.yaml | 6 ++++++ config/crd/bases/core.humio.com_humioingesttokens.yaml | 6 ++++++ config/crd/bases/core.humio.com_humioparsers.yaml | 6 ++++++ config/crd/bases/core.humio.com_humiorepositories.yaml | 6 ++++++ config/crd/bases/core.humio.com_humioscheduledsearches.yaml | 6 ++++++ config/crd/bases/core.humio.com_humioviews.yaml | 6 ++++++ 13 files changed, 68 insertions(+), 2 deletions(-) diff --git a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml index 9c19ec1b..63fff4a2 100644 --- a/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiobootstraptokens.yaml @@ -10,7 +10,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.23.0' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioactions.yaml b/config/crd/bases/core.humio.com_humioactions.yaml index 8b7b1fda..275ad98a 100644 --- a/config/crd/bases/core.humio.com_humioactions.yaml +++ b/config/crd/bases/core.humio.com_humioactions.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioactions.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioaggregatealerts.yaml b/config/crd/bases/core.humio.com_humioaggregatealerts.yaml index 2747e8c4..7fd4369f 100644 --- a/config/crd/bases/core.humio.com_humioaggregatealerts.yaml +++ b/config/crd/bases/core.humio.com_humioaggregatealerts.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioaggregatealerts.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioalerts.yaml b/config/crd/bases/core.humio.com_humioalerts.yaml index e2545259..2dbc7e8e 100644 --- a/config/crd/bases/core.humio.com_humioalerts.yaml +++ b/config/crd/bases/core.humio.com_humioalerts.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioalerts.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml index 9c19ec1b..63fff4a2 100644 --- a/config/crd/bases/core.humio.com_humiobootstraptokens.yaml +++ b/config/crd/bases/core.humio.com_humiobootstraptokens.yaml @@ -10,7 +10,7 @@ metadata: app.kubernetes.io/name: 'humio-operator' app.kubernetes.io/instance: 'humio-operator' app.kubernetes.io/managed-by: 'Helm' - helm.sh/chart: 'humio-operator-0.23.0' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioclusters.yaml b/config/crd/bases/core.humio.com_humioclusters.yaml index 072eae1c..7b4a9316 100644 --- a/config/crd/bases/core.humio.com_humioclusters.yaml +++ b/config/crd/bases/core.humio.com_humioclusters.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioclusters.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioexternalclusters.yaml b/config/crd/bases/core.humio.com_humioexternalclusters.yaml index 7d09a980..b60263f9 100644 --- a/config/crd/bases/core.humio.com_humioexternalclusters.yaml +++ b/config/crd/bases/core.humio.com_humioexternalclusters.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioexternalclusters.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiofilteralerts.yaml b/config/crd/bases/core.humio.com_humiofilteralerts.yaml index 48c2d478..1a5107b9 100644 --- a/config/crd/bases/core.humio.com_humiofilteralerts.yaml +++ b/config/crd/bases/core.humio.com_humiofilteralerts.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humiofilteralerts.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioingesttokens.yaml b/config/crd/bases/core.humio.com_humioingesttokens.yaml index dc9ac5f9..4632eda0 100644 --- a/config/crd/bases/core.humio.com_humioingesttokens.yaml +++ b/config/crd/bases/core.humio.com_humioingesttokens.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioingesttokens.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioparsers.yaml b/config/crd/bases/core.humio.com_humioparsers.yaml index b4f7ad31..acf7ba2f 100644 --- a/config/crd/bases/core.humio.com_humioparsers.yaml +++ b/config/crd/bases/core.humio.com_humioparsers.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioparsers.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humiorepositories.yaml b/config/crd/bases/core.humio.com_humiorepositories.yaml index c6fc6552..08244fb4 100644 --- a/config/crd/bases/core.humio.com_humiorepositories.yaml +++ b/config/crd/bases/core.humio.com_humiorepositories.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humiorepositories.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioscheduledsearches.yaml b/config/crd/bases/core.humio.com_humioscheduledsearches.yaml index 15dcec30..5cbec6f9 100644 --- a/config/crd/bases/core.humio.com_humioscheduledsearches.yaml +++ b/config/crd/bases/core.humio.com_humioscheduledsearches.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioscheduledsearches.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: diff --git a/config/crd/bases/core.humio.com_humioviews.yaml b/config/crd/bases/core.humio.com_humioviews.yaml index 52a21041..5cf7950a 100644 --- a/config/crd/bases/core.humio.com_humioviews.yaml +++ b/config/crd/bases/core.humio.com_humioviews.yaml @@ -5,6 +5,12 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.14.0 name: humioviews.core.humio.com + labels: + app: 'humio-operator' + app.kubernetes.io/name: 'humio-operator' + app.kubernetes.io/instance: 'humio-operator' + app.kubernetes.io/managed-by: 'Helm' + helm.sh/chart: 'humio-operator-0.24.0' spec: group: core.humio.com names: From 4916d348cfed1e6812dde39a936233286215a7c4 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 3 Sep 2024 14:00:04 -0700 Subject: [PATCH 46/54] cleanup --- pkg/humio/client_mock.go | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/pkg/humio/client_mock.go b/pkg/humio/client_mock.go index be302735..9cc0d629 100644 --- a/pkg/humio/client_mock.go +++ b/pkg/humio/client_mock.go @@ -39,20 +39,16 @@ var ( type resourceKey struct { // clusterName holds the value of the cluster clusterName string - // searchDomainName is the name of the repository or view searchDomainName string - // resourceName is the name of resource, like IngestToken, Parser, etc. resourceName string } type ClientMock struct { - OnPremLicense map[resourceKey]humioapi.OnPremLicense - - Repository map[resourceKey]humioapi.Repository - View map[resourceKey]humioapi.View - + OnPremLicense map[resourceKey]humioapi.OnPremLicense + Repository map[resourceKey]humioapi.Repository + View map[resourceKey]humioapi.View IngestToken map[resourceKey]humioapi.IngestToken Parser map[resourceKey]humioapi.Parser Action map[resourceKey]humioapi.Action @@ -60,8 +56,7 @@ type ClientMock struct { FilterAlert map[resourceKey]humioapi.FilterAlert AggregateAlert map[resourceKey]humioapi.AggregateAlert ScheduledSearch map[resourceKey]humioapi.ScheduledSearch - - User humioapi.User + User humioapi.User } type MockClientConfig struct { @@ -71,11 +66,9 @@ type MockClientConfig struct { func NewMockClient() *MockClientConfig { mockClientConfig := &MockClientConfig{ apiClient: &ClientMock{ - OnPremLicense: make(map[resourceKey]humioapi.OnPremLicense), - - Repository: make(map[resourceKey]humioapi.Repository), - View: make(map[resourceKey]humioapi.View), - + OnPremLicense: make(map[resourceKey]humioapi.OnPremLicense), + Repository: make(map[resourceKey]humioapi.Repository), + View: make(map[resourceKey]humioapi.View), IngestToken: make(map[resourceKey]humioapi.IngestToken), Parser: make(map[resourceKey]humioapi.Parser), Action: make(map[resourceKey]humioapi.Action), @@ -83,8 +76,7 @@ func NewMockClient() *MockClientConfig { FilterAlert: make(map[resourceKey]humioapi.FilterAlert), AggregateAlert: make(map[resourceKey]humioapi.AggregateAlert), ScheduledSearch: make(map[resourceKey]humioapi.ScheduledSearch), - - User: humioapi.User{}, + User: humioapi.User{}, }, } @@ -942,7 +934,6 @@ func (h *MockClientConfig) ClearHumioClientConnections(repoNameToKeep string) { } } h.apiClient.View = make(map[resourceKey]humioapi.View) - h.apiClient.IngestToken = make(map[resourceKey]humioapi.IngestToken) h.apiClient.Parser = make(map[resourceKey]humioapi.Parser) h.apiClient.Action = make(map[resourceKey]humioapi.Action) From 87bdbd25fc09e1cf45f3ba5f1200bc8f72f824b7 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 3 Sep 2024 14:07:02 -0700 Subject: [PATCH 47/54] cleanup --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1ee19245..84a9c565 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-logr/logr v1.4.1 github.com/go-logr/zapr v1.3.0 github.com/google/go-cmp v0.6.0 - github.com/humio/cli v0.36.0 + github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce github.com/onsi/ginkgo/v2 v2.17.1 github.com/onsi/gomega v1.32.0 github.com/prometheus/client_golang v1.19.0 diff --git a/go.sum b/go.sum index 44bb7d03..36a04211 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/humio/cli v0.36.0 h1:KAF4natLsnYNp2zyS1xCjDd6TB/pUz0wGootorBjjbA= -github.com/humio/cli v0.36.0/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= +github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce h1:WRVLad++Yerg08UcQCzAXY9UwV0P7U1lkOvrdMYUjVY= +github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= From 93c70fca9a7e12c22ada94cde48f7e2a4be41bb4 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 3 Sep 2024 14:25:11 -0700 Subject: [PATCH 48/54] cleanup --- api/v1alpha1/zz_generated.deepcopy.go | 203 ++++++++++++++++++ controllers/humioaggregatealert_controller.go | 2 +- .../humioscheduledsearch_controller.go | 2 +- .../clusters/humiocluster_controller_test.go | 5 +- 4 files changed, 208 insertions(+), 4 deletions(-) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index e48dd9ab..4b7b833e 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -335,6 +335,105 @@ func (in *HumioActionWebhookProperties) DeepCopy() *HumioActionWebhookProperties return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioAggregateAlert) DeepCopyInto(out *HumioAggregateAlert) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlert. +func (in *HumioAggregateAlert) DeepCopy() *HumioAggregateAlert { + if in == nil { + return nil + } + out := new(HumioAggregateAlert) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HumioAggregateAlert) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioAggregateAlertList) DeepCopyInto(out *HumioAggregateAlertList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]HumioAggregateAlert, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlertList. +func (in *HumioAggregateAlertList) DeepCopy() *HumioAggregateAlertList { + if in == nil { + return nil + } + out := new(HumioAggregateAlertList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HumioAggregateAlertList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioAggregateAlertSpec) DeepCopyInto(out *HumioAggregateAlertSpec) { + *out = *in + if in.Actions != nil { + in, out := &in.Actions, &out.Actions + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlertSpec. +func (in *HumioAggregateAlertSpec) DeepCopy() *HumioAggregateAlertSpec { + if in == nil { + return nil + } + out := new(HumioAggregateAlertSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioAggregateAlertStatus) DeepCopyInto(out *HumioAggregateAlertStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioAggregateAlertStatus. +func (in *HumioAggregateAlertStatus) DeepCopy() *HumioAggregateAlertStatus { + if in == nil { + return nil + } + out := new(HumioAggregateAlertStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioAlert) DeepCopyInto(out *HumioAlert) { *out = *in @@ -731,6 +830,11 @@ func (in *HumioClusterTLSSpec) DeepCopyInto(out *HumioClusterTLSSpec) { *out = new(bool) **out = **in } + if in.ExtraHostnames != nil { + in, out := &in.ExtraHostnames, &out.ExtraHostnames + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioClusterTLSSpec. @@ -1649,6 +1753,105 @@ func (in *HumioRetention) DeepCopy() *HumioRetention { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioScheduledSearch) DeepCopyInto(out *HumioScheduledSearch) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearch. +func (in *HumioScheduledSearch) DeepCopy() *HumioScheduledSearch { + if in == nil { + return nil + } + out := new(HumioScheduledSearch) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HumioScheduledSearch) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioScheduledSearchList) DeepCopyInto(out *HumioScheduledSearchList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]HumioScheduledSearch, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearchList. +func (in *HumioScheduledSearchList) DeepCopy() *HumioScheduledSearchList { + if in == nil { + return nil + } + out := new(HumioScheduledSearchList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HumioScheduledSearchList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioScheduledSearchSpec) DeepCopyInto(out *HumioScheduledSearchSpec) { + *out = *in + if in.Actions != nil { + in, out := &in.Actions, &out.Actions + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearchSpec. +func (in *HumioScheduledSearchSpec) DeepCopy() *HumioScheduledSearchSpec { + if in == nil { + return nil + } + out := new(HumioScheduledSearchSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HumioScheduledSearchStatus) DeepCopyInto(out *HumioScheduledSearchStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioScheduledSearchStatus. +func (in *HumioScheduledSearchStatus) DeepCopy() *HumioScheduledSearchStatus { + if in == nil { + return nil + } + out := new(HumioScheduledSearchStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioTokenSecretSpec) DeepCopyInto(out *HumioTokenSecretSpec) { *out = *in diff --git a/controllers/humioaggregatealert_controller.go b/controllers/humioaggregatealert_controller.go index 9f73c578..d654fe21 100644 --- a/controllers/humioaggregatealert_controller.go +++ b/controllers/humioaggregatealert_controller.go @@ -74,7 +74,7 @@ func (r *HumioAggregateAlertReconciler) Reconcile(ctx context.Context, req ctrl. r.Log = r.Log.WithValues("Request.UID", haa.UID) - cluster, err := helpers.NewCluster(ctx, r, haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName, haa.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName, haa.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioAggregateAlertStateConfigError, haa) if setStateErr != nil { diff --git a/controllers/humioscheduledsearch_controller.go b/controllers/humioscheduledsearch_controller.go index 31d6b38e..af3b72fc 100644 --- a/controllers/humioscheduledsearch_controller.go +++ b/controllers/humioscheduledsearch_controller.go @@ -77,7 +77,7 @@ func (r *HumioScheduledSearchReconciler) Reconcile(ctx context.Context, req ctrl r.Log = r.Log.WithValues("Request.UID", hss.UID) - cluster, err := helpers.NewCluster(ctx, r, hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName, hss.Namespace, helpers.UseCertManager(), true) + cluster, err := helpers.NewCluster(ctx, r, hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName, hss.Namespace, helpers.UseCertManager(), true, false) if err != nil || cluster == nil || cluster.Config() == nil { setStateErr := r.setState(ctx, humiov1alpha1.HumioScheduledSearchStateConfigError, hss) if setStateErr != nil { diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index e67b58dd..d04e1c50 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -19,11 +19,12 @@ package clusters import ( "context" "fmt" - cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" "os" "reflect" "strings" + cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" "github.com/humio/humio-operator/controllers" "github.com/humio/humio-operator/controllers/suite" @@ -1287,7 +1288,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating a cluster") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Validating pod bootstrap token annotation hash") From 073638106c399d1fd4f2681978c240d72d3a453c Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 3 Sep 2024 14:33:34 -0700 Subject: [PATCH 49/54] nosec // #nosec G101 --- controllers/humiocluster_annotations.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/controllers/humiocluster_annotations.go b/controllers/humiocluster_annotations.go index 1cc8836d..62420a15 100644 --- a/controllers/humiocluster_annotations.go +++ b/controllers/humiocluster_annotations.go @@ -31,11 +31,12 @@ import ( ) const ( - certHashAnnotation = "humio.com/certificate-hash" - PodHashAnnotation = "humio.com/pod-hash" - PodRevisionAnnotation = "humio.com/pod-revision" - envVarSourceHashAnnotation = "humio.com/env-var-source-hash" - pvcHashAnnotation = "humio_pvc_hash" + certHashAnnotation = "humio.com/certificate-hash" + PodHashAnnotation = "humio.com/pod-hash" + PodRevisionAnnotation = "humio.com/pod-revision" + envVarSourceHashAnnotation = "humio.com/env-var-source-hash" + pvcHashAnnotation = "humio_pvc_hash" + // #nosec G101 bootstrapTokenHashAnnotation = "humio.com/bootstrap-token-hash" ) From bc744ba22aebb95f912564ce9cb96a5d6f75cf54 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Tue, 3 Sep 2024 14:54:34 -0700 Subject: [PATCH 50/54] fix up go deps --- go.mod | 21 +++++++++++---------- go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 84a9c565..5c12e1a5 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,8 @@ require ( github.com/go-logr/zapr v1.3.0 github.com/google/go-cmp v0.6.0 github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce - github.com/onsi/ginkgo/v2 v2.17.1 - github.com/onsi/gomega v1.32.0 + github.com/onsi/ginkgo/v2 v2.19.0 + github.com/onsi/gomega v1.34.1 github.com/prometheus/client_golang v1.19.0 go.uber.org/zap v1.27.0 k8s.io/api v0.29.5 @@ -32,13 +32,13 @@ require ( github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240415144954-be81aee2d733 // indirect + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/imdario/mergo v0.3.16 // indirect @@ -56,17 +56,18 @@ require ( github.com/prometheus/procfs v0.13.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + golang.org/x/tools v0.23.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 36a04211..eec9e07a 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,8 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -50,8 +50,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240415144954-be81aee2d733 h1:nHRIUuWr4qaFmeHwGBzW5QtiLr3Zy5EXjnRpFG9RarE= -github.com/google/pprof v0.0.0-20240415144954-be81aee2d733/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -84,10 +84,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= -github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= -github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -106,7 +106,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -120,16 +119,18 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -140,10 +141,10 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= @@ -154,16 +155,16 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -172,7 +173,6 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.29.5 h1:levS+umUigHCfI3riD36pMY1vQEbrzh4r1ivVWAhHaI= From 762466c4207b1219465efdd2aae06ae8871c7b52 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Thu, 5 Sep 2024 14:59:35 -0700 Subject: [PATCH 51/54] bump default version to 1.142.3" and fix bootstrap pod exec for latest versions --- .../templates/operator-rbac.yaml | 8 ++++ controllers/humiobootstraptoken_controller.go | 26 ++++++++++--- controllers/humiobootstraptoken_defaults.go | 8 +++- controllers/humiocluster_defaults.go | 2 +- controllers/humiocluster_pods.go | 37 +++++++++++-------- pkg/kubernetes/humio_bootstrap_tokens.go | 1 - 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/charts/humio-operator/templates/operator-rbac.yaml b/charts/humio-operator/templates/operator-rbac.yaml index 457838c9..07f2a470 100644 --- a/charts/humio-operator/templates/operator-rbac.yaml +++ b/charts/humio-operator/templates/operator-rbac.yaml @@ -23,6 +23,7 @@ rules: - "" resources: - pods + - pods/exec - services - services/finalizers - endpoints @@ -67,6 +68,9 @@ rules: - humioclusters - humioclusters/finalizers - humioclusters/status + - humiobootstraptokens + - humiobootstraptokens/finalizers + - humiobootstraptokens/status - humioparsers - humioparsers/finalizers - humioparsers/status @@ -179,6 +183,7 @@ rules: - "" resources: - pods + - pods/exec - services - services/finalizers - endpoints @@ -231,6 +236,9 @@ rules: - humioclusters - humioclusters/finalizers - humioclusters/status + - humiobootstraptokens + - humiobootstraptokens/finalizers + - humiobootstraptokens/status - humioparsers - humioparsers/finalizers - humioparsers/status diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index ce2c3627..48d23605 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "strings" "time" "k8s.io/client-go/kubernetes/scheme" @@ -289,7 +290,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenSecret(ctx context.C return r.logErrorAndReturn(err, "cannot create bootstrap token") } if okayToCreate { - secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenName(), secretData, nil) + secret := kubernetes.ConstructSecret(hbt.Name, hbt.Namespace, humioBootstrapTokenConfig.bootstrapTokenSecretName(), secretData, nil) if err := controllerutil.SetControllerReference(hbt, secret, r.Scheme()); err != nil { return r.logErrorAndReturn(err, "could not set controller reference") } @@ -319,7 +320,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont return nil } - commandArgs := []string{"/bin/bash", "/app/humio/humio/bin/humio-run-class.sh", "com.humio.main.TokenHashing", "--json"} + commandArgs := []string{"env", "JVM_TMP_DIR=/tmp", "/app/humio/humio/bin/humio-token-hashing.sh", "--json"} if tokenSecret, ok := bootstrapTokenSecret.Data[BootstrapTokenSecretSecretName]; ok { commandArgs = append(commandArgs, string(tokenSecret)) @@ -356,10 +357,25 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont return r.logErrorAndReturn(err, "failed to exec pod") } + var jsonOutput string + var includeLine bool + outputLines := strings.Split(output, "\n") + for _, line := range outputLines { + if line == "{" { + includeLine = true + } + if line == "}" { + jsonOutput += "}" + includeLine = false + } + if includeLine { + jsonOutput += fmt.Sprintf("%s\n", line) + } + } var secretData HumioBootstrapTokenSecretData - err = json.Unmarshal([]byte(output), &secretData) + err = json.Unmarshal([]byte(jsonOutput), &secretData) if err != nil { - r.Log.Error(fmt.Errorf("failed to read output from exec command"), "omitting output") + return r.logErrorAndReturn(err, "failed to read output from exec command: output omitted") } updatedSecret, err := r.getBootstrapTokenSecret(ctx, hbt, hc) @@ -380,7 +396,7 @@ func (r *HumioBootstrapTokenReconciler) getBootstrapTokenSecret(ctx context.Cont existingSecret := &corev1.Secret{} err := r.Get(ctx, types.NamespacedName{ Namespace: hbt.Namespace, - Name: humioBootstrapTokenConfig.bootstrapTokenName(), + Name: humioBootstrapTokenConfig.bootstrapTokenSecretName(), }, existingSecret) return existingSecret, err } diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index 5b5bbdb4..b480049f 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -10,7 +10,7 @@ import ( ) const ( - bootstrapTokenSuffix = "bootstrap-token" + bootstrapTokenSecretSuffix = "bootstrap-token" bootstrapTokenPodNameSuffix = "bootstrap-token-onetime" ) @@ -24,10 +24,14 @@ func NewHumioBootstrapTokenConfig(bootstrapToken *humiov1alpha1.HumioBootstrapTo } func (b *HumioBootstrapTokenConfig) bootstrapTokenName() string { + return b.BootstrapToken.Name +} + +func (b *HumioBootstrapTokenConfig) bootstrapTokenSecretName() string { if b.BootstrapToken.Spec.TokenSecret.SecretKeyRef != nil { return b.BootstrapToken.Spec.TokenSecret.SecretKeyRef.Name } - return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, bootstrapTokenSuffix) + return fmt.Sprintf("%s-%s", b.BootstrapToken.Name, bootstrapTokenSecretSuffix) } func (b *HumioBootstrapTokenConfig) create() (bool, error) { diff --git a/controllers/humiocluster_defaults.go b/controllers/humiocluster_defaults.go index 8feec50a..8cdb8d20 100644 --- a/controllers/humiocluster_defaults.go +++ b/controllers/humiocluster_defaults.go @@ -33,7 +33,7 @@ import ( ) const ( - Image = "humio/humio-core:1.131.1" + Image = "humio/humio-core:1.142.3" HelperImage = "humio/humio-operator-helper:8f5ef6c7e470226e77d985f36cf39be9a100afea" targetReplicationFactor = 2 digestPartitionsCount = 24 diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index d2b8c54b..20010ac2 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -883,27 +883,32 @@ type podNameAndCertificateHash struct { func (r *HumioClusterReconciler) getDesiredBootstrapTokenHash(ctx context.Context, hc *humiov1alpha1.HumioCluster) (string, error) { humioBootstrapTokens, err := kubernetes.ListHumioBootstrapTokens(ctx, r.Client, hc.GetNamespace(), kubernetes.LabelsForHumioBootstrapToken(hc.GetName())) if err != nil { - return "", r.logErrorAndReturn(err, "failed to get bootstrap token") + return "", err } - if len(humioBootstrapTokens) > 0 { - if humioBootstrapTokens[0].Status.State == humiov1alpha1.HumioBootstrapTokenStateReady { - existingSecret := &corev1.Secret{} - err := r.Get(ctx, types.NamespacedName{ - Namespace: hc.GetNamespace(), - Name: humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, - }, existingSecret) - if err != nil { - return "", r.logErrorAndReturn(err, fmt.Sprintf("failed to get bootstrap token secret %s", - humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name)) - } + if len(humioBootstrapTokens) == 0 { + return "", fmt.Errorf("could not find bootstrap token matching labels %+v: %w", kubernetes.LabelsForHumioBootstrapToken(hc.GetName()), err) + } - if ok := string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key]); ok != "" { - return helpers.AsSHA256(string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key])), nil - } + if humioBootstrapTokens[0].Status.State == humiov1alpha1.HumioBootstrapTokenStateReady { + existingSecret := &corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ + Namespace: hc.GetNamespace(), + Name: humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, + }, existingSecret) + if err != nil { + return "", fmt.Errorf("failed to get bootstrap token secret %s: %w", + humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, err) } + + if ok := string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key]); ok != "" { + return helpers.AsSHA256(string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key])), nil + } else { + return "", fmt.Errorf("bootstrap token %s does not have a value for key %s", humioBootstrapTokens[0].Name, humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key) + } + } else { + return "", fmt.Errorf("bootstrap token not ready. status=%s", humioBootstrapTokens[0].Status.State) } - return "", r.logErrorAndReturn(err, fmt.Sprintf("could not find bootstrap token secret matching labels %+v", kubernetes.LabelsForHumioBootstrapToken(hc.GetName()))) } // findHumioNodeNameAndCertHash looks up the name of a free node certificate to use and the hash of the certificate specification diff --git a/pkg/kubernetes/humio_bootstrap_tokens.go b/pkg/kubernetes/humio_bootstrap_tokens.go index 764be88a..d500f795 100644 --- a/pkg/kubernetes/humio_bootstrap_tokens.go +++ b/pkg/kubernetes/humio_bootstrap_tokens.go @@ -25,7 +25,6 @@ limitations under the License. */ const ( - BootstrapTokenNameSuffix = "bootstrap-token" BootstrapTokenSecretNameSuffix = "bootstrap-token" BootstrapTokenManagedClusterNameLabelName = "managed-cluster-name" ) From d125db71f390972a8560057ef9743b59d9e84d45 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 6 Sep 2024 08:05:02 -0700 Subject: [PATCH 52/54] cleanup --- controllers/humiobootstraptoken_defaults.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/controllers/humiobootstraptoken_defaults.go b/controllers/humiobootstraptoken_defaults.go index b480049f..361e0375 100644 --- a/controllers/humiobootstraptoken_defaults.go +++ b/controllers/humiobootstraptoken_defaults.go @@ -23,10 +23,6 @@ func NewHumioBootstrapTokenConfig(bootstrapToken *humiov1alpha1.HumioBootstrapTo return HumioBootstrapTokenConfig{BootstrapToken: bootstrapToken, ManagedHumioCluster: managedHumioCluster} } -func (b *HumioBootstrapTokenConfig) bootstrapTokenName() string { - return b.BootstrapToken.Name -} - func (b *HumioBootstrapTokenConfig) bootstrapTokenSecretName() string { if b.BootstrapToken.Spec.TokenSecret.SecretKeyRef != nil { return b.BootstrapToken.Spec.TokenSecret.SecretKeyRef.Name From 41ce946d52ef87e0c19a537b9c8fc21686c174d6 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 6 Sep 2024 10:21:29 -0700 Subject: [PATCH 53/54] update test --- controllers/humiocluster_pods.go | 32 +++++++++---------- .../clusters/humiocluster_controller_test.go | 6 +++- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index 20010ac2..7117bfcf 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -890,25 +890,23 @@ func (r *HumioClusterReconciler) getDesiredBootstrapTokenHash(ctx context.Contex return "", fmt.Errorf("could not find bootstrap token matching labels %+v: %w", kubernetes.LabelsForHumioBootstrapToken(hc.GetName()), err) } - if humioBootstrapTokens[0].Status.State == humiov1alpha1.HumioBootstrapTokenStateReady { - existingSecret := &corev1.Secret{} - err := r.Get(ctx, types.NamespacedName{ - Namespace: hc.GetNamespace(), - Name: humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, - }, existingSecret) - if err != nil { - return "", fmt.Errorf("failed to get bootstrap token secret %s: %w", - humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, err) - } - - if ok := string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key]); ok != "" { - return helpers.AsSHA256(string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key])), nil - } else { - return "", fmt.Errorf("bootstrap token %s does not have a value for key %s", humioBootstrapTokens[0].Name, humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key) - } - } else { + if humioBootstrapTokens[0].Status.State != humiov1alpha1.HumioBootstrapTokenStateReady { return "", fmt.Errorf("bootstrap token not ready. status=%s", humioBootstrapTokens[0].Status.State) } + + existingSecret := &corev1.Secret{} + if r.Get(ctx, types.NamespacedName{ + Namespace: hc.GetNamespace(), + Name: humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, + }, existingSecret); err != nil { + return "", fmt.Errorf("failed to get bootstrap token secret %s: %w", + humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, err) + } + + if ok := string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key]); ok != "" { + return helpers.AsSHA256(string(existingSecret.Data[humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key])), nil + } + return "", fmt.Errorf("bootstrap token %s does not have a value for key %s", humioBootstrapTokens[0].Name, humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Key) } // findHumioNodeNameAndCertHash looks up the name of a free node certificate to use and the hash of the certificate specification diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index d04e1c50..0a43158a 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -1317,7 +1317,11 @@ var _ = Describe("HumioCluster Controller", func() { Expect(k8sClient.Update(ctx, &bootstrapTokenSecret)).To(BeNil()) var updatedHumioCluster humiov1alpha1.HumioCluster - Expect(k8sClient.Get(ctx, key, &updatedHumioCluster)).To(BeNil()) + Eventually(func() string { + updatedHumioCluster = humiov1alpha1.HumioCluster{} + Expect(k8sClient.Get(ctx, key, &updatedHumioCluster)).Should(Succeed()) + return updatedHumioCluster.Status.State + }, testTimeout, suite.TestInterval).Should(BeIdenticalTo(humiov1alpha1.HumioClusterStateRestarting)) suite.UsingClusterBy(key.Name, "Restarting the cluster in a rolling fashion") ensurePodsRollingRestart(ctx, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster), 2) From 0706d42f5fe79e5a685f3c0f7b463c936c573885 Mon Sep 17 00:00:00 2001 From: Jestin Woods Date: Fri, 6 Sep 2024 10:32:27 -0700 Subject: [PATCH 54/54] update test --- controllers/humiocluster_pods.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index 7117bfcf..52056294 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -895,7 +895,7 @@ func (r *HumioClusterReconciler) getDesiredBootstrapTokenHash(ctx context.Contex } existingSecret := &corev1.Secret{} - if r.Get(ctx, types.NamespacedName{ + if err := r.Get(ctx, types.NamespacedName{ Namespace: hc.GetNamespace(), Name: humioBootstrapTokens[0].Status.HashedTokenSecretKeyRef.SecretKeyRef.Name, }, existingSecret); err != nil {