Skip to content

Commit

Permalink
some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
jswoods committed Sep 28, 2023
1 parent bbc95d8 commit ed0a6a1
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 96 deletions.
14 changes: 7 additions & 7 deletions api/v1alpha1/humiobootstraptoken_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}
Expand Down
8 changes: 4 additions & 4 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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.
Expand Down
18 changes: 8 additions & 10 deletions config/crd/bases/core.humio.com_humiobootstraptokens.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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.
Expand Down
84 changes: 46 additions & 38 deletions controllers/humiobootstraptoken_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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")
}
Expand Down Expand Up @@ -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))
}

Expand Down Expand Up @@ -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")
Expand Down
22 changes: 11 additions & 11 deletions controllers/humiobootstraptoken_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
)

const (
BootstrapTokenSuffix = "bootstrap-token"
HashedBootstrapTokenSuffix = "hashed-bootstrap-token"
BootstrapTokenSuffix = "bootstrap-token"
//HashedBootstrapTokenSuffix = "hashed-bootstrap-token"
)

type HumioBootstrapTokenConfig struct {
Expand All @@ -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
}
Expand Down
21 changes: 16 additions & 5 deletions controllers/humiocluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,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{
Expand Down Expand Up @@ -470,13 +481,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")
Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/go-logr/logr"
"github.com/go-logr/zapr"
humioapi "github.com/humio/cli/api"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"
Expand Down Expand Up @@ -184,6 +185,13 @@ func main() {
ctrl.Log.Error(err, "unable to create controller", "controller", "HumioAlert")
os.Exit(1)
}
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)
}
//+kubebuilder:scaffold:builder

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
Expand Down
Loading

0 comments on commit ed0a6a1

Please sign in to comment.