Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use jwt-keyfile option if available. #318

Merged
merged 4 commits into from
Jan 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 65 additions & 65 deletions dashboard/assets.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pkg/deployment/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima
}
}
if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, podName, "", image, "", "", ib.Spec.GetImagePullPolicy(), "", false, terminationGracePeriod, args, env, nil, nil, nil,
tolerations, serviceAccountName, "", "", nil); err != nil {
tolerations, serviceAccountName, "", "", "", nil); err != nil {
log.Debug().Err(err).Msg("Failed to create image ID pod")
return true, maskAny(err)
}
Expand Down
36 changes: 18 additions & 18 deletions pkg/deployment/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
case api.ServerGroupSingle:
log.Debug().Str("id", id).Msg("Adding single server")
if err := status.Members.Add(api.MemberStatus{
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
PersistentVolumeClaimName: k8sutil.CreatePersistentVolumeClaimName(deploymentName, role, id),
PodName: "",
}, group); err != nil {
Expand All @@ -101,9 +101,9 @@ func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
case api.ServerGroupAgents:
log.Debug().Str("id", id).Msg("Adding agent")
if err := status.Members.Add(api.MemberStatus{
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
PersistentVolumeClaimName: k8sutil.CreatePersistentVolumeClaimName(deploymentName, role, id),
PodName: "",
}, group); err != nil {
Expand All @@ -112,9 +112,9 @@ func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
case api.ServerGroupDBServers:
log.Debug().Str("id", id).Msg("Adding dbserver")
if err := status.Members.Add(api.MemberStatus{
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
PersistentVolumeClaimName: k8sutil.CreatePersistentVolumeClaimName(deploymentName, role, id),
PodName: "",
}, group); err != nil {
Expand All @@ -123,9 +123,9 @@ func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
case api.ServerGroupCoordinators:
log.Debug().Str("id", id).Msg("Adding coordinator")
if err := status.Members.Add(api.MemberStatus{
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
PersistentVolumeClaimName: "",
PodName: "",
}, group); err != nil {
Expand All @@ -134,9 +134,9 @@ func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
case api.ServerGroupSyncMasters:
log.Debug().Str("id", id).Msg("Adding syncmaster")
if err := status.Members.Add(api.MemberStatus{
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
PersistentVolumeClaimName: "",
PodName: "",
}, group); err != nil {
Expand All @@ -145,9 +145,9 @@ func createMember(log zerolog.Logger, status *api.DeploymentStatus, group api.Se
case api.ServerGroupSyncWorkers:
log.Debug().Str("id", id).Msg("Adding syncworker")
if err := status.Members.Add(api.MemberStatus{
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
ID: id,
CreatedAt: metav1.Now(),
Phase: api.MemberPhaseNone,
PersistentVolumeClaimName: "",
PodName: "",
}, group); err != nil {
Expand Down
48 changes: 41 additions & 7 deletions pkg/deployment/resources/pod_creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ func versionHasAdvertisedEndpoint(v driver.Version) bool {
return v.CompareTo("3.4.0") >= 0
}

// versionHasJWTSecretKeyfile derives from the version number of arangod has
// the option --auth.jwt-secret-keyfile which can take the JWT secret from
// a file in the file system.
func versionHasJWTSecretKeyfile(v driver.Version) bool {
if v.CompareTo("3.3.22") >= 0 && v.CompareTo("3.4.0") < 0 {
return true
}
if v.CompareTo("3.4.2") >= 0 {
return true
}

return false
}

// createArangodArgs creates command line arguments for an arangod server in the given group.
func createArangodArgs(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
agents api.MemberStatusList, id string, version driver.Version, autoUpgrade bool) []string {
Expand All @@ -85,8 +99,17 @@ func createArangodArgs(apiObject metav1.Object, deplSpec api.DeploymentSpec, gro
// With authentication
options = append(options,
optionPair{"--server.authentication", "true"},
optionPair{"--server.jwt-secret", "$(" + constants.EnvArangodJWTSecret + ")"},
)
if versionHasJWTSecretKeyfile(version) {
keyPath := filepath.Join(k8sutil.ClusterJWTSecretVolumeMountDir, constants.SecretKeyToken)
options = append(options,
optionPair{"--server.jwt-secret-keyfile", keyPath},
)
} else {
options = append(options,
optionPair{"--server.jwt-secret", "$(" + constants.EnvArangodJWTSecret + ")"},
)
}
} else {
// Without authentication
options = append(options,
Expand Down Expand Up @@ -499,17 +522,18 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
// Create pod
if group.IsArangod() {
// Prepare arguments
version := imageInfo.ArangoDBVersion
autoUpgrade := m.Conditions.IsTrue(api.ConditionTypeAutoUpgrade)
if autoUpgrade {
newPhase = api.MemberPhaseUpgrading
}
args := createArangodArgs(apiObject, spec, group, status.Members.Agents, m.ID, imageInfo.ArangoDBVersion, autoUpgrade)
args := createArangodArgs(apiObject, spec, group, status.Members.Agents, m.ID, version, autoUpgrade)
env := make(map[string]k8sutil.EnvValue)
livenessProbe, err := r.createLivenessProbe(spec, group)
if err != nil {
return maskAny(err)
}
readinessProbe, err := r.createReadinessProbe(spec, group, imageInfo.ArangoDBVersion)
readinessProbe, err := r.createReadinessProbe(spec, group, version)
if err != nil {
return maskAny(err)
}
Expand All @@ -535,11 +559,21 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
return maskAny(errors.Wrapf(err, "RocksDB encryption key secret validation failed"))
}
}
// Check cluster JWT secret
var clusterJWTSecretName string
if spec.IsAuthenticated() {
env[constants.EnvArangodJWTSecret] = k8sutil.EnvValue{
SecretName: spec.Authentication.GetJWTSecretName(),
SecretKey: constants.SecretKeyToken,
if versionHasJWTSecretKeyfile(version) {
clusterJWTSecretName = spec.Authentication.GetJWTSecretName()
if err := k8sutil.ValidateTokenSecret(secrets, clusterJWTSecretName); err != nil {
return maskAny(errors.Wrapf(err, "Cluster JWT secret validation failed"))
}
} else {
env[constants.EnvArangodJWTSecret] = k8sutil.EnvValue{
SecretName: spec.Authentication.GetJWTSecretName(),
SecretKey: constants.SecretKeyToken,
}
}

}

if spec.License.HasSecretName() {
Expand All @@ -554,7 +588,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
finalizers := r.createPodFinalizers(group)
if err := k8sutil.CreateArangodPod(kubecli, spec.IsDevelopment(), apiObject, role, m.ID, m.PodName, m.PersistentVolumeClaimName, imageInfo.ImageID, lifecycleImage, alpineImage, spec.GetImagePullPolicy(),
engine, requireUUID, terminationGracePeriod, args, env, finalizers, livenessProbe, readinessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, rocksdbEncryptionSecretName,
groupSpec.GetNodeSelector()); err != nil {
clusterJWTSecretName, groupSpec.GetNodeSelector()); err != nil {
return maskAny(err)
}
log.Debug().Str("pod-name", m.PodName).Msg("Created pod")
Expand Down
4 changes: 2 additions & 2 deletions pkg/logging/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ var (
// The defaultLevels list is used during development to increase the
// default level for components that we care a little less about.
defaultLevels = map[string]string{
//"operator": "info",
//"something.status": "info",
//"operator": "info",
//"something.status": "info",
}
)

Expand Down
4 changes: 2 additions & 2 deletions pkg/operator/operator_deployment_relication.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (o *Operator) onDeleteArangoDeploymentReplication(obj interface{}) {
Str("name", apiObject.GetObjectMeta().GetName()).
Msg("ArangoDeploymentReplication deleted")
ev := &Event{
Type: kwatch.Deleted,
Type: kwatch.Deleted,
DeploymentReplication: apiObject,
}

Expand All @@ -124,7 +124,7 @@ func (o *Operator) onDeleteArangoDeploymentReplication(obj interface{}) {
// syncArangoDeploymentReplication synchronized the given deployment replication.
func (o *Operator) syncArangoDeploymentReplication(apiObject *api.ArangoDeploymentReplication) {
ev := &Event{
Type: kwatch.Added,
Type: kwatch.Added,
DeploymentReplication: apiObject,
}
// re-watch or restart could give ADD event.
Expand Down
2 changes: 1 addition & 1 deletion pkg/replication/deployment_replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func New(config Config, deps Dependencies, apiObject *api.ArangoDeploymentReplic
// This sends an update event in the event queue.
func (dr *DeploymentReplication) Update(apiObject *api.ArangoDeploymentReplication) {
dr.send(&deploymentReplicationEvent{
Type: eventArangoDeploymentReplicationUpdated,
Type: eventArangoDeploymentReplicationUpdated,
DeploymentReplication: apiObject,
})
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/storage/pv_creator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func TestGetDeploymentInfo(t *testing.T) {
ExpectedEnforceAntiAffinity bool
}{
{
Input: v1.PersistentVolumeClaim{},
Input: v1.PersistentVolumeClaim{},
ExpectedDeploymentName: "",
ExpectedRole: "",
ExpectedEnforceAntiAffinity: false,
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/pvc_informer.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ func (ls *LocalStorage) listenForPvcEvents() {
AddFunc: func(obj interface{}) {
if pvc, ok := getPvc(obj); ok {
ls.send(&localStorageEvent{
Type: eventPVCAdded,
Type: eventPVCAdded,
PersistentVolumeClaim: pvc,
})
}
},
UpdateFunc: func(oldObj, newObj interface{}) {
if pvc, ok := getPvc(newObj); ok {
ls.send(&localStorageEvent{
Type: eventPVCUpdated,
Type: eventPVCUpdated,
PersistentVolumeClaim: pvc,
})
}
Expand Down
19 changes: 18 additions & 1 deletion pkg/util/k8sutil/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
rocksdbEncryptionVolumeName = "rocksdb-encryption"
ArangodVolumeMountDir = "/data"
RocksDBEncryptionVolumeMountDir = "/secrets/rocksdb/encryption"
JWTSecretFileVolumeMountDir = "/secrets/jwt"
TLSKeyfileVolumeMountDir = "/secrets/tls"
LifecycleVolumeMountDir = "/lifecycle/tools"
ClientAuthCAVolumeMountDir = "/secrets/client-auth/ca"
Expand Down Expand Up @@ -417,7 +418,7 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy
engine string, requireUUID bool, terminationGracePeriod time.Duration,
args []string, env map[string]EnvValue, finalizers []string,
livenessProbe *HTTPProbeConfig, readinessProbe *HTTPProbeConfig, tolerations []v1.Toleration, serviceAccountName string,
tlsKeyfileSecretName, rocksdbEncryptionSecretName string, nodeSelector map[string]string) error {
tlsKeyfileSecretName, rocksdbEncryptionSecretName string, clusterJWTSecretName string, nodeSelector map[string]string) error {
// Prepare basic pod
p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, finalizers, tolerations, serviceAccountName, nodeSelector)
terminationGracePeriodSeconds := int64(math.Ceil(terminationGracePeriod.Seconds()))
Expand Down Expand Up @@ -447,6 +448,9 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy
if rocksdbEncryptionSecretName != "" {
c.VolumeMounts = append(c.VolumeMounts, rocksdbEncryptionVolumeMounts()...)
}
if clusterJWTSecretName != "" {
c.VolumeMounts = append(c.VolumeMounts, clusterJWTVolumeMounts()...)
}
p.Spec.Containers = append(p.Spec.Containers, c)

// Add UUID init container
Expand Down Expand Up @@ -503,6 +507,19 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy
p.Spec.Volumes = append(p.Spec.Volumes, vol)
}

// Cluster JWT secret mount (if any)
if clusterJWTSecretName != "" {
vol := v1.Volume{
Name: clusterJWTSecretVolumeName,
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{
SecretName: clusterJWTSecretName,
},
},
}
p.Spec.Volumes = append(p.Spec.Volumes, vol)
}

// Lifecycle volumes (if any)
p.Spec.Volumes = append(p.Spec.Volumes, lifecycleVolumes...)

Expand Down