Skip to content

Commit

Permalink
Adding operator checks to SSL
Browse files Browse the repository at this point in the history
adding external ssl validator using pq driver for golang
fix - adapting secret to the one in noobaa spec

Signed-off-by: jackyalbo <jacky.albo@gmail.com>
  • Loading branch information
jackyalbo committed Sep 21, 2023
1 parent ca77862 commit 72bc5c3
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 36 deletions.
7 changes: 0 additions & 7 deletions deploy/internal/deployment-endpoint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ spec:
secret:
secretName: noobaa-s3-serving-cert
optional: true
- name: external-db-ssl-secret
secret:
secretName: noobaa-external-db-cert
optional: true
- name: oidc-token
projected:
sources:
Expand Down Expand Up @@ -132,9 +128,6 @@ spec:
- name: s3-secret
mountPath: /etc/s3-secret
readOnly: true
- name: external-db-ssl-secret
mountPath: /etc/external-db-secret
readOnly: true
- name: noobaa-auth-token
mountPath: /etc/noobaa-auth-token
readOnly: true
Expand Down
7 changes: 0 additions & 7 deletions deploy/internal/statefulset-core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ spec:
secret:
secretName: noobaa-s3-serving-cert
optional: true
- name: external-db-ssl-secret
secret:
secretName: noobaa-external-db-cert
optional: true
- name: noobaa-server
secret:
secretName: noobaa-server
Expand All @@ -63,9 +59,6 @@ spec:
- name: s3-secret
mountPath: /etc/s3-secret
readOnly: true
- name: external-db-ssl-secret
mountPath: /etc/external-db-secret
readOnly: true
- name: noobaa-server
mountPath: /etc/noobaa-server
readOnly: true
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.16.5 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/lib/pq v1.10.9
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1809,6 +1809,8 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libopenstorage/autopilot-api v0.6.1-0.20210128210103-5fbb67948648/go.mod h1:6JLrPbR3ZJQFbUY/+QJMl/aF00YdIrLf8/GWAplgvJs=
github.com/libopenstorage/openstorage v8.0.0+incompatible/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
github.com/libopenstorage/operator v0.0.0-20200725001727-48d03e197117/go.mod h1:Qh+VXOB6hj60VmlgsmY+R1w+dFuHK246UueM4SAqZG0=
Expand Down
18 changes: 2 additions & 16 deletions pkg/bundle/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3678,7 +3678,7 @@ data:
su postgres -c "bash -x /usr/bin/run-postgresql"
`

const Sha256_deploy_internal_deployment_endpoint_yaml = "c6b23dc4cd61b35fcdd53df59074a95df46526823ebd42862289886c8b11ae0f"
const Sha256_deploy_internal_deployment_endpoint_yaml = "bd3efd480e3a73ebdc64acfbde114f938283604a7a8291d94a280b535a5c81cd"

const File_deploy_internal_deployment_endpoint_yaml = `apiVersion: apps/v1
kind: Deployment
Expand Down Expand Up @@ -3714,10 +3714,6 @@ spec:
secret:
secretName: noobaa-s3-serving-cert
optional: true
- name: external-db-ssl-secret
secret:
secretName: noobaa-external-db-cert
optional: true
- name: oidc-token
projected:
sources:
Expand Down Expand Up @@ -3814,9 +3810,6 @@ spec:
- name: s3-secret
mountPath: /etc/s3-secret
readOnly: true
- name: external-db-ssl-secret
mountPath: /etc/external-db-secret
readOnly: true
- name: noobaa-auth-token
mountPath: /etc/noobaa-auth-token
readOnly: true
Expand Down Expand Up @@ -4704,7 +4697,7 @@ spec:
noobaa-s3-svc: "true"
`

const Sha256_deploy_internal_statefulset_core_yaml = "d794c900f09e09b0e2be94869f5537271cbc2ab6d806d5182fb7fe2ff950b8ae"
const Sha256_deploy_internal_statefulset_core_yaml = "0489de0ea1cd3904274a8f58a5bca789592eab4991e911ce7703d238a223a168"

const File_deploy_internal_statefulset_core_yaml = `apiVersion: apps/v1
kind: StatefulSet
Expand Down Expand Up @@ -4741,10 +4734,6 @@ spec:
secret:
secretName: noobaa-s3-serving-cert
optional: true
- name: external-db-ssl-secret
secret:
secretName: noobaa-external-db-cert
optional: true
- name: noobaa-server
secret:
secretName: noobaa-server
Expand All @@ -4771,9 +4760,6 @@ spec:
- name: s3-secret
mountPath: /etc/s3-secret
readOnly: true
- name: external-db-ssl-secret
mountPath: /etc/external-db-secret
readOnly: true
- name: noobaa-server
mountPath: /etc/noobaa-server
readOnly: true
Expand Down
85 changes: 85 additions & 0 deletions pkg/system/phase1_verifying.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package system

