mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-15 17:51:03 +00:00
Added License Key secret support.
This commit is contained in:
parent
aa8eb3b057
commit
4f1e42198c
15 changed files with 210 additions and 92 deletions
File diff suppressed because one or more lines are too long
|
@ -26,6 +26,7 @@ import (
|
|||
"reflect"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
@ -54,6 +55,7 @@ type DeploymentSpec struct {
|
|||
ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"`
|
||||
DowntimeAllowed *bool `json:"downtimeAllowed,omitempty"`
|
||||
DisableIPv6 *bool `json:"disableIPv6,omitempty"`
|
||||
LicenseKey *string `json:"licenseKey,omitempty"`
|
||||
|
||||
ExternalAccess ExternalAccessSpec `json:"externalAccess"`
|
||||
RocksDB RocksDBSpec `json:"rocksdb"`
|
||||
|
@ -124,6 +126,20 @@ func (s DeploymentSpec) IsAuthenticated() bool {
|
|||
return s.Authentication.IsAuthenticated()
|
||||
}
|
||||
|
||||
// HasLicenseKey returns true if a license key secret name was set
|
||||
func (s DeploymentSpec) HasLicenseKey() bool {
|
||||
return s.LicenseKey != nil
|
||||
}
|
||||
|
||||
// GetLicenseKey returns the license key if set. Empty string otherwise.
|
||||
func (s DeploymentSpec) GetLicenseKey() string {
|
||||
if s.HasLicenseKey() {
|
||||
return *s.LicenseKey
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsSecure returns true when SSL is enabled
|
||||
func (s DeploymentSpec) IsSecure() bool {
|
||||
return s.TLS.IsSecure()
|
||||
|
@ -204,6 +220,9 @@ func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) {
|
|||
if s.DisableIPv6 == nil {
|
||||
s.DisableIPv6 = util.NewBoolOrNil(source.DisableIPv6)
|
||||
}
|
||||
if s.LicenseKey == nil {
|
||||
s.LicenseKey = util.NewStringOrNil(source.LicenseKey)
|
||||
}
|
||||
s.ExternalAccess.SetDefaultsFrom(source.ExternalAccess)
|
||||
s.RocksDB.SetDefaultsFrom(source.RocksDB)
|
||||
s.Authentication.SetDefaultsFrom(source.Authentication)
|
||||
|
@ -272,6 +291,11 @@ func (s *DeploymentSpec) Validate() error {
|
|||
if err := s.Chaos.Validate(); err != nil {
|
||||
return maskAny(errors.Wrap(err, "spec.chaos"))
|
||||
}
|
||||
if s.HasLicenseKey() {
|
||||
if err := k8sutil.ValidateResourceName(s.GetLicenseKey()); err != nil {
|
||||
return maskAny(errors.Wrap(err, "spec.licenseKey"))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -244,6 +244,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) {
|
|||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.LicenseKey != nil {
|
||||
in, out := &in.LicenseKey, &out.LicenseKey
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
in.ExternalAccess.DeepCopyInto(&out.ExternalAccess)
|
||||
in.RocksDB.DeepCopyInto(&out.RocksDB)
|
||||
in.Authentication.DeepCopyInto(&out.Authentication)
|
||||
|
|
|
@ -377,6 +377,6 @@ func (d *Deployment) DeleteSecret(secretName string) error {
|
|||
|
||||
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
|
||||
func (d *Deployment) GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
|
||||
agents api.MemberStatusList, id string) []string {
|
||||
return d.resources.GetExpectedPodArguments(apiObject, deplSpec, group, agents, id)
|
||||
agents api.MemberStatusList, id string, version driver.Version) []string {
|
||||
return d.resources.GetExpectedPodArguments(apiObject, deplSpec, group, agents, id, version)
|
||||
}
|
||||
|
|
|
@ -80,6 +80,12 @@ func (d *Deployment) inspectDeployment(lastInterval util.Interval) util.Interval
|
|||
d.CreateEvent(k8sutil.NewErrorEvent("Secret hash validation failed", err, d.apiObject))
|
||||
}
|
||||
|
||||
// Check for LicenseKeySecret
|
||||
if err := d.resources.ValidateLicenseKeySecret(); err != nil {
|
||||
hasError = true
|
||||
d.CreateEvent(k8sutil.NewErrorEvent("License Key Secret invalid", err, d.apiObject))
|
||||
}
|
||||
|
||||
// Is the deployment in a good state?
|
||||
status, _ := d.GetStatus()
|
||||
if status.Conditions.IsTrue(api.ConditionTypeSecretsChanged) {
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/arangod"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/constants"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
|
||||
)
|
||||
|
||||
|
@ -178,7 +179,14 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima
|
|||
tolerations = k8sutil.AddTolerationIfNotFound(tolerations, k8sutil.NewNoExecuteToleration(k8sutil.TolerationKeyNodeAlphaUnreachable, shortDur))
|
||||
serviceAccountName := ""
|
||||
|
||||
if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, podName, "", image, "", "", ib.Spec.GetImagePullPolicy(), "", false, terminationGracePeriod, args, nil, nil, nil, nil,
|
||||
env := make(map[string]k8sutil.EnvValue)
|
||||
if ib.Spec.HasLicenseKey() {
|
||||
env[constants.EnvArangoLicenseKey] = k8sutil.EnvValue{
|
||||
SecretName: ib.Spec.GetLicenseKey(),
|
||||
SecretKey: constants.SecretKeyToken,
|
||||
}
|
||||
}
|
||||
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, "", ""); err != nil {
|
||||
log.Debug().Err(err).Msg("Failed to create image ID pod")
|
||||
return true, maskAny(err)
|
||||
|
|
|
@ -97,7 +97,7 @@ func (a *actionCleanoutMember) CheckProgress(ctx context.Context) (bool, bool, e
|
|||
}
|
||||
// do not try to clean out a pod that was not initialized
|
||||
if !m.IsInitialized {
|
||||
return false, true, nil
|
||||
return true, false, nil
|
||||
}
|
||||
c, err := a.actionCtx.GetDatabaseClient(ctx)
|
||||
if err != nil {
|
||||
|
|
|
@ -92,5 +92,5 @@ type Context interface {
|
|||
DeleteSecret(secretName string) error
|
||||
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
|
||||
GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
|
||||
agents api.MemberStatusList, id string) []string
|
||||
agents api.MemberStatusList, id string, version driver.Version) []string
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ func createPlan(log zerolog.Logger, apiObject k8sutil.APIObject,
|
|||
newPlan = createUpgradeMemberPlan(log, m, group, "Version upgrade", spec.GetImage(), status)
|
||||
} else {
|
||||
// Upgrade is not needed, see if rotation is needed
|
||||
if rotNeeded, reason := podNeedsRotation(log, *p, apiObject, spec, group, status.Members.Agents, m.ID, context); rotNeeded {
|
||||
if rotNeeded, reason := podNeedsRotation(log, *p, apiObject, spec, group, status, m.ID, context); rotNeeded {
|
||||
newPlan = createRotateMemberPlan(log, m, group, reason)
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ func podNeedsUpgrading(p v1.Pod, spec api.DeploymentSpec, images api.ImageInfoLi
|
|||
// given deployment spec.
|
||||
// When true is returned, a reason for the rotation is already returned.
|
||||
func podNeedsRotation(log zerolog.Logger, p v1.Pod, apiObject metav1.Object, spec api.DeploymentSpec,
|
||||
group api.ServerGroup, agents api.MemberStatusList, id string,
|
||||
group api.ServerGroup, status api.DeploymentStatus, id string,
|
||||
context PlanBuilderContext) (bool, string) {
|
||||
groupSpec := spec.GetServerGroupSpec(group)
|
||||
|
||||
|
@ -319,8 +319,13 @@ func podNeedsRotation(log zerolog.Logger, p v1.Pod, apiObject metav1.Object, spe
|
|||
return true, "Server container not found"
|
||||
}
|
||||
|
||||
podImageInfo, found := status.Images.GetByImageID(c.Image)
|
||||
if !found {
|
||||
return false, "Server Image not found"
|
||||
}
|
||||
|
||||
// Check arguments
|
||||
expectedArgs := strings.Join(context.GetExpectedPodArguments(apiObject, spec, group, agents, id), " ")
|
||||
expectedArgs := strings.Join(context.GetExpectedPodArguments(apiObject, spec, group, status.Members.Agents, id, podImageInfo.ArangoDBVersion), " ")
|
||||
actualArgs := strings.Join(getContainerArgs(c), " ")
|
||||
if expectedArgs != actualArgs {
|
||||
log.Debug().
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
package reconcile
|
||||
|
||||
import (
|
||||
driver "github.com/arangodb/go-driver"
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
|
||||
"k8s.io/api/core/v1"
|
||||
|
@ -44,7 +45,7 @@ type PlanBuilderContext interface {
|
|||
GetPvc(pvcName string) (*v1.PersistentVolumeClaim, error)
|
||||
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
|
||||
GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
|
||||
agents api.MemberStatusList, id string) []string
|
||||
agents api.MemberStatusList, id string, version driver.Version) []string
|
||||
}
|
||||
|
||||
// newPlanBuilderContext creates a PlanBuilderContext from the given context
|
||||
|
|
51
pkg/deployment/resources/license.go
Normal file
51
pkg/deployment/resources/license.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package resources
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/constants"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ValidateLicenseKeySecret checks if the licens key secret exists and is valid
|
||||
func (r *Resources) ValidateLicenseKeySecret() error {
|
||||
spec := r.context.GetSpec()
|
||||
|
||||
if spec.HasLicenseKey() {
|
||||
secretName := spec.GetLicenseKey()
|
||||
|
||||
kubecli := r.context.GetKubeCli()
|
||||
ns := r.context.GetNamespace()
|
||||
s, err := kubecli.CoreV1().Secrets(ns).Get(secretName, metav1.GetOptions{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := s.Data[constants.SecretKeyToken]; !ok {
|
||||
return fmt.Errorf("Invalid secret format")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -63,7 +63,7 @@ func (o optionPair) CompareTo(other optionPair) int {
|
|||
|
||||
// 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, autoUpgrade bool) []string {
|
||||
agents api.MemberStatusList, id string, version driver.Version, autoUpgrade bool) []string {
|
||||
options := make([]optionPair, 0, 64)
|
||||
svrSpec := deplSpec.GetServerGroupSpec(group)
|
||||
|
||||
|
@ -487,7 +487,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
|
|||
if autoUpgrade {
|
||||
newPhase = api.MemberPhaseUpgrading
|
||||
}
|
||||
args := createArangodArgs(apiObject, spec, group, status.Members.Agents, m.ID, autoUpgrade)
|
||||
args := createArangodArgs(apiObject, spec, group, status.Members.Agents, m.ID, imageInfo.ArangoDBVersion, autoUpgrade)
|
||||
env := make(map[string]k8sutil.EnvValue)
|
||||
livenessProbe, err := r.createLivenessProbe(spec, group)
|
||||
if err != nil {
|
||||
|
@ -525,6 +525,14 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
|
|||
SecretKey: constants.SecretKeyToken,
|
||||
}
|
||||
}
|
||||
|
||||
if spec.HasLicenseKey() {
|
||||
env[constants.EnvArangoLicenseKey] = k8sutil.EnvValue{
|
||||
SecretName: spec.GetLicenseKey(),
|
||||
SecretKey: constants.SecretKeyToken,
|
||||
}
|
||||
}
|
||||
|
||||
engine := spec.GetStorageEngine().AsArangoArgument()
|
||||
requireUUID := group == api.ServerGroupDBServers && m.IsInitialized
|
||||
finalizers := r.createPodFinalizers(group)
|
||||
|
@ -591,6 +599,12 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, memberID string,
|
|||
SecretKey: constants.SecretKeyToken,
|
||||
}
|
||||
}
|
||||
if spec.HasLicenseKey() {
|
||||
env[constants.EnvArangoLicenseKey] = k8sutil.EnvValue{
|
||||
SecretName: spec.GetLicenseKey(),
|
||||
SecretKey: constants.SecretKeyToken,
|
||||
}
|
||||
}
|
||||
livenessProbe, err := r.createLivenessProbe(spec, group)
|
||||
if err != nil {
|
||||
return maskAny(err)
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
driver "github.com/arangodb/go-driver"
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha"
|
||||
"github.com/arangodb/kube-arangodb/pkg/metrics"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
|
@ -266,9 +267,9 @@ func (r *Resources) InspectPods(ctx context.Context) (util.Interval, error) {
|
|||
|
||||
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
|
||||
func (r *Resources) GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
|
||||
agents api.MemberStatusList, id string) []string {
|
||||
agents api.MemberStatusList, id string, version driver.Version) []string {
|
||||
if group.IsArangod() {
|
||||
return createArangodArgs(apiObject, deplSpec, group, agents, id, false)
|
||||
return createArangodArgs(apiObject, deplSpec, group, agents, id, version, false)
|
||||
}
|
||||
if group.IsArangosync() {
|
||||
groupSpec := deplSpec.GetServerGroupSpec(group)
|
||||
|
|
|
@ -55,5 +55,7 @@ func (o *Operator) waitForCRD(enableDeployment, enableDeploymentReplication, ena
|
|||
}
|
||||
}
|
||||
|
||||
log.Debug().Msg("CRDs ready")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ const (
|
|||
EnvOperatorPodNamespace = "MY_POD_NAMESPACE"
|
||||
EnvOperatorPodIP = "MY_POD_IP"
|
||||
|
||||
EnvArangoLicenseKey = "ARANGO_LICENSE_KEY" // Contains the License Key for the Docker Image
|
||||
EnvArangodJWTSecret = "ARANGOD_JWT_SECRET" // Contains JWT secret for the ArangoDB cluster
|
||||
EnvArangoSyncMonitoringToken = "ARANGOSYNC_MONITORING_TOKEN" // Constains monitoring token for ArangoSync servers
|
||||
|
||||
|
|
Loading…
Reference in a new issue