mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
[Feature] [ML] Enable TLS (#1657)
This commit is contained in:
parent
687f649507
commit
1a81cf4e89
7 changed files with 549 additions and 4 deletions
|
@ -9,6 +9,7 @@
|
|||
- (Feature) (ML) Unify API
|
||||
- (Feature) (ML) Add TLS Secrets
|
||||
- (Feature) (ML) Allow to change API port
|
||||
- (Feature) (ML) Enable TLS
|
||||
|
||||
## [1.2.40](https://github.com/arangodb/kube-arangodb/tree/1.2.40) (2024-04-10)
|
||||
- (Feature) Add Core fields to the Scheduler Container Spec
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2023-2024 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.
|
||||
|
@ -32,6 +32,7 @@ const (
|
|||
ExtensionMetadataServiceValidCondition api.ConditionType = "MetadataServiceValid"
|
||||
ExtensionServiceAccountReadyCondition api.ConditionType = "ServiceAccountReady"
|
||||
ExtensionStatefulSetReadyCondition api.ConditionType = "ExtensionDeploymentReady"
|
||||
ExtensionTLSEnabledCondition api.ConditionType = "TLSEnabled"
|
||||
LicenseValidCondition api.ConditionType = "LicenseValid"
|
||||
CronJobSyncedCondition api.ConditionType = "CronJobSynced"
|
||||
BatchJobSyncedCondition api.ConditionType = "BatchJobSynced"
|
||||
|
|
|
@ -27,3 +27,19 @@ type ArangoMLExtensionSpecDeploymentTLS struct {
|
|||
// AltNames define TLS AltNames used when TLS on the ArangoDB is enabled
|
||||
AltNames []string `json:"altNames,omitempty"`
|
||||
}
|
||||
|
||||
func (a *ArangoMLExtensionSpecDeploymentTLS) IsEnabled() bool {
|
||||
if a == nil || a.Enabled == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return *a.Enabled
|
||||
}
|
||||
|
||||
func (a *ArangoMLExtensionSpecDeploymentTLS) GetAltNames() []string {
|
||||
if a == nil || a.AltNames == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return a.AltNames
|
||||
}
|
||||
|
|
244
pkg/util/k8sutil/helpers/updator.go
Normal file
244
pkg/util/k8sutil/helpers/updator.go
Normal file
|
@ -0,0 +1,244 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 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 helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/logging"
|
||||
operator "github.com/arangodb/kube-arangodb/pkg/operatorV2"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors"
|
||||
)
|
||||
|
||||
type Action int
|
||||
|
||||
func (a Action) Or(b Action) Action {
|
||||
if b > a {
|
||||
return b
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
const (
|
||||
ActionOK Action = iota
|
||||
ActionReplace
|
||||
ActionUpdate
|
||||
)
|
||||
|
||||
type Object interface {
|
||||
comparable
|
||||
meta.Object
|
||||
}
|
||||
|
||||
type Client[T Object] interface {
|
||||
Get(ctx context.Context, name string, options meta.GetOptions) (T, error)
|
||||
Update(ctx context.Context, object T, options meta.UpdateOptions) (T, error)
|
||||
Create(ctx context.Context, object T, options meta.CreateOptions) (T, error)
|
||||
Delete(ctx context.Context, name string, options meta.DeleteOptions) error
|
||||
}
|
||||
|
||||
type Generate[T Object] func(ctx context.Context, ref *sharedApi.Object) (T, bool, string, error)
|
||||
|
||||
func OperatorUpdate[T Object](ctx context.Context, logger logging.Logger, client Client[T], ref **sharedApi.Object, generator Generate[T], decisions ...Decision[T]) (bool, error) {
|
||||
changed, err := Update[T](ctx, logger, client, ref, generator, decisions...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if changed {
|
||||
return true, operator.Reconcile("Change in resources")
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func Update[T Object](ctx context.Context, logger logging.Logger, client Client[T], ref **sharedApi.Object, generator Generate[T], decisions ...Decision[T]) (bool, error) {
|
||||
decision := Decision[T](EmptyDecision[T]).With(decisions...)
|
||||
|
||||
if ref == nil {
|
||||
return false, errors.Errorf("Reference is nil")
|
||||
}
|
||||
|
||||
currentRef := *ref
|
||||
|
||||
var discoveredObject T
|
||||
var discoveredObjectExists bool
|
||||
|
||||
if currentRef != nil {
|
||||
object, err := util.WithKubernetesContextTimeoutP2A2(ctx, client.Get, currentRef.GetName(), meta.GetOptions{})
|
||||
if err != nil {
|
||||
if !kerrors.Is(err, kerrors.NotFound) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
*ref = nil
|
||||
logger.
|
||||
Str("name", currentRef.GetName()).
|
||||
Str("checksum", currentRef.GetChecksum()).
|
||||
Str("uid", string(currentRef.GetUID())).
|
||||
Debug("Object has been removed")
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if object.GetDeletionTimestamp() != nil {
|
||||
// Object is currently deleting
|
||||
logger.
|
||||
Str("name", currentRef.GetName()).
|
||||
Str("checksum", currentRef.GetChecksum()).
|
||||
Str("uid", string(currentRef.GetUID())).
|
||||
Debug("Object is currently deleting")
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if object.GetUID() != currentRef.GetUID() {
|
||||
logger.
|
||||
Str("name", currentRef.GetName()).
|
||||
Str("checksum", currentRef.GetChecksum()).
|
||||
Str("uid", string(currentRef.GetUID())).
|
||||
Warn("Recreation Required as UID changed")
|
||||
|
||||
if err := util.WithKubernetesContextTimeoutP1A2(ctx, client.Delete, currentRef.GetName(), meta.DeleteOptions{}); err != nil {
|
||||
if !kerrors.Is(err, kerrors.NotFound) {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
discoveredObject = object
|
||||
discoveredObjectExists = true
|
||||
}
|
||||
|
||||
object, skip, checksum, err := generator(ctx, currentRef.DeepCopy())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if skip {
|
||||
// Skip update as it is not required
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if object == util.Default[T]() {
|
||||
// Object is supposed to be removed
|
||||
if currentRef == nil {
|
||||
// Nothing to do
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Remove object
|
||||
if err := util.WithKubernetesContextTimeoutP1A2(ctx, client.Delete, currentRef.GetName(), meta.DeleteOptions{}); err != nil {
|
||||
if !kerrors.Is(err, kerrors.NotFound) {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
logger.
|
||||
Str("name", currentRef.GetName()).
|
||||
Str("checksum", currentRef.GetChecksum()).
|
||||
Str("uid", string(currentRef.GetUID())).
|
||||
Info("Object deletion has been requested")
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if !discoveredObjectExists {
|
||||
// Let's create Object
|
||||
newObject, err := util.WithKubernetesContextTimeoutP2A2(ctx, client.Create, object, meta.CreateOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
currentRef = util.NewType(sharedApi.NewObjectWithChecksum(newObject, checksum))
|
||||
*ref = currentRef
|
||||
logger.
|
||||
Str("name", currentRef.GetName()).
|
||||
Str("checksum", currentRef.GetChecksum()).
|
||||
Str("uid", string(currentRef.GetUID())).
|
||||
Info("Object has been created")
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Object exists, lets check if update is required
|
||||
action, err := decision(ctx, DecisionObject[T]{
|
||||
Checksum: currentRef.GetChecksum(),
|
||||
Object: discoveredObject,
|
||||
}, DecisionObject[T]{
|
||||
Checksum: checksum,
|
||||
Object: object,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch action {
|
||||
case ActionOK:
|
||||
// Nothing to do
|
||||
return false, nil
|
||||
case ActionReplace:
|
||||
// Object needs to be removed
|
||||
logger.
|
||||
Str("name", currentRef.GetName()).
|
||||
Str("checksum", currentRef.GetChecksum()).
|
||||
Str("uid", string(currentRef.GetUID())).
|
||||
Info("Object needs to be replaced")
|
||||
|
||||
if err := util.WithKubernetesContextTimeoutP1A2(ctx, client.Delete, currentRef.GetName(), meta.DeleteOptions{}); err != nil {
|
||||
if !kerrors.Is(err, kerrors.NotFound) {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
case ActionUpdate:
|
||||
logger.
|
||||
Str("name", currentRef.GetName()).
|
||||
Str("checksum", currentRef.GetChecksum()).
|
||||
Str("uid", string(currentRef.GetUID())).
|
||||
Info("Object needs to be updated in-place")
|
||||
|
||||
newObject, err := util.WithKubernetesContextTimeoutP2A2(ctx, client.Update, object, meta.UpdateOptions{})
|
||||
if err != nil {
|
||||
if !kerrors.Is(err, kerrors.NotFound) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Reconcile if object was not found
|
||||
return true, nil
|
||||
}
|
||||
|
||||
*ref = util.NewType(sharedApi.NewObjectWithChecksum(newObject, checksum))
|
||||
|
||||
return true, nil
|
||||
|
||||
default:
|
||||
return false, errors.Errorf("Unknown action returned")
|
||||
}
|
||||
}
|
85
pkg/util/k8sutil/helpers/updator_decition.go
Normal file
85
pkg/util/k8sutil/helpers/updator_decition.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 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 helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type DecisionObject[T Object] struct {
|
||||
Checksum string
|
||||
Object T
|
||||
}
|
||||
|
||||
func EmptyDecision[T Object](ctx context.Context, current, expected DecisionObject[T]) (Action, error) {
|
||||
return ActionOK, nil
|
||||
}
|
||||
|
||||
type Decision[T Object] func(ctx context.Context, current, expected DecisionObject[T]) (Action, error)
|
||||
|
||||
func (d Decision[T]) Call(ctx context.Context, current, expected DecisionObject[T]) (Action, error) {
|
||||
if d == nil {
|
||||
return EmptyDecision[T](ctx, current, expected)
|
||||
}
|
||||
|
||||
return d(ctx, current, expected)
|
||||
}
|
||||
|
||||
func (d Decision[T]) With(other ...Decision[T]) Decision[T] {
|
||||
return func(ctx context.Context, current, expected DecisionObject[T]) (Action, error) {
|
||||
action, err := d.Call(ctx, current, expected)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
for _, o := range other {
|
||||
if action == ActionReplace {
|
||||
return ActionReplace, nil
|
||||
}
|
||||
|
||||
otherAction, err := o.Call(ctx, current, expected)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
action = action.Or(otherAction)
|
||||
}
|
||||
|
||||
return action, nil
|
||||
}
|
||||
}
|
||||
|
||||
func ReplaceChecksum[T Object](ctx context.Context, current, expected DecisionObject[T]) (Action, error) {
|
||||
if current.Checksum != expected.Checksum {
|
||||
return ActionReplace, nil
|
||||
}
|
||||
|
||||
return ActionOK, nil
|
||||
}
|
||||
|
||||
func UpdateOwnerReference[T Object](ctx context.Context, current, expected DecisionObject[T]) (Action, error) {
|
||||
if !reflect.DeepEqual(current.Object.GetOwnerReferences(), expected.Object.GetOwnerReferences()) {
|
||||
return ActionUpdate, nil
|
||||
}
|
||||
|
||||
return ActionOK, nil
|
||||
}
|
191
pkg/util/k8sutil/helpers/updator_test.go
Normal file
191
pkg/util/k8sutil/helpers/updator_test.go
Normal file
|
@ -0,0 +1,191 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 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 helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/require"
|
||||
core "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/logging"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/tests"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logging.Global().SetRoot(zerolog.New(os.Stdout).With().Timestamp().Logger())
|
||||
}
|
||||
|
||||
func runUpdate[T Object](t *testing.T, iterations int, client Client[T], ref **sharedApi.Object, generator Generate[T], decisions ...Decision[T]) {
|
||||
logger := logging.Global().Get("test")
|
||||
|
||||
i := 0
|
||||
|
||||
for i = 1; i < 1024; i++ {
|
||||
var changed bool
|
||||
t.Run(fmt.Sprintf("Iteration %d", i), func(t *testing.T) {
|
||||
ok, err := Update[T](context.Background(), logger, client, ref, generator, decisions...)
|
||||
require.NoError(t, err)
|
||||
changed = ok
|
||||
})
|
||||
|
||||
if !changed {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.EqualValues(t, iterations, i, fmt.Sprintf("Expected %d iterations, got %d", iterations, i))
|
||||
}
|
||||
|
||||
func get[T Object](t *testing.T, client Client[T], in T) (T, bool) {
|
||||
obj, err := client.Get(context.Background(), in.GetName(), meta.GetOptions{})
|
||||
if err != nil {
|
||||
if kerrors.Is(err, kerrors.NotFound) {
|
||||
return util.Default[T](), false
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
return obj, true
|
||||
}
|
||||
|
||||
func Test_Updator(t *testing.T) {
|
||||
logging.Global().RegisterLogger("test", logging.Trace)
|
||||
|
||||
client := fake.NewSimpleClientset().CoreV1().Secrets(tests.FakeNamespace)
|
||||
|
||||
var secret = core.Secret{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "secret",
|
||||
Namespace: tests.FakeNamespace,
|
||||
UID: uuid.NewUUID(),
|
||||
},
|
||||
}
|
||||
var checksum = util.SHA256FromString("")
|
||||
|
||||
var ref *sharedApi.Object
|
||||
|
||||
var retSecret Generate[*core.Secret] = func(_ context.Context, _ *sharedApi.Object) (*core.Secret, bool, string, error) {
|
||||
return secret.DeepCopy(), false, checksum, nil
|
||||
}
|
||||
|
||||
t.Run("Ensure default is handled", func(t *testing.T) {
|
||||
runUpdate[*core.Secret](t, 2, client, &ref, retSecret)
|
||||
|
||||
_, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("Ensure rerun is handled", func(t *testing.T) {
|
||||
runUpdate[*core.Secret](t, 1, client, &ref, retSecret)
|
||||
|
||||
_, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("Ensure delete is not handled when skip is requested", func(t *testing.T) {
|
||||
runUpdate[*core.Secret](t, 1, client, &ref, func(ctx context.Context, _ *sharedApi.Object) (*core.Secret, bool, string, error) {
|
||||
return nil, true, "", nil
|
||||
})
|
||||
|
||||
_, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("Ensure delete is handled", func(t *testing.T) {
|
||||
runUpdate[*core.Secret](t, 3, client, &ref, func(ctx context.Context, _ *sharedApi.Object) (*core.Secret, bool, string, error) {
|
||||
return nil, false, "", nil
|
||||
})
|
||||
|
||||
_, ok := get[*core.Secret](t, client, &secret)
|
||||
require.False(t, ok)
|
||||
})
|
||||
|
||||
t.Run("Recreate", func(t *testing.T) {
|
||||
runUpdate[*core.Secret](t, 2, client, &ref, retSecret)
|
||||
|
||||
_, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("Change checksum without handler", func(t *testing.T) {
|
||||
checksum = util.SHA256FromString("NEW")
|
||||
|
||||
runUpdate[*core.Secret](t, 1, client, &ref, retSecret)
|
||||
|
||||
require.NotEqual(t, checksum, ref.GetChecksum())
|
||||
|
||||
_, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("Change checksum with recreate handler", func(t *testing.T) {
|
||||
runUpdate[*core.Secret](t, 4, client, &ref, retSecret, ReplaceChecksum[*core.Secret])
|
||||
|
||||
require.Equal(t, checksum, ref.GetChecksum())
|
||||
|
||||
_, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("UUID Changed", func(t *testing.T) {
|
||||
ref.UID = util.NewType(uuid.NewUUID())
|
||||
|
||||
runUpdate[*core.Secret](t, 4, client, &ref, retSecret)
|
||||
|
||||
s, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, ref.GetUID(), s.GetUID())
|
||||
})
|
||||
|
||||
t.Run("Owner Added Without Handler", func(t *testing.T) {
|
||||
secret.SetOwnerReferences([]meta.OwnerReference{
|
||||
{
|
||||
UID: uuid.NewUUID(),
|
||||
},
|
||||
})
|
||||
|
||||
runUpdate[*core.Secret](t, 1, client, &ref, retSecret)
|
||||
|
||||
s, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
require.NotEqual(t, secret.GetOwnerReferences(), s.GetOwnerReferences())
|
||||
})
|
||||
|
||||
t.Run("Owner Added With Handler", func(t *testing.T) {
|
||||
runUpdate[*core.Secret](t, 2, client, &ref, retSecret, UpdateOwnerReference[*core.Secret])
|
||||
|
||||
s, ok := get[*core.Secret](t, client, &secret)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, secret.GetOwnerReferences(), s.GetOwnerReferences())
|
||||
})
|
||||
}
|
|
@ -213,10 +213,9 @@ func GetTLSKeyfileFromSecret(s *core.Secret) (string, error) {
|
|||
return string(keyfile), nil
|
||||
}
|
||||
|
||||
// CreateTLSKeyfileSecret creates a secret used to store a PEM encoded keyfile
|
||||
// RenderTLSKeyfileSecret renders a secret used to store a PEM encoded keyfile
|
||||
// in the format ArangoDB accepts it for its `--ssl.keyfile` option.
|
||||
func CreateTLSKeyfileSecret(ctx context.Context, secrets secretv1.ModInterface, secretName string, keyfile string,
|
||||
ownerRef *meta.OwnerReference) (*core.Secret, error) {
|
||||
func RenderTLSKeyfileSecret(secretName string, keyfile string, ownerRef *meta.OwnerReference) *core.Secret {
|
||||
// Create secret
|
||||
secret := &core.Secret{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
|
@ -228,6 +227,14 @@ func CreateTLSKeyfileSecret(ctx context.Context, secrets secretv1.ModInterface,
|
|||
}
|
||||
// Attach secret to owner
|
||||
AddOwnerRefToObject(secret, ownerRef)
|
||||
return secret
|
||||
}
|
||||
|
||||
// CreateTLSKeyfileSecret creates a secret used to store a PEM encoded keyfile
|
||||
// in the format ArangoDB accepts it for its `--ssl.keyfile` option.
|
||||
func CreateTLSKeyfileSecret(ctx context.Context, secrets secretv1.ModInterface, secretName string, keyfile string,
|
||||
ownerRef *meta.OwnerReference) (*core.Secret, error) {
|
||||
secret := RenderTLSKeyfileSecret(secretName, keyfile, ownerRef)
|
||||
if s, err := secrets.Create(ctx, secret, meta.CreateOptions{}); err != nil {
|
||||
// Failed to create secret
|
||||
return nil, kerrors.NewResourceError(err, secret)
|
||||
|
|
Loading…
Reference in a new issue