Skip to content

Commit

Permalink
add controller to create and delete individual usernames in mariadb
Browse files Browse the repository at this point in the history
this is a first draft of a "create /drop account" controller that is
separate from the main "create/drop database" controller, for the
purpose of producing rotating username/passwords. The background for the
change is based on discussions surrounding
https://issues.redhat.com/browse/OSPRH-92 where internal control plane
services such as Galera , Rabbit, Redis etc. would provide interfaces to
add /remove arbitrary usernames, where a "password rotation" would
involve adding a new username/password and having services switch there,
retiring the old account once all finalizers have been removed.
  • Loading branch information
zzzeek committed Nov 22, 2023
1 parent d9d9d1f commit 4471b1e
Show file tree
Hide file tree
Showing 13 changed files with 656 additions and 58 deletions.
60 changes: 60 additions & 0 deletions api/bases/mariadb.openstack.org_mariadbaccounts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.1
creationTimestamp: null
name: mariadbaccounts.mariadb.openstack.org
spec:
group: mariadb.openstack.org
names:
kind: MariaDBAccount
listKind: MariaDBAccountList
plural: mariadbaccounts
singular: mariadbaccount
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: MariaDBAccount is the Schema for the mariadbaccounts API
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: MariaDBAccountSpec defines the desired state of MariaDBAccount
properties:
secret:
description: Name of secret which contains DatabasePassword
type: string
userName:
description: UserName for new account
type: string
type: object
status:
description: MariaDBAccountStatus defines the observed state of MariaDBAccount
properties:
completed:
type: boolean
hash:
additionalProperties:
type: string
description: Map of hashes to track e.g. job status
type: object
type: object
type: object
served: true
storage: true
subresources:
status: {}
22 changes: 14 additions & 8 deletions api/v1beta1/mariadbaccount_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,28 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
const (
// AccountCreateHash hash
AccountCreateHash = "accountcreate"

// AccountDeleteHash hash
AccountDeleteHash = "accountdelete"
)

// MariaDBAccountSpec defines the desired state of MariaDBAccount
type MariaDBAccountSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// UserName for new account
UserName string `json:"userName,omitempty"`

// Foo is an example field of MariaDBAccount. Edit mariadbaccount_types.go to remove/update
Foo string `json:"foo,omitempty"`
// Name of secret which contains DatabasePassword
Secret string `json:"secret,omitempty"`
}

// MariaDBAccountStatus defines the observed state of MariaDBAccount
type MariaDBAccountStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Completed bool `json:"completed,omitempty"`
// Map of hashes to track e.g. job status
Hash map[string]string `json:"hash,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down
9 changes: 8 additions & 1 deletion api/v1beta1/zz_generated.deepcopy.go

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

60 changes: 60 additions & 0 deletions config/crd/bases/mariadb.openstack.org_mariadbaccounts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.11.1
creationTimestamp: null
name: mariadbaccounts.mariadb.openstack.org
spec:
group: mariadb.openstack.org
names:
kind: MariaDBAccount
listKind: MariaDBAccountList
plural: mariadbaccounts
singular: mariadbaccount
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: MariaDBAccount is the Schema for the mariadbaccounts API
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: MariaDBAccountSpec defines the desired state of MariaDBAccount
properties:
secret:
description: Name of secret which contains DatabasePassword
type: string
userName:
description: UserName for new account
type: string
type: object
status:
description: MariaDBAccountStatus defines the observed state of MariaDBAccount
properties:
completed:
type: boolean
hash:
additionalProperties:
type: string
description: Map of hashes to track e.g. job status
type: object
type: object
type: object
served: true
storage: true
subresources:
status: {}
26 changes: 26 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,32 @@ rules:
- list
- patch
- update
- apiGroups:
- mariadb.openstack.org
resources:
- mariadbaccounts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- mariadb.openstack.org
resources:
- mariadbaccounts/finalizers
verbs:
- update
- apiGroups:
- mariadb.openstack.org
resources:
- mariadbaccounts/status
verbs:
- get
- patch
- update
- apiGroups:
- mariadb.openstack.org
resources:
Expand Down
17 changes: 15 additions & 2 deletions config/samples/mariadb_v1beta1_mariadbaccount.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ metadata:
app.kubernetes.io/part-of: mariadb-operator
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/created-by: mariadb-operator
name: mariadbaccount-sample
mariaDBDatabaseName: neutron
name: neutron1
spec:
# TODO(user): Add fields here
userName: neutron1
secret: neutrondb-secret

---

apiVersion: v1
data:
# neutron123
DatabasePassword: bmV1dHJvbjEyMw==
kind: Secret
metadata:
name: neutrondb-secret
type: Opaque
44 changes: 44 additions & 0 deletions controllers/galera_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/kubectl/pkg/util/podutils"
Expand All @@ -49,6 +50,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"

databasev1beta1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1"
mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1"
mariadb "github.com/openstack-k8s-operators/mariadb-operator/pkg/mariadb"
)
Expand Down Expand Up @@ -665,3 +667,45 @@ func (r *GaleraReconciler) SetupWithManager(mgr ctrl.Manager) error {
Owns(&rbacv1.RoleBinding{}).
Complete(r)
}

// GetDatabaseObject - returns either a Galera or MariaDB object (and an associated client.Object interface).
// used by both MariaDBDatabaseReconciler and MariaDBAccountReconciler
// this will later return only Galera objects, so as a lookup it's part of the galera controller

func GetDatabaseObject(clientObj client.Client, ctx context.Context, name string, namespace string) (client.Object, *databasev1beta1.Galera, *databasev1beta1.MariaDB, error) {

dbGalera := &databasev1beta1.Galera{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}

objectKey := client.ObjectKeyFromObject(dbGalera)

err := clientObj.Get(ctx, objectKey, dbGalera)
if err != nil && !k8s_errors.IsNotFound(err) {
return nil, nil, nil, err
}

if err != nil {
// Try to fetch MariaDB when Galera is not used
dbMariadb := &databasev1beta1.MariaDB{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}

objectKey = client.ObjectKeyFromObject(dbMariadb)

err = clientObj.Get(ctx, objectKey, dbMariadb)
if err != nil {
return nil, nil, nil, err
}

return dbMariadb, nil, dbMariadb, nil
}

return dbGalera, dbGalera, nil, nil
}
Loading

0 comments on commit 4471b1e

Please sign in to comment.