1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] [ACS] Initial (#926)

This commit is contained in:
Adam Janikowski 2022-03-10 12:29:55 +01:00 committed by GitHub
parent 3b874af937
commit 267eeb59f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 653 additions and 24 deletions

1
.gitignore vendored
View file

@ -8,6 +8,7 @@ vendor/
deps/
.vscode/
**/*.enterprise.go
**/*.enterprise.go
**/enterprise/**
enterprise.mk
local/

View file

@ -6,6 +6,7 @@
- (Feature) Add CRD Installer
- (Bugfix) Assign imagePullSecrets to LocalStorage
- (Update) Bump K8S API to 1.21.10
- (Feature) (ACS) Add ACS handler
## [1.2.8](https://github.com/arangodb/kube-arangodb/tree/1.2.8) (2022-02-24)
- Do not check License V2 on Community images

View file

@ -14,7 +14,7 @@ metadata:
release: {{ .Release.Name }}
rules:
- apiGroups: ["database.arangodb.com"]
resources: ["arangodeployments", "arangodeployments/status","arangomembers", "arangomembers/status"]
resources: ["arangodeployments", "arangodeployments/status","arangomembers", "arangomembers/status", "arangoclustersynchronizations", "arangoclustersynchronizations/status"]
verbs: ["*"]
- apiGroups: [""]
resources: ["pods", "services", "endpoints", "persistentvolumeclaims", "events", "secrets", "serviceaccounts"]

7
go.mod
View file

@ -28,7 +28,6 @@ require (
github.com/arangodb/go-driver v1.2.1
github.com/arangodb/go-driver/v2 v2.0.0-20211021031401-d92dcd5a4c83
github.com/arangodb/go-upgrade-rules v0.0.0-20180809110947-031b4774ff21
//github.com/arangodb/rebalancer v0.1.1
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9
github.com/ghodss/yaml v1.0.0
@ -55,11 +54,6 @@ require (
k8s.io/klog v1.0.0
)
require (
github.com/arangodb/rebalancer v0.1.1
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
)
require (
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
github.com/beorn7/perks v1.0.1 // indirect
@ -102,6 +96,7 @@ require (
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 // indirect
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
golang.org/x/text v0.3.6 // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect

View file

@ -21,4 +21,12 @@
package v1
type ArangoClusterSynchronizationSpec struct {
DeploymentName string `json:"deploymentName,omitempty"`
KubeConfig *ArangoClusterSynchronizationKubeConfigSpec `json:"kubeconfig,omitempty"`
}
type ArangoClusterSynchronizationKubeConfigSpec struct {
SecretName string `json:"secretName"`
SecretKey string `json:"secretKey"`
Namespace string `json:"namespace"`
}

View file

@ -20,5 +20,15 @@
package v1
import "k8s.io/apimachinery/pkg/types"
type ArangoClusterSynchronizationStatus struct {
Deployment *ArangoClusterSynchronizationDeploymentStatus `json:"deployment,omitempty"`
Conditions ConditionList `json:"conditions,omitempty"`
}
type ArangoClusterSynchronizationDeploymentStatus struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
UID types.UID `json:"uid"`
}

View file

@ -67,8 +67,8 @@ func (in *ArangoClusterSynchronization) DeepCopyInto(out *ArangoClusterSynchroni
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@ -90,6 +90,38 @@ func (in *ArangoClusterSynchronization) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationDeploymentStatus) DeepCopyInto(out *ArangoClusterSynchronizationDeploymentStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoClusterSynchronizationDeploymentStatus.
func (in *ArangoClusterSynchronizationDeploymentStatus) DeepCopy() *ArangoClusterSynchronizationDeploymentStatus {
if in == nil {
return nil
}
out := new(ArangoClusterSynchronizationDeploymentStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationKubeConfigSpec) DeepCopyInto(out *ArangoClusterSynchronizationKubeConfigSpec) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoClusterSynchronizationKubeConfigSpec.
func (in *ArangoClusterSynchronizationKubeConfigSpec) DeepCopy() *ArangoClusterSynchronizationKubeConfigSpec {
if in == nil {
return nil
}
out := new(ArangoClusterSynchronizationKubeConfigSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationList) DeepCopyInto(out *ArangoClusterSynchronizationList) {
*out = *in
@ -126,6 +158,11 @@ func (in *ArangoClusterSynchronizationList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationSpec) DeepCopyInto(out *ArangoClusterSynchronizationSpec) {
*out = *in
if in.KubeConfig != nil {
in, out := &in.KubeConfig, &out.KubeConfig
*out = new(ArangoClusterSynchronizationKubeConfigSpec)
**out = **in
}
return
}
@ -142,6 +179,18 @@ func (in *ArangoClusterSynchronizationSpec) DeepCopy() *ArangoClusterSynchroniza
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationStatus) DeepCopyInto(out *ArangoClusterSynchronizationStatus) {
*out = *in
if in.Deployment != nil {
in, out := &in.Deployment, &out.Deployment
*out = new(ArangoClusterSynchronizationDeploymentStatus)
**out = **in
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make(ConditionList, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}

View file

@ -21,4 +21,11 @@
package v2alpha1
type ArangoClusterSynchronizationSpec struct {
DeploymentName *string `json:"deploymentName,omitempty"`
KubeConfig *ArangoClusterSynchronizationKubeConfigSpec `json:"kubeconfig,omitempty"`
}
type ArangoClusterSynchronizationKubeConfigSpec struct {
SecretName string `json:"secretName"`
Namespace string `json:"namespace"`
}

View file

@ -20,5 +20,17 @@
package v2alpha1
import "k8s.io/apimachinery/pkg/types"
type ArangoClusterSynchronizationStatus struct {
Deployment *ArangoClusterSynchronizationDeploymentStatus `json:"deployment,omitempty"`
KubeConfig *ArangoClusterSynchronizationKubeConfigStatus `json:"kubeconfig,omitempty"`
}
type ArangoClusterSynchronizationDeploymentStatus struct {
UID types.UID `json:"UID"`
}
type ArangoClusterSynchronizationKubeConfigStatus struct {
Conditions ConditionList `json:"conditions,omitempty"`
}

View file

@ -67,8 +67,8 @@ func (in *ArangoClusterSynchronization) DeepCopyInto(out *ArangoClusterSynchroni
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@ -90,6 +90,61 @@ func (in *ArangoClusterSynchronization) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationDeploymentStatus) DeepCopyInto(out *ArangoClusterSynchronizationDeploymentStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoClusterSynchronizationDeploymentStatus.
func (in *ArangoClusterSynchronizationDeploymentStatus) DeepCopy() *ArangoClusterSynchronizationDeploymentStatus {
if in == nil {
return nil
}
out := new(ArangoClusterSynchronizationDeploymentStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationKubeConfigSpec) DeepCopyInto(out *ArangoClusterSynchronizationKubeConfigSpec) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoClusterSynchronizationKubeConfigSpec.
func (in *ArangoClusterSynchronizationKubeConfigSpec) DeepCopy() *ArangoClusterSynchronizationKubeConfigSpec {
if in == nil {
return nil
}
out := new(ArangoClusterSynchronizationKubeConfigSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationKubeConfigStatus) DeepCopyInto(out *ArangoClusterSynchronizationKubeConfigStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make(ConditionList, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoClusterSynchronizationKubeConfigStatus.
func (in *ArangoClusterSynchronizationKubeConfigStatus) DeepCopy() *ArangoClusterSynchronizationKubeConfigStatus {
if in == nil {
return nil
}
out := new(ArangoClusterSynchronizationKubeConfigStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationList) DeepCopyInto(out *ArangoClusterSynchronizationList) {
*out = *in
@ -126,6 +181,16 @@ func (in *ArangoClusterSynchronizationList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationSpec) DeepCopyInto(out *ArangoClusterSynchronizationSpec) {
*out = *in
if in.DeploymentName != nil {
in, out := &in.DeploymentName, &out.DeploymentName
*out = new(string)
**out = **in
}
if in.KubeConfig != nil {
in, out := &in.KubeConfig, &out.KubeConfig
*out = new(ArangoClusterSynchronizationKubeConfigSpec)
**out = **in
}
return
}
@ -142,6 +207,16 @@ func (in *ArangoClusterSynchronizationSpec) DeepCopy() *ArangoClusterSynchroniza
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ArangoClusterSynchronizationStatus) DeepCopyInto(out *ArangoClusterSynchronizationStatus) {
*out = *in
if in.Deployment != nil {
in, out := &in.Deployment, &out.Deployment
*out = new(ArangoClusterSynchronizationDeploymentStatus)
**out = **in
}
if in.KubeConfig != nil {
in, out := &in.KubeConfig, &out.KubeConfig
*out = new(ArangoClusterSynchronizationKubeConfigStatus)
(*in).DeepCopyInto(*out)
}
return
}

View file

@ -0,0 +1,34 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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
//go:build !enterprise
// +build !enterprise
package acs
import (
"context"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
)
func Inspect(ctx context.Context, deployment *api.ArangoDeployment, client kclient.Client, cachedStatus inspectorInterface.Inspector) error {
return nil
}

View file

@ -0,0 +1,28 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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 sutil
import api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
const (
DeploymentReadyCondition api.ConditionType = "DeploymentReady"
KubernetesConnectedCondition api.ConditionType = "KubernetesConnected"
)

View file

@ -41,10 +41,11 @@ import (
"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/acs"
"github.com/arangodb/kube-arangodb/pkg/metrics"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var (
@ -84,7 +85,7 @@ func (d *Deployment) inspectDeployment(lastInterval util.Interval) util.Interval
var updated *api.ArangoDeployment
err = globals.GetGlobalTimeouts().Kubernetes().RunWithTimeout(ctxReconciliation, func(ctxChild context.Context) error {
var err error
updated, err = d.deps.Client.Arango().DatabaseV1().ArangoDeployments(d.GetNamespace()).Get(ctxChild, deploymentName, metav1.GetOptions{})
updated, err = d.deps.Client.Arango().DatabaseV1().ArangoDeployments(d.GetNamespace()).Get(ctxChild, deploymentName, meta.GetOptions{})
return err
})
if k8sutil.IsNotFound(err) {
@ -174,6 +175,10 @@ func (d *Deployment) inspectDeploymentWithError(ctx context.Context, lastInterva
}
}
if err := acs.Inspect(ctx, d.apiObject, d.deps.Client, cachedStatus); err != nil {
d.deps.Log.Warn().Err(err).Msgf("Unable to handle ACS objects")
}
// Cleanup terminated pods on the beginning of loop
if x, err := d.resources.CleanupTerminatedPods(ctx, cachedStatus); err != nil {
return minInspectionInterval, errors.Wrapf(err, "Pod cleanup failed")

View file

@ -38,11 +38,11 @@ func (i *inspector) GetArangoClusterSynchronizations() (arangoclustersynchroniza
i.lock.Lock()
defer i.lock.Unlock()
if i.nodes == nil {
if i.acs == nil {
return nil, false
}
return i.acs, i.nodes.accessible
return i.acs, i.acs.accessible
}
type arangoClusterSynchronizationLoader struct {
@ -51,6 +51,28 @@ type arangoClusterSynchronizationLoader struct {
acs map[string]*api.ArangoClusterSynchronization
}
func (a *arangoClusterSynchronizationLoader) FilterArangoClusterSynchronizations(filters ...arangoclustersynchronization.Filter) []*api.ArangoClusterSynchronization {
q := make([]*api.ArangoClusterSynchronization, 0, len(a.acs))
for _, obj := range a.acs {
if a.filterArangoClusterSynchronizations(obj, filters...) {
q = append(q, obj)
}
}
return q
}
func (a *arangoClusterSynchronizationLoader) filterArangoClusterSynchronizations(obj *api.ArangoClusterSynchronization, filters ...arangoclustersynchronization.Filter) bool {
for _, f := range filters {
if !f(obj) {
return false
}
}
return true
}
func (a *arangoClusterSynchronizationLoader) ArangoClusterSynchronizations() []*api.ArangoClusterSynchronization {
var r []*api.ArangoClusterSynchronization
for _, acs := range a.acs {
@ -157,12 +179,12 @@ func getArangoClusterSynchronizations(ctx context.Context, k versioned.Interface
}
if acss.Continue != "" {
nextNodeLayer, err := getArangoClusterSynchronizations(ctx, k, namespace, acss.Continue)
newACSLoader, err := getArangoClusterSynchronizations(ctx, k, namespace, acss.Continue)
if err != nil {
return nil, err
}
return append(acss.Items, nextNodeLayer...), nil
return append(acss.Items, newACSLoader...), nil
}
return acss.Items, nil

View file

@ -179,6 +179,7 @@ func (i *inspector) Refresh(ctx context.Context) error {
i.serviceMonitors = new.serviceMonitors
i.arangoMembers = new.arangoMembers
i.nodes = new.nodes
i.acs = new.acs
i.versionInfo = new.versionInfo
return nil

View file

@ -31,6 +31,7 @@ type Loader interface {
type Inspector interface {
ArangoClusterSynchronizations() []*api.ArangoClusterSynchronization
ArangoClusterSynchronization(name string) (*api.ArangoClusterSynchronization, bool)
FilterArangoClusterSynchronizations(filters ...Filter) []*api.ArangoClusterSynchronization
IterateArangoClusterSynchronizations(action Action, filters ...Filter) error
ArangoClusterSynchronizationReadInterface() ReadInterface
}

View file

@ -24,15 +24,11 @@ import (
"sync"
"github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned"
versionedFake "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/fake"
"github.com/dchest/uniuri"
"github.com/pkg/errors"
monitoring "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
monitoringFake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake"
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apiextensionsclientFake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
"k8s.io/client-go/kubernetes"
kubernetesFake "k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/rest"
)
@ -168,10 +164,8 @@ type Client interface {
KubernetesExtensions() apiextensionsclient.Interface
Arango() versioned.Interface
Monitoring() monitoring.Interface
}
func NewFakeClient() Client {
return NewStaticClient(kubernetesFake.NewSimpleClientset(), apiextensionsclientFake.NewSimpleClientset(), versionedFake.NewSimpleClientset(), monitoringFake.NewSimpleClientset())
Config() *rest.Config
}
func NewStaticClient(kubernetes kubernetes.Interface, kubernetesExtensions apiextensionsclient.Interface, arango versioned.Interface, monitoring monitoring.Interface) Client {
@ -186,6 +180,8 @@ func NewStaticClient(kubernetes kubernetes.Interface, kubernetesExtensions apiex
func newClient(cfg *rest.Config) (*client, error) {
var c client
c.config = cfg
if q, err := kubernetes.NewForConfig(cfg); err != nil {
return nil, err
} else {
@ -218,6 +214,11 @@ type client struct {
kubernetesExtensions apiextensionsclient.Interface
arango versioned.Interface
monitoring monitoring.Interface
config *rest.Config
}
func (c *client) Config() *rest.Config {
return c.config
}
func (c *client) Kubernetes() kubernetes.Interface {

101
pkg/util/kclient/fake.go Normal file
View file

@ -0,0 +1,101 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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 kclient
import (
"sync"
versionedFake "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/fake"
monitoringFake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake"
apiextensionsclientFake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
"k8s.io/apimachinery/pkg/runtime"
kubernetesFake "k8s.io/client-go/kubernetes/fake"
)
func NewFakeClient() Client {
return NewStaticClient(kubernetesFake.NewSimpleClientset(), apiextensionsclientFake.NewSimpleClientset(), versionedFake.NewSimpleClientset(), monitoringFake.NewSimpleClientset())
}
type FakeClientBuilder interface {
Kubernetes(objects ...runtime.Object) FakeClientBuilder
KubernetesExtensions(objects ...runtime.Object) FakeClientBuilder
Arango(objects ...runtime.Object) FakeClientBuilder
Monitoring(objects ...runtime.Object) FakeClientBuilder
Client() Client
}
func NewFakeClientBuilder() FakeClientBuilder {
return &fakeClientBuilder{}
}
type fakeClientBuilder struct {
lock sync.Mutex
kubernetes []runtime.Object
kubernetesExtensions []runtime.Object
arango []runtime.Object
monitoring []runtime.Object
}
func (f *fakeClientBuilder) Kubernetes(objects ...runtime.Object) FakeClientBuilder {
f.lock.Lock()
defer f.lock.Unlock()
f.kubernetes = append(f.kubernetes, objects...)
return f
}
func (f *fakeClientBuilder) KubernetesExtensions(objects ...runtime.Object) FakeClientBuilder {
f.lock.Lock()
defer f.lock.Unlock()
f.kubernetesExtensions = append(f.kubernetesExtensions, objects...)
return f
}
func (f *fakeClientBuilder) Arango(objects ...runtime.Object) FakeClientBuilder {
f.lock.Lock()
defer f.lock.Unlock()
f.arango = append(f.arango, objects...)
return f
}
func (f *fakeClientBuilder) Monitoring(objects ...runtime.Object) FakeClientBuilder {
f.lock.Lock()
defer f.lock.Unlock()
f.monitoring = append(f.monitoring, objects...)
return f
}
func (f *fakeClientBuilder) Client() Client {
return NewStaticClient(
kubernetesFake.NewSimpleClientset(f.kubernetes...),
apiextensionsclientFake.NewSimpleClientset(f.kubernetesExtensions...),
versionedFake.NewSimpleClientset(f.arango...),
monitoringFake.NewSimpleClientset(f.monitoring...))
}

View file

@ -0,0 +1,51 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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 (
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/secret"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
"github.com/pkg/errors"
rest "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
func SecretConfigGetter(s secret.Inspector, name, key string) kclient.ConfigGetter {
return func() (*rest.Config, string, error) {
secret, ok := s.Secret(name)
if !ok {
return nil, "", errors.Errorf("Secret %s not found", name)
}
v, ok := secret.Data[key]
if !ok {
return nil, "", errors.Errorf("Key %s/%s not found", name, key)
}
cfg, err := clientcmd.RESTConfigFromKubeConfig(v)
if err != nil {
return nil, "", err
}
return cfg, util.SHA256(v), nil
}
}

View file

@ -0,0 +1,131 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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"
"testing"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
"github.com/stretchr/testify/require"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func Test_SecretConfigGetter(t *testing.T) {
t.Run("Missing secret", func(t *testing.T) {
c := kclient.NewFakeClient()
i, err := inspector.NewInspector(context.Background(), c, "default")
require.NoError(t, err)
_, _, err = SecretConfigGetter(i, "secret", "key")()
require.EqualError(t, err, "Secret secret not found")
})
t.Run("Missing key", func(t *testing.T) {
c := kclient.NewFakeClient()
s := core.Secret{
ObjectMeta: meta.ObjectMeta{
Name: "secret",
Namespace: "default",
},
}
_, err := c.Kubernetes().CoreV1().Secrets("default").Create(context.Background(), &s, meta.CreateOptions{})
require.NoError(t, err)
i, err := inspector.NewInspector(context.Background(), c, "default")
require.NoError(t, err)
_, _, err = SecretConfigGetter(i, "secret", "key")()
require.EqualError(t, err, "Key secret/key not found")
})
t.Run("Invalid data", func(t *testing.T) {
c := kclient.NewFakeClient()
s := core.Secret{
ObjectMeta: meta.ObjectMeta{
Name: "secret",
Namespace: "default",
},
Data: map[string][]byte{
"key": []byte(`
random data
`),
},
}
_, err := c.Kubernetes().CoreV1().Secrets("default").Create(context.Background(), &s, meta.CreateOptions{})
require.NoError(t, err)
i, err := inspector.NewInspector(context.Background(), c, "default")
require.NoError(t, err)
_, _, err = SecretConfigGetter(i, "secret", "key")()
require.Error(t, err, "Key secret/key not found")
})
t.Run("Valid data", func(t *testing.T) {
c := kclient.NewFakeClient()
s := core.Secret{
ObjectMeta: meta.ObjectMeta{
Name: "secret",
Namespace: "default",
},
Data: map[string][]byte{
"key": []byte(`
apiVersion: v1
clusters:
- cluster:
server: https://localhost
name: test
contexts:
- context:
cluster: test
user: test
namespace: test
name: test
current-context: test
kind: Config
preferences: {}
users:
- name: test
user:
token: x
`),
},
}
_, err := c.Kubernetes().CoreV1().Secrets("default").Create(context.Background(), &s, meta.CreateOptions{})
require.NoError(t, err)
i, err := inspector.NewInspector(context.Background(), c, "default")
require.NoError(t, err)
_, _, err = SecretConfigGetter(i, "secret", "key")()
require.NoError(t, err)
})
}

57
pkg/util/tests/gen.go Normal file
View file

@ -0,0 +1,57 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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 tests
import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/uuid"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
"testing"
"context"
"github.com/stretchr/testify/require"
)
func NewArangoDeployment(name string) *api.ArangoDeployment {
return &api.ArangoDeployment{
ObjectMeta: meta.ObjectMeta{
Name: name,
Namespace: FakeNamespace,
UID: uuid.NewUUID(),
},
}
}
func NewArangoClusterSynchronization(name string) *api.ArangoClusterSynchronization {
return &api.ArangoClusterSynchronization{
ObjectMeta: meta.ObjectMeta{
Name: name,
Namespace: FakeNamespace,
UID: uuid.NewUUID(),
},
}
}
func RefreshArangoClusterSynchronization(t *testing.T, client kclient.Client, acs *api.ArangoClusterSynchronization) *api.ArangoClusterSynchronization {
nacs, err := client.Arango().DatabaseV1().ArangoClusterSynchronizations(acs.GetNamespace()).Get(context.Background(), acs.GetName(), meta.GetOptions{})
require.NoError(t, err)
return nacs
}

View file

@ -0,0 +1,39 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 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 tests
import (
"testing"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
"context"
"github.com/stretchr/testify/require"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
)
const FakeNamespace = "fake"
func NewInspector(t *testing.T, c kclient.Client) inspectorInterface.Inspector {
i, err := inspector.NewInspector(context.Background(), c, FakeNamespace)
require.NoError(t, err)
return i
}