import (
"database/sql"
"fmt"
"os"

// this is the driver we are using for psql
_ "github.com/lib/pq"

"github.com/asaskevich/govalidator"
semver "github.com/coreos/go-semver/semver"
dockerref "github.com/docker/distribution/reference"
Expand Down Expand Up @@ -31,6 +35,34 @@ func (r *Reconciler) ReconcilePhaseVerifying() error {
}
}

if r.ExternalPgSecret != nil {
if r.ExternalPgSecret.StringData["db_url"] == "" {
return util.NewPersistentError("InvalidExternalPgSecert",
"ExternalPgSecret is missing db_url")
}
if r.ExternalPgSSLSecret != nil {
if r.ExternalPgSSLSecret.StringData["tls.key"] == "" ||
r.ExternalPgSSLSecret.StringData["tls.crt"] == "" {
return util.NewPersistentError("InvalidExternalPgCert",
fmt.Sprintf("%q is missing private key (must be tls.key)"+
" or missing cert key (must be tls.cert)", r.ExternalPgSSLSecret.Name))
}
err := os.WriteFile("/tmp/tls.key", []byte(r.ExternalPgSSLSecret.StringData["tls.key"]), 0600)
if err != nil {
return fmt.Errorf("failed to write k8s secret tls.key content to a file %v", err)
}
err = os.WriteFile("/tmp/tls.crt", []byte(r.ExternalPgSSLSecret.StringData["tls.crt"]), 0644)
if err != nil {
return fmt.Errorf("failed to write k8s secret tls.key content to a file %v", err)
}
os.Setenv("PGSSLKEY", "/tmp/tls.key")
os.Setenv("PGSSLCERT", "/tmp/tls.crt")
}
if err := r.checkExternalPg(r.ExternalPgSecret.StringData["db_url"]); err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -171,3 +203,56 @@ func (r *Reconciler) CheckJoinSecret() error {
}
return nil
}

func (r *Reconciler) checkExternalPg(postgresDbURL string) error {
dbURL := r.ExternalPgSecret.StringData["db_url"]
if r.NooBaa.Spec.ExternalPgSSLRequired {
if !r.NooBaa.Spec.ExternalPgSSLUnauthorized {
dbURL += "?sslmode=verify-full" // won't allow self-signed certs
} // when we want to allow self-signed we will use the default sslmode=require
} else {
dbURL += "?sslmode=disable" // don't use ssl - the default is to use it
}
db, err := sql.Open("postgres", dbURL)
if err != nil {
return util.NewPersistentError("InvalidExternalPgUrl",
fmt.Sprintf("failed openning a connection to external DB url: %q, error: %s",
dbURL, err))
}
defer db.Close()
err = db.Ping()
if err != nil {
return util.NewPersistentError("InvalidExternalPgUrl",
fmt.Sprintf("failed pinging external DB url: %q, error: %s",
dbURL, err))
}
// Query the PostgreSQL version
var version string
err = db.QueryRow("SELECT current_setting('server_version_num')::integer / 10000").Scan(&version)
if err != nil {
return util.NewPersistentError("InvalidExternalPgVersion",
fmt.Sprintf("failed getting version of external DB url: %q, error: %s",
dbURL, err))
}
// Check if the version is 15
if version != "15" {
return util.NewPersistentError("InvalidExternalPgVersion",
fmt.Sprintf("version of external DB %q, is not supported: %s",
dbURL, version))
}
// Query the database's collation
var collation string
err = db.QueryRow("SELECT datcollate FROM pg_database WHERE datname = current_database()").Scan(&collation)
if err != nil {
return util.NewPersistentError("InvalidExternalPgCollation",
fmt.Sprintf("failed getting database collation of external DB url: %q, error: %s",
dbURL, err))
}
// Check if the collation is "C"
if collation != "C" {
return util.NewPersistentError("InvalidExternalPgCollation",
fmt.Sprintf("collation of external DB url: %q, is not supported: %s",
dbURL, err))
}
return nil
}
19 changes: 19 additions & 0 deletions pkg/system/phase2_creating.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,14 @@ func (r *Reconciler) SetDesiredCoreApp() error {
}}
util.MergeVolumeMountList(&c.VolumeMounts, &configMapVolumeMounts)
}
if r.ExternalPgSSLSecret != nil && util.KubeCheckQuiet(r.ExternalPgSSLSecret) {
secretVolumeMounts := []corev1.VolumeMount{{
Name: r.ExternalPgSSLSecret.Name,
MountPath: "/etc/external-db-secret",
ReadOnly: true,
}}
util.MergeVolumeMountList(&c.VolumeMounts, &secretVolumeMounts)
}
}
}
if r.NooBaa.Spec.ImagePullSecret == nil {
Expand Down Expand Up @@ -578,6 +586,17 @@ func (r *Reconciler) SetDesiredCoreApp() error {
}}
util.MergeVolumeList(&podSpec.Volumes, &configMapVolumes)
}
if r.ExternalPgSSLSecret != nil && util.KubeCheckQuiet(r.ExternalPgSSLSecret) {
secretVolumes := []corev1.Volume{{
Name: r.ExternalPgSSLSecret.Name,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: r.ExternalPgSSLSecret.Name,
},
},
}}
util.MergeVolumeList(&podSpec.Volumes, &secretVolumes)
}
return nil
}

