Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
Support password authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Schlicht committed Apr 17, 2020
1 parent 535fbd6 commit b3752d8
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 9 deletions.
4 changes: 4 additions & 0 deletions operator/params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ parameters:
description: "Authentication backend, implementing IAuthenticator; used to identify users."
default: "AllowAllAuthenticator"

- name: AUTHENTICATION_CREDENTIALS_SECRET
description: "Secret containing the credentials used by the operator when running 'nodetool' for its functionality. Only relevant if AUTHENTICATOR is set to 'PasswordAuthenticator'. The secret needs to have a 'username' and a 'password' entry."
default: ""

- name: AUTHORIZER
description: "Authorization backend, implementing IAuthorizer; used to limit access/provide permissions."
default: "AllowAllAuthorizer"
Expand Down
6 changes: 4 additions & 2 deletions operator/templates/node-scripts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ metadata:
name: {{ .Name }}-node-scripts
namespace: {{ .Namespace }}
data:
node-drain.sh: |
nodetool {{ if .Params.AUTHENTICATION_CREDENTIALS_SECRET }}-u $(cat /etc/cassandra/authentication/username) -pw $(cat /etc/cassandra/authentication/password){{ end }} drain
node-readiness-probe.sh: |
nodetool status -p {{ .Params.JMX_PORT }} | grep -q "UN ${POD_IP}"
nodetool {{ if .Params.AUTHENTICATION_CREDENTIALS_SECRET }}-u $(cat /etc/cassandra/authentication/username) -pw $(cat /etc/cassandra/authentication/password){{ end }} status -p {{ .Params.JMX_PORT }} | grep -q "UN ${POD_IP}"
node-liveness-probe.sh: |
nodetool info
nodetool {{ if .Params.AUTHENTICATION_CREDENTIALS_SECRET }}-u $(cat /etc/cassandra/authentication/username) -pw $(cat /etc/cassandra/authentication/password){{ end }} info
generate-rackdc-properties.sh: |
# Generate the rackdc-properties
RACK=`kubectl get node -L$RACKLABEL | grep ${NODE_NAME} | awk '{print $6}'`
Expand Down
6 changes: 3 additions & 3 deletions operator/templates/repair-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ spec:
spec:
containers:
- name: repair-job
image: bitnami/kubectl:1.18.0
command: [ "kubectl", "exec", "{{ $.Params.REPAIR_POD }}", "--", "nodetool", "repair" ]
image: bitnami/kubectl:latest
command: ["/bin/bash"]
args: [ "-c", "kubectl exec {{ $.Params.REPAIR_POD }} -- nodetool {{ if $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}-u $(cat /etc/cassandra/authentication/username) -pw $(cat /etc/cassandra/authentication/password){{ end }} repair"]
restartPolicy: Never
serviceAccountName: {{ .Name }}-node-repairer
17 changes: 15 additions & 2 deletions operator/templates/stateful-set.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ spec:
preStop:
exec:
command:
- nodetool
- drain
- /bin/bash
- /etc/cassandra/node-drain.sh
readinessProbe:
exec:
command:
Expand Down Expand Up @@ -222,6 +222,9 @@ spec:
- name: jvm-options
mountPath: /etc/cassandra/jvm.options
subPath: jvm.options
- name: node-scripts
mountPath: /etc/cassandra/node-drain.sh
subPath: node-drain.sh
- name: node-scripts
mountPath: /etc/cassandra/node-readiness-probe.sh
subPath: node-readiness-probe.sh
Expand All @@ -239,6 +242,11 @@ spec:
- name: generate-tls-artifacts
mountPath: /etc/tls/bin
{{ end }}
{{ if $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
- name: {{ $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
mountPath: /etc/cassandra/authentication
readOnly: true
{{ end }}
{{ if eq $.Params.PROMETHEUS_EXPORTER_ENABLED "true" }}
- name: prometheus-exporter
image: {{ $.Params.PROMETHEUS_EXPORTER_DOCKER_IMAGE }}
Expand Down Expand Up @@ -356,6 +364,11 @@ spec:
name: {{ $.Name }}-generate-tls-artifacts-sh
defaultMode: 0755
{{ end }}
{{ if $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
- name: {{ $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
secret:
secretName: {{ $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
{{ end }}
volumeClaimTemplates:
- metadata:
name: var-lib-cassandra
Expand Down
4 changes: 4 additions & 0 deletions templates/operator/params.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ parameters:
description: "Authentication backend, implementing IAuthenticator; used to identify users."
default: "AllowAllAuthenticator"

- name: AUTHENTICATION_CREDENTIALS_SECRET
description: "Secret containing the credentials used by the operator when running 'nodetool' for its functionality. Only relevant if AUTHENTICATOR is set to 'PasswordAuthenticator'. The secret needs to have a 'username' and a 'password' entry."
default: ""

- name: AUTHORIZER
description: "Authorization backend, implementing IAuthorizer; used to limit access/provide permissions."
default: "AllowAllAuthorizer"
Expand Down
17 changes: 15 additions & 2 deletions templates/operator/templates/stateful-set.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ spec:
preStop:
exec:
command:
- nodetool
- drain
- /bin/bash
- /etc/cassandra/node-drain.sh
readinessProbe:
exec:
command:
Expand Down Expand Up @@ -222,6 +222,9 @@ spec:
- name: jvm-options
mountPath: /etc/cassandra/jvm.options
subPath: jvm.options
- name: node-scripts
mountPath: /etc/cassandra/node-drain.sh
subPath: node-drain.sh
- name: node-scripts
mountPath: /etc/cassandra/node-readiness-probe.sh
subPath: node-readiness-probe.sh
Expand All @@ -239,6 +242,11 @@ spec:
- name: generate-tls-artifacts
mountPath: /etc/tls/bin
{{ end }}
{{ if $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
- name: {{ $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
mountPath: /etc/cassandra/authentication
readOnly: true
{{ end }}
{{ if eq $.Params.PROMETHEUS_EXPORTER_ENABLED "true" }}
- name: prometheus-exporter
image: {{ $.Params.PROMETHEUS_EXPORTER_DOCKER_IMAGE }}
Expand Down Expand Up @@ -356,6 +364,11 @@ spec:
name: {{ $.Name }}-generate-tls-artifacts-sh
defaultMode: 0755
{{ end }}
{{ if $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
- name: {{ $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
secret:
secretName: {{ $.Params.AUTHENTICATION_CREDENTIALS_SECRET }}
{{ end }}
volumeClaimTemplates:
- metadata:
name: var-lib-cassandra
Expand Down
5 changes: 5 additions & 0 deletions tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1Gn
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
Expand All @@ -39,6 +40,7 @@ github.com/alecthomas/gometalinter v3.0.0+incompatible/go.mod h1:qfIpQGGz3d+Nmgy
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053 h1:H/GMMKYPkEIC3DF/JWQz8Pdd+Feifov2EIgGfNpeogI=
github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053/go.mod h1:xW8sBma2LE3QxFSzCnH9qe6gAE2yO9GvQaWwX89HxbE=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
Expand Down Expand Up @@ -332,6 +334,7 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
Expand Down Expand Up @@ -561,6 +564,7 @@ gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20191106092431-e228e37189d3 h1:ho4SukHOmqjp7XHH7nPNx7GcgDK6ObVflhAQAT7MvpE=
gopkg.in/yaml.v3 v3.0.0-20191106092431-e228e37189d3/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
Expand Down Expand Up @@ -607,6 +611,7 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
sigs.k8s.io/controller-runtime v0.5.1 h1:TNidCfVoU/cs2i+9xoTcL/l7yhl0bDhYXU0NCG6wmiE=
sigs.k8s.io/controller-runtime v0.5.1/go.mod h1:Uojny7gvg55YLQnEGnPzRE3dC4ik2tRlZJgOUCWXAV4=
sigs.k8s.io/controller-tools v0.2.6/go.mod h1:9VKHPszmf2DHz/QmHkcfZoewO6BL7pPs9uAiBVsaJSE=
sigs.k8s.io/kind v0.6.1 h1:13zGO85bX34eyJFQWilTWyuqncRAhCaHoffF9vPuYbg=
sigs.k8s.io/kind v0.6.1/go.mod h1:dhW5h0O4PRVq8B6eExphIa9mBnrlBzxEz3R/P1YcYj0=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
Expand Down
111 changes: 111 additions & 0 deletions tests/suites/authentication/authentication_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package authentication

import (
"fmt"
"os"
"testing"
"time"

testclient "github.com/kudobuilder/test-tools/pkg/client"
"github.com/kudobuilder/test-tools/pkg/kubernetes"
"github.com/kudobuilder/test-tools/pkg/kudo"
. "github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/reporters"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/api/errors"

"github.com/mesosphere/kudo-cassandra-operator/tests/cassandra"
)

var (
kubeConfigPath = os.Getenv("KUBECONFIG")
operatorName = os.Getenv("OPERATOR_NAME")
operatorDirectory = os.Getenv("OPERATOR_DIRECTORY")

instanceName = fmt.Sprintf("%s-instance", operatorName)
testNamespace = "authentication"
)

var _ = Describe("Authentication tests", func() {
var (
client testclient.Client
credentials kubernetes.Secret
operator kudo.Operator
)

AfterEach(func() {
err := operator.Uninstall()
Expect(err).NotTo(HaveOccurred())

err = credentials.Delete()
Expect(err).NotTo(HaveOccurred())

err = kubernetes.DeleteNamespace(client, testNamespace)
Expect(err).NotTo(HaveOccurred())
})

Context("when using the 'PasswordAuthenticator'", func() {
It("should authenticate 'nodetool' calls", func() {
var err error

client, err = testclient.NewForConfig(kubeConfigPath)
Expect(err).NotTo(HaveOccurred())

By("Setting up namespace")
err = kubernetes.CreateNamespace(client, testNamespace)
if !errors.IsAlreadyExists(err) {
Expect(err).NotTo(HaveOccurred())
}

By("Adding a secret containing the default user credentials")
const secretName = "authn-credentials" ////nolint:gosec

credentials, err = kubernetes.CreateSecret(secretName).
WithNamespace(testNamespace).
WithStringData(map[string]string{
"username": "cassandra",
"password": "cassandra",
}).
Do(client)
Expect(err).NotTo(HaveOccurred())

By("Installing the operator with 'PasswordAuthenticator'")
parameters := map[string]string{
"AUTHENTICATOR": "PasswordAuthenticator",
"AUTHENTICATION_CREDENTIALS_SECRET": secretName,
}

operator, err = kudo.InstallOperator(operatorDirectory).
WithNamespace(testNamespace).
WithInstance(instanceName).
WithParameters(parameters).
Do(client)
Expect(err).NotTo(HaveOccurred())

err = operator.Instance.WaitForPlanComplete("deploy", kudo.WaitTimeout(time.Minute*10))
Expect(err).NotTo(HaveOccurred())

By("Triggering a Cassandra node repair which uses 'nodetool'")
podName, err := cassandra.FirstPodName(operator.Instance)
Expect(err).To(BeNil())

err = operator.Instance.UpdateParameters(map[string]string{
"REPAIR_POD": podName,
})
Expect(err).To(BeNil())

err = operator.Instance.WaitForPlanComplete("repair-pod")
Expect(err).To(BeNil())

repair, err := cassandra.NodeWasRepaired(client, operator.Instance)
Expect(err).To(BeNil())
Expect(repair).To(BeTrue())
})
})
})

func TestService(t *testing.T) {
RegisterFailHandler(Fail)
junitReporter := reporters.NewJUnitReporter("authentication-test-junit.xml")
RunSpecsWithDefaultAndCustomReporters(t, "Authentication tests", []Reporter{junitReporter})
}

0 comments on commit b3752d8

Please sign in to comment.