Skip to content

Commit

Permalink
Optionally read credentials from secret
Browse files Browse the repository at this point in the history
  • Loading branch information
etomaselli committed Dec 4, 2023
1 parent 9e6965b commit 779ea79
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 65 deletions.
6 changes: 4 additions & 2 deletions api/v1/dremiorestserver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type DremioRestServerSpec struct {

// Properties to connect to Dremio
// +operator-sdk:csv:customresourcedefinitions:type=spec
Dremio DremioProperties `json:"dremio,omitempty"`
Connection ConnectionProperties `json:"connection,omitempty"`

// Corresponds to resources.limits of a container
// +operator-sdk:csv:customresourcedefinitions:type=spec
Expand All @@ -46,13 +46,15 @@ type DremioRestServerSpec struct {
ContainerRequests Requests `json:"containerRequests,omitempty"`
}

type DremioProperties struct {
type ConnectionProperties struct {
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
User string `json:"user,omitempty"`
Password string `json:"password,omitempty"`
// Additional JDBC options supported by the Arrow Flight SQL JDBC driver that will be passed as query parameters (e.g.: useEncryption=false&disableCertificateVerification=true)
JdbcProperties string `json:"jdbcProperties,omitempty"`
// Alternative to password
SecretName string `json:"secretName,omitempty"`
}

type Limits struct {
Expand Down
10 changes: 5 additions & 5 deletions api/v1/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 @@ -35,23 +35,7 @@ spec:
spec:
description: Dremio REST Server properties
properties:
containerLimits:
description: Corresponds to resources.limits of a container
properties:
cpu:
type: string
memory:
type: string
type: object
containerRequests:
description: Corresponds to resources.requests of a container
properties:
cpu:
type: string
memory:
type: string
type: object
dremio:
connection:
description: Properties to connect to Dremio
properties:
host:
Expand All @@ -65,9 +49,28 @@ spec:
type: string
port:
type: integer
secretName:
description: Alternative to password
type: string
user:
type: string
type: object
containerLimits:
description: Corresponds to resources.limits of a container
properties:
cpu:
type: string
memory:
type: string
type: object
containerRequests:
description: Corresponds to resources.requests of a container
properties:
cpu:
type: string
memory:
type: string
type: object
javaOptions:
description: 'Corresponds to JAVA_TOOL_OPTIONS: on JDK 9+, --add-opens=java.base/java.nio=ALL-UNNAMED
is required'
Expand Down
7 changes: 4 additions & 3 deletions config/samples/operator_v1_dremiorestserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ metadata:
spec:
javaOptions: --add-opens=java.base/java.nio=ALL-UNNAMED
tables: postgres.instagram.utenti
dremio:
connection:
host: 192.168.178.120
port: 32010
user: dremio
password: dremio123
user:
password:
jdbcProperties: useEncryption=false&disableCertificateVerification=true
secretName: mysecret
# containerLimits:
# cpu: 1000m
# memory: 512Mi
Expand Down
39 changes: 21 additions & 18 deletions deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,7 @@ spec:
spec:
description: Dremio REST Server properties
properties:
containerLimits:
description: Corresponds to resources.limits of a container
properties:
cpu:
type: string
memory:
type: string
type: object
containerRequests:
description: Corresponds to resources.requests of a container
properties:
cpu:
type: string
memory:
type: string
type: object
dremio:
connection:
description: Properties to connect to Dremio
properties:
host:
Expand All @@ -77,9 +61,28 @@ spec:
type: string
port:
type: integer
secretName:
description: Alternative to password
type: string
user:
type: string
type: object
containerLimits:
description: Corresponds to resources.limits of a container
properties:
cpu:
type: string
memory:
type: string
type: object
containerRequests:
description: Corresponds to resources.requests of a container
properties:
cpu:
type: string
memory:
type: string
type: object
javaOptions:
description: 'Corresponds to JAVA_TOOL_OPTIONS: on JDK 9+, --add-opens=java.base/java.nio=ALL-UNNAMED
is required'
Expand Down Expand Up @@ -436,7 +439,7 @@ spec:
value: 0.0.2-SNAPSHOT
- name: DRS_SERVICE_TYPE
value: ClusterIP
image: dremiorestserver.digitalhub/dremio-rest-server-operator:0.0.2
image: dremiorestserver.digitalhub/dremio-rest-server-operator:1.0.0
livenessProbe:
httpGet:
path: /healthz
Expand Down
99 changes: 79 additions & 20 deletions internal/controller/dremiorestserver_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const dremioRestServerImage = "DRS_IMAGE"
const dremioRestServerImageTag = "DRS_IMAGE_TAG"
const dremioRestServerServiceType = "DRS_SERVICE_TYPE"

const dremioUriSecretKey = "dremioUri"

// Definitions to manage status conditions
const (
// Launch deployment and service
Expand Down Expand Up @@ -118,7 +120,7 @@ func (r *DremioRestServerReconciler) Reconcile(ctx context.Context, req ctrl.Req
err = r.Get(ctx, types.NamespacedName{Name: formatResourceName(dremiorestserver.Name), Namespace: dremiorestserver.Namespace}, existingSecret)
if err != nil && apierrors.IsNotFound(err) {
// Create secret
secret, err := r.secretForDremiorestserver(dremiorestserver)
secret, err := r.secretForDremiorestserver(dremiorestserver, ctx)
if err != nil {
log.Error(err, "Failed to define new Secret resource for DremioRestServer")

Expand Down Expand Up @@ -221,7 +223,15 @@ func (r *DremioRestServerReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, err
}

updated := crUpdated(dep, dremiorestserver)
dremioUri, err := r.createConnectionString(dremiorestserver, ctx)
if err != nil {
return ctrl.Result{}, err
}

secret := &corev1.Secret{}
err = r.Get(ctx, types.NamespacedName{Name: formatResourceName(dremiorestserver.Name), Namespace: dremiorestserver.Namespace}, secret)

updated := crUpdated(dep, dremiorestserver, dremioUri, string(secret.Data[dremioUriSecretKey]))
if updated {
dremiorestserver.Status.State = typeUpdating
if err = r.Status().Update(ctx, dremiorestserver); err != nil {
Expand Down Expand Up @@ -272,6 +282,13 @@ func (r *DremioRestServerReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, err
}

// Delete secret
secret := &corev1.Secret{}
err = r.Get(ctx, types.NamespacedName{Name: formatResourceName(dremiorestserver.Name), Namespace: dremiorestserver.Namespace}, secret)
if err := r.Delete(ctx, secret); err != nil {
log.Error(err, "Failed to clean up secret")
}

// Move to deploying state
dremiorestserver.Status.State = typeDeploying
if err = r.Status().Update(ctx, dremiorestserver); err != nil {
Expand Down Expand Up @@ -330,7 +347,11 @@ func (r *DremioRestServerReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, nil
}

func crUpdated(dep *appsv1.Deployment, cr *operatorv1.DremioRestServer) bool {
func crUpdated(dep *appsv1.Deployment, cr *operatorv1.DremioRestServer, newDremioUri string, oldDremioUri string) bool {
if newDremioUri != oldDremioUri {
return true
}

// Check if CR spec (JavaOptions, Tables, ContainerLimits, ContainerRequests) has been modified
for _, env := range dep.Spec.Template.Spec.Containers[0].Env {
if env.Name == "JAVA_TOOL_OPTIONS" {
Expand Down Expand Up @@ -401,6 +422,7 @@ func (r *DremioRestServerReconciler) deploymentForDremiorestserver(
}

emptyDirSize := resource.MustParse("10Mi")

//leave limits and requests empty by default
limits := corev1.ResourceList{}
if dremiorestserver.Spec.ContainerLimits.Cpu != "" {
Expand Down Expand Up @@ -518,7 +540,7 @@ func (r *DremioRestServerReconciler) deploymentForDremiorestserver(
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: formatResourceName(dremiorestserver.Name)},
Key: "dremioUri",
Key: dremioUriSecretKey,
Optional: &[]bool{false}[0],
},
},
Expand Down Expand Up @@ -585,28 +607,51 @@ func (r *DremioRestServerReconciler) serviceForDremiorestserver(dremiorestserver
return service, nil
}

func (r *DremioRestServerReconciler) secretForDremiorestserver(dremiorestserver *operatorv1.DremioRestServer) (*corev1.Secret, error) {
tag, found := os.LookupEnv(dremioRestServerImageTag)
if !found {
tag = "latest"
}

host := dremiorestserver.Spec.Dremio.Host
func (r *DremioRestServerReconciler) createConnectionString(dremiorestserver *operatorv1.DremioRestServer, ctx context.Context) (string, error) {
host := dremiorestserver.Spec.Connection.Host
if host == "" {
return nil, fmt.Errorf("dremio host missing from spec")
return "", fmt.Errorf("dremio host missing from spec")
}

port := dremiorestserver.Spec.Dremio.Port
if port == 0 {
return nil, fmt.Errorf("dremio port missing from spec")
user := dremiorestserver.Spec.Connection.User
password := dremiorestserver.Spec.Connection.Password
secretName := dremiorestserver.Spec.Connection.SecretName

// check that there is either password or secretName
if secretName != "" {
if password != "" || user != "" {
return "", fmt.Errorf("either specify user and password or secretName")
}

//read secret
secret := &corev1.Secret{}
err := r.Get(ctx, types.NamespacedName{Name: secretName, Namespace: dremiorestserver.Namespace}, secret)
if err != nil {
return "", err
}

//check that secret contains USER and PASSWORD
userFromSecret := secret.Data["USER"]
passwordFromSecret := secret.Data["PASSWORD"]
if userFromSecret == nil || passwordFromSecret == nil {
return "", fmt.Errorf("secret must contain USER and PASSWORD")
}

user = string(userFromSecret)
password = string(passwordFromSecret)
} else if password == "" || user == "" {
return "", fmt.Errorf("specify both user and password")
}

user := dremiorestserver.Spec.Dremio.User
password := dremiorestserver.Spec.Dremio.Password
jdbcProperties := dremiorestserver.Spec.Dremio.JdbcProperties
port := dremiorestserver.Spec.Connection.Port
jdbcProperties := dremiorestserver.Spec.Connection.JdbcProperties

if port != 0 {
host = fmt.Sprintf("%v:%v", host, port)
}

// build Dremio URI
dremioRestServerUri := fmt.Sprintf("%v:%v/", host, port)
dremioRestServerUri := host

str := []string{}
if user != "" {
Expand All @@ -624,13 +669,27 @@ func (r *DremioRestServerReconciler) secretForDremiorestserver(dremiorestserver
dremioRestServerUri += fmt.Sprintf("?%v", queryParams)
}

return dremioRestServerUri, nil
}

func (r *DremioRestServerReconciler) secretForDremiorestserver(dremiorestserver *operatorv1.DremioRestServer, ctx context.Context) (*corev1.Secret, error) {
tag, found := os.LookupEnv(dremioRestServerImageTag)
if !found {
tag = "latest"
}

dremioRestServerUri, err := r.createConnectionString(dremiorestserver, ctx)
if err != nil {
return nil, err
}

secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: formatResourceName(dremiorestserver.Name),
Namespace: dremiorestserver.Namespace,
Labels: labelsForDremioRestServer(dremiorestserver.Name, tag),
},
StringData: map[string]string{"dremioUri": dremioRestServerUri},
StringData: map[string]string{dremioUriSecretKey: dremioRestServerUri},
}

if err := ctrl.SetControllerReference(dremiorestserver, secret, r.Scheme); err != nil {
Expand Down

0 comments on commit 779ea79

Please sign in to comment.