Expand Down
18 changes: 18 additions & 0 deletions pkg/system/phase4_configuring.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,24 @@ func (r *Reconciler) setDesiredEndpointMounts(podSpec *corev1.PodSpec, container
util.MergeVolumeMountList(&container.VolumeMounts, &configMapVolumeMounts)
}

if r.ExternalPgSSLSecret != nil && util.KubeCheckQuiet(r.ExternalPgSSLSecret) {
secretVolumes := []corev1.Volume{{
Name: r.ExternalPgSSLSecret.Name,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: r.ExternalPgSSLSecret.Name,
},
},
}}
util.MergeVolumeList(&podSpec.Volumes, &secretVolumes)
secretVolumeMounts := []corev1.VolumeMount{{
Name: r.ExternalPgSSLSecret.Name,
MountPath: "/etc/external-db-secret",
ReadOnly: true,
}}
util.MergeVolumeMountList(&container.VolumeMounts, &secretVolumeMounts)
}

r.setDesiredRootMasterKeyMounts(podSpec, container)

for _, nsStore := range namespaceStoreList.Items {
Expand Down
20 changes: 15 additions & 5 deletions pkg/system/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ type Reconciler struct {
KedaTriggerAuthentication *kedav1alpha1.TriggerAuthentication
KedaScaled *kedav1alpha1.ScaledObject
AdapterHPA *autoscalingv2.HorizontalPodAutoscaler
ExternalPgSecret *corev1.Secret
ExternalPgSSLSecret *corev1.Secret
}

// NewReconciler initializes a reconciler to be used for loading or reconciling a noobaa system
Expand Down Expand Up @@ -392,19 +394,27 @@ func (r *Reconciler) Reconcile() (reconcile.Result, error) {
}

if r.NooBaa.Spec.ExternalPgSecret != nil {
secret := &corev1.Secret{
r.ExternalPgSecret = &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: r.NooBaa.Spec.ExternalPgSecret.Namespace,
Name: r.NooBaa.Spec.ExternalPgSecret.Name,
},
}
if !util.KubeCheck(secret) {
if !util.KubeCheck(r.ExternalPgSecret) {
log.Errorf("❌ External DB secret %q was not found or deleted", r.NooBaa.Spec.ExternalPgSecret.Name)
return res, nil
}
err = CheckPostgresURL(secret.StringData["db_url"])
if err != nil {
log.Errorf(`❌ %s`, err)
}

if r.NooBaa.Spec.ExternalPgSSLSecret != nil {
r.ExternalPgSSLSecret = &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: r.NooBaa.Spec.ExternalPgSSLSecret.Namespace,
Name: r.NooBaa.Spec.ExternalPgSSLSecret.Name,
},
}
if !util.KubeCheck(r.ExternalPgSSLSecret) {
log.Errorf("❌ External DB secret %q was not found or deleted", r.NooBaa.Spec.ExternalPgSecret.Name)
return res, nil
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ func CheckPostgresURL(postgresDbURL string) error {
// This is temporary checks - In next PRs we will change to psql client checks instead
u, err := url.Parse(postgresDbURL)
if err != nil {
return fmt.Errorf("failed parsing external DB url: %q", postgresDbURL)
return fmt.Errorf("failed parsing external DB url: %q, error: %s", postgresDbURL, err)
}
_, _, err = net.SplitHostPort(u.Host)
if err != nil {
Expand Down

0 comments on commit 72bc5c3

Please sign in to comment.