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:
parent
3b874af937
commit
267eeb59f5
22 changed files with 653 additions and 24 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,6 +8,7 @@ vendor/
|
|||
deps/
|
||||
.vscode/
|
||||
**/*.enterprise.go
|
||||
**/*.enterprise.go
|
||||
**/enterprise/**
|
||||
enterprise.mk
|
||||
local/
|
|
@ -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
|
||||
|
|
|
@ -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
7
go.mod
|
@ -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
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
53
pkg/apis/deployment/v1/zz_generated.deepcopy.go
generated
53
pkg/apis/deployment/v1/zz_generated.deepcopy.go
generated
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
34
pkg/deployment/acs/acs.community.go
Normal file
34
pkg/deployment/acs/acs.community.go
Normal 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
|
||||
}
|
28
pkg/deployment/acs/sutil/conditions.go
Normal file
28
pkg/deployment/acs/sutil/conditions.go
Normal 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"
|
||||
)
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
101
pkg/util/kclient/fake.go
Normal 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...))
|
||||
}
|
51
pkg/util/kclient/helpers/secret.go
Normal file
51
pkg/util/kclient/helpers/secret.go
Normal 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
|
||||
}
|
||||
}
|
131
pkg/util/kclient/helpers/secret_test.go
Normal file
131
pkg/util/kclient/helpers/secret_test.go
Normal 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
57
pkg/util/tests/gen.go
Normal 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
|
||||
}
|
39
pkg/util/tests/inspector.go
Normal file
39
pkg/util/tests/inspector.go
Normal 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
|
||||
}
|
Loading…
Reference in a new issue