This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-swck.git
The following commit(s) were added to refs/heads/master by this push:
new d125f2e [Feature] Add BanyanDB CRD & Controllers (#70)
d125f2e is described below
commit d125f2eaf28f96e895e85ff287ab3329facee8b0
Author: William Song <[email protected]>
AuthorDate: Sat Sep 24 10:46:23 2022 +0800
[Feature] Add BanyanDB CRD & Controllers (#70)
Co-authored-by: Gao Hongtao <[email protected]>
---
.github/workflows/go.yml | 15 +
operator/PROJECT | 9 +
operator/apis/operator/v1alpha1/banyandb_types.go | 106 ++
.../apis/operator/v1alpha1/banyandb_webhook.go | 90 ++
.../operator/v1alpha1/zz_generated.deepcopy.go | 141 ++-
.../operator.skywalking.apache.org_banyandbs.yaml | 1312 ++++++++++++++++++++
.../operator.skywalking.apache.org_swagents.yaml | 2 +-
operator/config/crd/kustomization.yaml | 3 +
operator/config/rbac/role.yaml | 40 +
operator/config/samples/banyandb.yaml | 37 +
operator/config/webhook/manifests.yaml | 40 +
...ellite_controller.go => banyandb_controller.go} | 80 +-
.../controllers/operator/oapserver_controller.go | 1 +
.../controllers/operator/satellite_controller.go | 1 +
.../controllers/operator/storage_controller.go | 1 +
operator/controllers/operator/ui_controller.go | 1 +
operator/main.go | 13 +
.../manifests/banyandb/templates/deployment.yaml | 118 ++
.../manifests/banyandb/templates/grpc_service.yaml | 58 +
.../manifests/banyandb/templates/http_service.yaml | 58 +
.../manifests/banyandb/templates/ingress.yaml | 53 +
.../operator/manifests/banyandb/templates/pvc.yaml | 64 +
.../banyandb/templates/service_account.yaml | 27 +
operator/pkg/operator/manifests/repo.go | 2 +-
test/e2e/banyandb/e2e.yaml | 110 ++
test/e2e/deploy-banyandb.yaml | 66 +
test/e2e/skywalking-components-with-banyandb.yaml | 50 +
test/e2e/verify/affinity.yaml | 16 +
28 files changed, 2462 insertions(+), 52 deletions(-)
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 73aaa8d..e498c7c 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -146,6 +146,21 @@ jobs:
uses:
apache/skywalking-infra-e2e@996ed8902e941e2883fcf0ac5b3090364942d205
with:
e2e-file: test/e2e/oap-ui-agent-external-storage/e2e.yaml
+ banyandb-e2e-tests:
+ name: e2e tests(oap+ui+agent+banyandb)
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: 1.17
+ id: go
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v2
+ - name: Run E2E Test
+ uses:
apache/skywalking-infra-e2e@996ed8902e941e2883fcf0ac5b3090364942d205
+ with:
+ e2e-file: test/e2e/banyandb/e2e.yaml
adapter-hpa-e2e-tests:
name: e2e tests(oap+agent+adapter+hpa)
runs-on: ubuntu-latest
diff --git a/operator/PROJECT b/operator/PROJECT
index 12e05a3..73b6a37 100644
--- a/operator/PROJECT
+++ b/operator/PROJECT
@@ -122,4 +122,13 @@ resources:
defaulting: true
validation: true
webhookVersion: v1
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: skywalking.apache.org
+ group: operator
+ kind: BanyanDB
+ path: github.com/apache/skywalking-swck/operator/apis/operator/v1alpha1
+ version: v1alpha1
version: "3"
diff --git a/operator/apis/operator/v1alpha1/banyandb_types.go
b/operator/apis/operator/v1alpha1/banyandb_types.go
new file mode 100644
index 0000000..05f5244
--- /dev/null
+++ b/operator/apis/operator/v1alpha1/banyandb_types.go
@@ -0,0 +1,106 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package v1alpha1
+
+import (
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// BanyanDBSpec defines the desired state of BanyanDB
+type BanyanDBSpec struct {
+ // Version of BanyanDB.
+ // +kubebuilder:validation:Required
+ Version string `json:"version"`
+
+ // Number of replicas
+ // +kubebuilder:validation:Required
+ Counts int `json:"counts"`
+
+ // Pod template of each BanyanDB instance
+ // +kubebuilder:validation:Required
+ Image string `json:"image"`
+
+ // Pod affinity
+ // +kubebuilder:validation:Optional
+ Affinity corev1.Affinity `json:"affinity"`
+
+ // BanyanDB startup parameters
+ // +kubebuilder:validation:Optional
+ Config []string `json:"config"`
+
+ // BanyanDB HTTP Service
+ // +kubebuilder:validation:Optional
+ HTTPSvc Service `json:"httpService,omitempty"`
+
+ // BanyanDB gRPC Serice
+ // +kubebuilder:validation:Optional
+ GRPCSvc Service `json:"gRPCService,omitempty"`
+
+ // BanyanDB Storage
+ // +kubebuilder:validation:Optional
+ Storages []StorageConfig `json:"storages,omitempty"`
+}
+
+type StorageConfig struct {
+ // the name of storage config
+ // +kubebuilder:validation:Optional
+ Name string `json:"name,omitempty"`
+
+ // mount path of the volume
+ // +kubebuilder:validation:Optional
+ Path string `json:"path,omitempty"`
+
+ // the persistent volume spec for the storage
+ // +kubebuilder:validation:Optional
+ PersistentVolumeClaimSpec corev1.PersistentVolumeClaimSpec
`json:"persistentVolumeClaimSpec,omitempty"`
+}
+
+// BanyanDBStatus defines the observed state of BanyanDB
+type BanyanDBStatus struct {
+ AvailableReplicas int32 `json:"available_pods,omitempty"`
+ // Represents the latest available observations of the underlying
statefulset's current state.
+ // +kubebuilder:validation:Optional
+ Conditions []appsv1.DeploymentCondition `json:"conditions,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+
+// BanyanDB is the Schema for the banyandbs API
+type BanyanDB struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec BanyanDBSpec `json:"spec,omitempty"`
+ Status BanyanDBStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// BanyanDBList contains a list of BanyanDB
+type BanyanDBList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []BanyanDB `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&BanyanDB{}, &BanyanDBList{})
+}
diff --git a/operator/apis/operator/v1alpha1/banyandb_webhook.go
b/operator/apis/operator/v1alpha1/banyandb_webhook.go
new file mode 100644
index 0000000..4e1b370
--- /dev/null
+++ b/operator/apis/operator/v1alpha1/banyandb_webhook.go
@@ -0,0 +1,90 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+package v1alpha1
+
+import (
+ "fmt"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
+ "sigs.k8s.io/controller-runtime/pkg/webhook"
+)
+
+var banyandbLog = logf.Log.WithName("banyandb-resource")
+
+func (r *BanyanDB) SetupWebhookWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewWebhookManagedBy(mgr).
+ For(r).
+ Complete()
+}
+
+// nolint: lll
+//+kubebuilder:webhook:path=/mutate-operator-skywalking-apache-org-v1alpha1-banyandb,mutating=true,failurePolicy=fail,sideEffects=None,groups=operator.skywalking.apache.org,resources=banyandbs,verbs=create;update,versions=v1alpha1,name=mbanyandb.kb.io,admissionReviewVersions=v1
+
+var _ webhook.Defaulter = &BanyanDB{}
+
+func (r *BanyanDB) Default() {
+ banyandbLog.Info("default", "name", r.Name)
+
+ if r.Spec.Version == "" {
+ // use the latest version by default
+ r.Spec.Version = "latest"
+ }
+
+ if r.Spec.Image == "" {
+ r.Spec.Image = fmt.Sprintf("apache/skywalking-banyandb:%s",
r.Spec.Version)
+ }
+
+ if r.Spec.Counts == 0 {
+ // currently only support one data copy
+ r.Spec.Counts = 1
+ }
+}
+
+// nolint: lll
+//
+kubebuilder:webhook:admissionReviewVersions=v1,sideEffects=None,verbs=create;update,path=/validate-operator-skywalking-apache-org-v1alpha1-banyandb,mutating=false,failurePolicy=fail,groups=operator.skywalking.apache.org,resources=banyandbs,versions=v1alpha1,name=vbanyandb.kb.io
+
+var _ webhook.Validator = &BanyanDB{}
+
+func (r *BanyanDB) ValidateCreate() error {
+ banyandbLog.Info("validate create", "name", r.Name)
+ return r.validate()
+}
+
+func (r *BanyanDB) ValidateUpdate(old runtime.Object) error {
+ banyandbLog.Info("validate update", "name", r.Name)
+ return r.validate()
+}
+
+func (r *BanyanDB) ValidateDelete() error {
+ banyandbLog.Info("validate delete", "name", r.Name)
+ return r.validate()
+}
+
+func (r *BanyanDB) validate() error {
+ if r.Spec.Image == "" {
+ return fmt.Errorf("image is absent")
+ }
+
+ if r.Spec.Counts != 1 {
+ return fmt.Errorf("banyandb only support 1 copy for now")
+ }
+
+ return nil
+}
diff --git a/operator/apis/operator/v1alpha1/zz_generated.deepcopy.go
b/operator/apis/operator/v1alpha1/zz_generated.deepcopy.go
index 0a32237..11a476f 100644
--- a/operator/apis/operator/v1alpha1/zz_generated.deepcopy.go
+++ b/operator/apis/operator/v1alpha1/zz_generated.deepcopy.go
@@ -23,12 +23,123 @@
package v1alpha1
import (
- appsv1 "k8s.io/api/apps/v1"
+ v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
- v1 "k8s.io/api/networking/v1"
+ networkingv1 "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/runtime"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
+func (in *BanyanDB) DeepCopyInto(out *BanyanDB) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new BanyanDB.
+func (in *BanyanDB) DeepCopy() *BanyanDB {
+ if in == nil {
+ return nil
+ }
+ out := new(BanyanDB)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver,
creating a new runtime.Object.
+func (in *BanyanDB) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
+func (in *BanyanDBList) DeepCopyInto(out *BanyanDBList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]BanyanDB, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new BanyanDBList.
+func (in *BanyanDBList) DeepCopy() *BanyanDBList {
+ if in == nil {
+ return nil
+ }
+ out := new(BanyanDBList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver,
creating a new runtime.Object.
+func (in *BanyanDBList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
+func (in *BanyanDBSpec) DeepCopyInto(out *BanyanDBSpec) {
+ *out = *in
+ in.Affinity.DeepCopyInto(&out.Affinity)
+ if in.Config != nil {
+ in, out := &in.Config, &out.Config
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ in.HTTPSvc.DeepCopyInto(&out.HTTPSvc)
+ in.GRPCSvc.DeepCopyInto(&out.GRPCSvc)
+ if in.Storages != nil {
+ in, out := &in.Storages, &out.Storages
+ *out = make([]StorageConfig, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new BanyanDBSpec.
+func (in *BanyanDBSpec) DeepCopy() *BanyanDBSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(BanyanDBSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
+func (in *BanyanDBStatus) DeepCopyInto(out *BanyanDBStatus) {
+ *out = *in
+ if in.Conditions != nil {
+ in, out := &in.Conditions, &out.Conditions
+ *out = make([]v1.DeploymentCondition, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new BanyanDBStatus.
+func (in *BanyanDBStatus) DeepCopy() *BanyanDBStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(BanyanDBStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
func (in *Config) DeepCopyInto(out *Config) {
*out = *in
@@ -194,7 +305,7 @@ func (in *Ingress) DeepCopyInto(out *Ingress) {
}
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
- *out = make([]v1.IngressTLS, len(*in))
+ *out = make([]networkingv1.IngressTLS, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -629,7 +740,7 @@ func (in *OAPServerStatus) DeepCopyInto(out
*OAPServerStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]appsv1.DeploymentCondition, len(*in))
+ *out = make([]v1.DeploymentCondition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -764,7 +875,7 @@ func (in *SatelliteStatus) DeepCopyInto(out
*SatelliteStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]appsv1.DeploymentCondition, len(*in))
+ *out = make([]v1.DeploymentCondition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -881,6 +992,22 @@ func (in *Storage) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
+func (in *StorageConfig) DeepCopyInto(out *StorageConfig) {
+ *out = *in
+
in.PersistentVolumeClaimSpec.DeepCopyInto(&out.PersistentVolumeClaimSpec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new StorageConfig.
+func (in *StorageConfig) DeepCopy() *StorageConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(StorageConfig)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
func (in *StorageList) DeepCopyInto(out *StorageList) {
*out = *in
@@ -942,7 +1069,7 @@ func (in *StorageStatus) DeepCopyInto(out *StorageStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]appsv1.StatefulSetCondition, len(*in))
+ *out = make([]v1.StatefulSetCondition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -1178,7 +1305,7 @@ func (in *UIStatus) DeepCopyInto(out *UIStatus) {
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
- *out = make([]appsv1.DeploymentCondition, len(*in))
+ *out = make([]v1.DeploymentCondition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
diff --git
a/operator/config/crd/bases/operator.skywalking.apache.org_banyandbs.yaml
b/operator/config/crd/bases/operator.skywalking.apache.org_banyandbs.yaml
new file mode 100644
index 0000000..3922932
--- /dev/null
+++ b/operator/config/crd/bases/operator.skywalking.apache.org_banyandbs.yaml
@@ -0,0 +1,1312 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.7.0
+ creationTimestamp: null
+ name: banyandbs.operator.skywalking.apache.org
+spec:
+ group: operator.skywalking.apache.org
+ names:
+ kind: BanyanDB
+ listKind: BanyanDBList
+ plural: banyandbs
+ singular: banyandb
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: BanyanDB is the Schema for the banyandbs API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this
representation
+ of an object. Servers should convert recognized schemas to the
latest
+ internal value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST
resource this
+ object represents. Servers may infer this from the endpoint the
client
+ submits requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BanyanDBSpec defines the desired state of BanyanDB
+ properties:
+ affinity:
+ description: Pod affinity
+ properties:
+ nodeAffinity:
+ description: Describes node affinity scheduling rules for
the
+ pod.
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule
pods to
+ nodes that satisfy the affinity expressions
specified by
+ this field, but it may choose a node that violates
one or
+ more of the expressions. The node that is most
preferred
+ is the one with the greatest sum of weights, i.e.
for each
+ node that meets all of the scheduling requirements
(resource
+ request, requiredDuringScheduling affinity
expressions,
+ etc.), compute a sum by iterating through the
elements of
+ this field and adding "weight" to the sum if the
node matches
+ the corresponding matchExpressions; the node(s) with
the
+ highest sum are the most preferred.
+ items:
+ description: An empty preferred scheduling term
matches
+ all objects with implicit weight 0 (i.e. it's a
no-op).
+ A null preferred scheduling term matches no
objects (i.e.
+ is also a no-op).
+ properties:
+ preference:
+ description: A node selector term, associated
with the
+ corresponding weight.
+ properties:
+ matchExpressions:
+ description: A list of node selector
requirements
+ by node's labels.
+ items:
+ description: A node selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the
selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's
relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists, DoesNotExist. Gt,
and
+ Lt.
+ type: string
+ values:
+ description: An array of string
values. If
+ the operator is In or NotIn, the
values
+ array must be non-empty. If the
operator
+ is Exists or DoesNotExist, the
values array
+ must be empty. If the operator is Gt
or
+ Lt, the values array must have a
single
+ element, which will be interpreted
as an
+ integer. This array is replaced
during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector
requirements
+ by node's fields.
+ items:
+ description: A node selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the
selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's
relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists, DoesNotExist. Gt,
and
+ Lt.
+ type: string
+ values:
+ description: An array of string
values. If
+ the operator is In or NotIn, the
values
+ array must be non-empty. If the
operator
+ is Exists or DoesNotExist, the
values array
+ must be empty. If the operator is Gt
or
+ Lt, the values array must have a
single
+ element, which will be interpreted
as an
+ integer. This array is replaced
during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ weight:
+ description: Weight associated with matching the
corresponding
+ nodeSelectorTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - preference
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by
this
+ field are not met at scheduling time, the pod will
not be
+ scheduled onto the node. If the affinity
requirements specified
+ by this field cease to be met at some point during
pod execution
+ (e.g. due to an update), the system may or may not
try to
+ eventually evict the pod from its node.
+ properties:
+ nodeSelectorTerms:
+ description: Required. A list of node selector
terms.
+ The terms are ORed.
+ items:
+ description: A null or empty node selector term
matches
+ no objects. The requirements of them are
ANDed. The
+ TopologySelectorTerm type implements a subset
of the
+ NodeSelectorTerm.
+ properties:
+ matchExpressions:
+ description: A list of node selector
requirements
+ by node's labels.
+ items:
+ description: A node selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the
selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's
relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists, DoesNotExist. Gt,
and
+ Lt.
+ type: string
+ values:
+ description: An array of string
values. If
+ the operator is In or NotIn, the
values
+ array must be non-empty. If the
operator
+ is Exists or DoesNotExist, the
values array
+ must be empty. If the operator is Gt
or
+ Lt, the values array must have a
single
+ element, which will be interpreted
as an
+ integer. This array is replaced
during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchFields:
+ description: A list of node selector
requirements
+ by node's fields.
+ items:
+ description: A node selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: The label key that the
selector
+ applies to.
+ type: string
+ operator:
+ description: Represents a key's
relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists, DoesNotExist. Gt,
and
+ Lt.
+ type: string
+ values:
+ description: An array of string
values. If
+ the operator is In or NotIn, the
values
+ array must be non-empty. If the
operator
+ is Exists or DoesNotExist, the
values array
+ must be empty. If the operator is Gt
or
+ Lt, the values array must have a
single
+ element, which will be interpreted
as an
+ integer. This array is replaced
during a
+ strategic merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ type: object
+ type: array
+ required:
+ - nodeSelectorTerms
+ type: object
+ type: object
+ podAffinity:
+ description: Describes pod affinity scheduling rules (e.g.
co-locate
+ this pod in the same node, zone, etc. as some other
pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule
pods to
+ nodes that satisfy the affinity expressions
specified by
+ this field, but it may choose a node that violates
one or
+ more of the expressions. The node that is most
preferred
+ is the one with the greatest sum of weights, i.e.
for each
+ node that meets all of the scheduling requirements
(resource
+ request, requiredDuringScheduling affinity
expressions,
+ etc.), compute a sum by iterating through the
elements of
+ this field and adding "weight" to the sum if the
node has
+ pods which matches the corresponding
podAffinityTerm; the
+ node(s) with the highest sum are the most preferred.
+ items:
+ description: The weights of all of the matched
WeightedPodAffinityTerm
+ fields are added per-node to find the most
preferred node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term,
associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of
resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list
of label
+ selector requirements. The
requirements are
+ ANDed.
+ items:
+ description: A label selector
requirement
+ is a selector that contains values,
a key,
+ and an operator that relates the key
and
+ values.
+ properties:
+ key:
+ description: key is the label key
that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's
+ relationship to a set of values.
Valid
+ operators are In, NotIn, Exists
and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be
non-empty.
+ If the operator is Exists or
DoesNotExist,
+ the values array must be empty.
This
+ array is replaced during a
strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator
is
+ "In", and the values array contains
only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of
namespaces
+ that the term applies to. The term is
applied
+ to the union of the namespaces selected by
this
+ field and the ones listed in the
namespaces field.
+ null selector and null or empty namespaces
list
+ means "this pod's namespace". An empty
selector
+ ({}) matches all namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list
of label
+ selector requirements. The
requirements are
+ ANDed.
+ items:
+ description: A label selector
requirement
+ is a selector that contains values,
a key,
+ and an operator that relates the key
and
+ values.
+ properties:
+ key:
+ description: key is the label key
that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's
+ relationship to a set of values.
Valid
+ operators are In, NotIn, Exists
and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be
non-empty.
+ If the operator is Exists or
DoesNotExist,
+ the values array must be empty.
This
+ array is replaced during a
strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator
is
+ "In", and the values array contains
only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static
list
+ of namespace names that the term applies
to. The
+ term is applied to the union of the
namespaces
+ listed in this field and the ones selected
by
+ namespaceSelector. null or empty
namespaces list
+ and null namespaceSelector means "this
pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located
(affinity)
+ or not co-located (anti-affinity) with the
pods
+ matching the labelSelector in the
specified namespaces,
+ where co-located is defined as running on
a node
+ whose value of the label with key
topologyKey
+ matches that of any node on which any of
the selected
+ pods is running. Empty topologyKey is not
allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the
corresponding
+ podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the affinity requirements specified by
this
+ field are not met at scheduling time, the pod will
not be
+ scheduled onto the node. If the affinity
requirements specified
+ by this field cease to be met at some point during
pod execution
+ (e.g. due to a pod label update), the system may or
may
+ not try to eventually evict the pod from its node.
When
+ there are multiple elements, the lists of nodes
corresponding
+ to each podAffinityTerm are intersected, i.e. all
terms
+ must be satisfied.
+ items:
+ description: Defines a set of pods (namely those
matching
+ the labelSelector relative to the given
namespace(s))
+ that this pod should be co-located (affinity) or
not co-located
+ (anti-affinity) with, where co-located is defined
as running
+ on a node whose value of the label with key
<topologyKey>
+ matches that of any node on which a pod of the set
of
+ pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of
resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of
label
+ selector requirements. The requirements
are ANDed.
+ items:
+ description: A label selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that
the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be non-empty.
If the
+ operator is Exists or DoesNotExist,
the
+ values array must be empty. This
array is
+ replaced during a strategic merge
patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator is
"In",
+ and the values array contains only
"value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of
namespaces
+ that the term applies to. The term is applied
to the
+ union of the namespaces selected by this field
and
+ the ones listed in the namespaces field. null
selector
+ and null or empty namespaces list means "this
pod's
+ namespace". An empty selector ({}) matches all
namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of
label
+ selector requirements. The requirements
are ANDed.
+ items:
+ description: A label selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that
the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be non-empty.
If the
+ operator is Exists or DoesNotExist,
the
+ values array must be empty. This
array is
+ replaced during a strategic merge
patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator is
"In",
+ and the values array contains only
"value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static list
of namespace
+ names that the term applies to. The term is
applied
+ to the union of the namespaces listed in this
field
+ and the ones selected by namespaceSelector.
null or
+ empty namespaces list and null
namespaceSelector means
+ "this pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located
(affinity)
+ or not co-located (anti-affinity) with the
pods matching
+ the labelSelector in the specified namespaces,
where
+ co-located is defined as running on a node
whose value
+ of the label with key topologyKey matches that
of
+ any node on which any of the selected pods is
running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ podAntiAffinity:
+ description: Describes pod anti-affinity scheduling rules
(e.g.
+ avoid putting this pod in the same node, zone, etc. as
some
+ other pod(s)).
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ description: The scheduler will prefer to schedule
pods to
+ nodes that satisfy the anti-affinity expressions
specified
+ by this field, but it may choose a node that
violates one
+ or more of the expressions. The node that is most
preferred
+ is the one with the greatest sum of weights, i.e.
for each
+ node that meets all of the scheduling requirements
(resource
+ request, requiredDuringScheduling anti-affinity
expressions,
+ etc.), compute a sum by iterating through the
elements of
+ this field and adding "weight" to the sum if the
node has
+ pods which matches the corresponding
podAffinityTerm; the
+ node(s) with the highest sum are the most preferred.
+ items:
+ description: The weights of all of the matched
WeightedPodAffinityTerm
+ fields are added per-node to find the most
preferred node(s)
+ properties:
+ podAffinityTerm:
+ description: Required. A pod affinity term,
associated
+ with the corresponding weight.
+ properties:
+ labelSelector:
+ description: A label query over a set of
resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list
of label
+ selector requirements. The
requirements are
+ ANDed.
+ items:
+ description: A label selector
requirement
+ is a selector that contains values,
a key,
+ and an operator that relates the key
and
+ values.
+ properties:
+ key:
+ description: key is the label key
that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's
+ relationship to a set of values.
Valid
+ operators are In, NotIn, Exists
and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be
non-empty.
+ If the operator is Exists or
DoesNotExist,
+ the values array must be empty.
This
+ array is replaced during a
strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator
is
+ "In", and the values array contains
only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of
namespaces
+ that the term applies to. The term is
applied
+ to the union of the namespaces selected by
this
+ field and the ones listed in the
namespaces field.
+ null selector and null or empty namespaces
list
+ means "this pod's namespace". An empty
selector
+ ({}) matches all namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list
of label
+ selector requirements. The
requirements are
+ ANDed.
+ items:
+ description: A label selector
requirement
+ is a selector that contains values,
a key,
+ and an operator that relates the key
and
+ values.
+ properties:
+ key:
+ description: key is the label key
that
+ the selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's
+ relationship to a set of values.
Valid
+ operators are In, NotIn, Exists
and
+ DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be
non-empty.
+ If the operator is Exists or
DoesNotExist,
+ the values array must be empty.
This
+ array is replaced during a
strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator
is
+ "In", and the values array contains
only "value".
+ The requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static
list
+ of namespace names that the term applies
to. The
+ term is applied to the union of the
namespaces
+ listed in this field and the ones selected
by
+ namespaceSelector. null or empty
namespaces list
+ and null namespaceSelector means "this
pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located
(affinity)
+ or not co-located (anti-affinity) with the
pods
+ matching the labelSelector in the
specified namespaces,
+ where co-located is defined as running on
a node
+ whose value of the label with key
topologyKey
+ matches that of any node on which any of
the selected
+ pods is running. Empty topologyKey is not
allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ weight:
+ description: weight associated with matching the
corresponding
+ podAffinityTerm, in the range 1-100.
+ format: int32
+ type: integer
+ required:
+ - podAffinityTerm
+ - weight
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ description: If the anti-affinity requirements
specified by
+ this field are not met at scheduling time, the pod
will
+ not be scheduled onto the node. If the anti-affinity
requirements
+ specified by this field cease to be met at some
point during
+ pod execution (e.g. due to a pod label update), the
system
+ may or may not try to eventually evict the pod from
its
+ node. When there are multiple elements, the lists of
nodes
+ corresponding to each podAffinityTerm are
intersected, i.e.
+ all terms must be satisfied.
+ items:
+ description: Defines a set of pods (namely those
matching
+ the labelSelector relative to the given
namespace(s))
+ that this pod should be co-located (affinity) or
not co-located
+ (anti-affinity) with, where co-located is defined
as running
+ on a node whose value of the label with key
<topologyKey>
+ matches that of any node on which a pod of the set
of
+ pods is running
+ properties:
+ labelSelector:
+ description: A label query over a set of
resources,
+ in this case pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of
label
+ selector requirements. The requirements
are ANDed.
+ items:
+ description: A label selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that
the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be non-empty.
If the
+ operator is Exists or DoesNotExist,
the
+ values array must be empty. This
array is
+ replaced during a strategic merge
patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator is
"In",
+ and the values array contains only
"value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaceSelector:
+ description: A label query over the set of
namespaces
+ that the term applies to. The term is applied
to the
+ union of the namespaces selected by this field
and
+ the ones listed in the namespaces field. null
selector
+ and null or empty namespaces list means "this
pod's
+ namespace". An empty selector ({}) matches all
namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of
label
+ selector requirements. The requirements
are ANDed.
+ items:
+ description: A label selector requirement
is a
+ selector that contains values, a key,
and an
+ operator that relates the key and values.
+ properties:
+ key:
+ description: key is the label key that
the
+ selector applies to.
+ type: string
+ operator:
+ description: operator represents a
key's relationship
+ to a set of values. Valid operators
are
+ In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of
string
+ values. If the operator is In or
NotIn,
+ the values array must be non-empty.
If the
+ operator is Exists or DoesNotExist,
the
+ values array must be empty. This
array is
+ replaced during a strategic merge
patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of
{key,value}
+ pairs. A single {key,value} in the
matchLabels
+ map is equivalent to an element of
matchExpressions,
+ whose key field is "key", the operator is
"In",
+ and the values array contains only
"value". The
+ requirements are ANDed.
+ type: object
+ type: object
+ namespaces:
+ description: namespaces specifies a static list
of namespace
+ names that the term applies to. The term is
applied
+ to the union of the namespaces listed in this
field
+ and the ones selected by namespaceSelector.
null or
+ empty namespaces list and null
namespaceSelector means
+ "this pod's namespace".
+ items:
+ type: string
+ type: array
+ topologyKey:
+ description: This pod should be co-located
(affinity)
+ or not co-located (anti-affinity) with the
pods matching
+ the labelSelector in the specified namespaces,
where
+ co-located is defined as running on a node
whose value
+ of the label with key topologyKey matches that
of
+ any node on which any of the selected pods is
running.
+ Empty topologyKey is not allowed.
+ type: string
+ required:
+ - topologyKey
+ type: object
+ type: array
+ type: object
+ type: object
+ config:
+ description: BanyanDB startup parameters
+ items:
+ type: string
+ type: array
+ counts:
+ description: Number of replicas
+ type: integer
+ gRPCService:
+ description: BanyanDB gRPC Serice
+ properties:
+ ingress:
+ description: Ingress defines the behavior of an ingress
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Annotations is an unstructured key value
map
+ stored with a resource that may be set by external
tools
+ to store and retrieve arbitrary metadata. They are
not queryable
+ and should be preserved when modifying objects.
+ type: object
+ host:
+ description: Host is the fully qualified domain name
of a
+ network host, as defined by RFC 3986. Note the
following
+ deviations from the "host" part of the URI as
defined in
+ RFC 3986
+ type: string
+ ingressClassName:
+ description: IngressClassName is the name of the
IngressClass
+ cluster resource. The associated IngressClass
defines which
+ controller will implement the resource. This
replaces the
+ deprecated `kubernetes.io/ingress.class` annotation.
For
+ backwards compatibility, when that annotation is
set, it
+ must be given precedence over this field. The
controller
+ may emit a warning if the field and annotation have
different
+ values. Implementations of this API should ignore
Ingresses
+ without a class specified. An IngressClass resource
may
+ be marked as default, which can be used to set a
default
+ value for this field. For more information, refer to
the
+ IngressClass documentation.
+ type: string
+ tls:
+ description: TLS configuration. Currently the Ingress
only
+ supports a single TLS port, 443. If multiple members
of
+ this list specify different hosts, they will be
multiplexed
+ on the same port according to the hostname specified
through
+ the SNI TLS extension, if the ingress controller
fulfilling
+ the ingress supports SNI.
+ items:
+ description: IngressTLS describes the transport
layer security
+ associated with an Ingress.
+ properties:
+ hosts:
+ description: Hosts are a list of hosts included
in the
+ TLS certificate. The values in this list must
match
+ the name/s used in the tlsSecret. Defaults to
the
+ wildcard host setting for the loadbalancer
controller
+ fulfilling this Ingress, if left unspecified.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ secretName:
+ description: SecretName is the name of the
secret used
+ to terminate TLS traffic on port 443. Field is
left
+ optional to allow TLS routing based on SNI
hostname
+ alone. If the SNI host in a listener conflicts
with
+ the "Host" header field used by an
IngressRule, the
+ SNI host is used for termination and value of
the
+ Host header is used for routing.
+ type: string
+ type: object
+ type: array
+ type: object
+ template:
+ description: ServiceTemplate defines the behavior of a
service.
+ properties:
+ clusterIP:
+ description: clusterIP is the IP address of the
service and
+ is usually assigned randomly.
+ type: string
+ externalIPs:
+ description: externalIPs is a list of IP addresses for
which
+ nodes in the cluster will also accept traffic for
this service.
+ items:
+ type: string
+ type: array
+ loadBalancerIP:
+ description: 'Only applies to Service Type:
LoadBalancer LoadBalancer
+ will get created with the IP specified in this
field.'
+ type: string
+ loadBalancerSourceRanges:
+ description: If specified and supported by the
platform, this
+ will restrict traffic through the cloud-provider
load-balancer
+ will be restricted to the specified client IPs.
+ items:
+ type: string
+ type: array
+ type:
+ description: type determines how the Service is
exposed.
+ type: string
+ type: object
+ type: object
+ httpService:
+ description: BanyanDB HTTP Service
+ properties:
+ ingress:
+ description: Ingress defines the behavior of an ingress
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Annotations is an unstructured key value
map
+ stored with a resource that may be set by external
tools
+ to store and retrieve arbitrary metadata. They are
not queryable
+ and should be preserved when modifying objects.
+ type: object
+ host:
+ description: Host is the fully qualified domain name
of a
+ network host, as defined by RFC 3986. Note the
following
+ deviations from the "host" part of the URI as
defined in
+ RFC 3986
+ type: string
+ ingressClassName:
+ description: IngressClassName is the name of the
IngressClass
+ cluster resource. The associated IngressClass
defines which
+ controller will implement the resource. This
replaces the
+ deprecated `kubernetes.io/ingress.class` annotation.
For
+ backwards compatibility, when that annotation is
set, it
+ must be given precedence over this field. The
controller
+ may emit a warning if the field and annotation have
different
+ values. Implementations of this API should ignore
Ingresses
+ without a class specified. An IngressClass resource
may
+ be marked as default, which can be used to set a
default
+ value for this field. For more information, refer to
the
+ IngressClass documentation.
+ type: string
+ tls:
+ description: TLS configuration. Currently the Ingress
only
+ supports a single TLS port, 443. If multiple members
of
+ this list specify different hosts, they will be
multiplexed
+ on the same port according to the hostname specified
through
+ the SNI TLS extension, if the ingress controller
fulfilling
+ the ingress supports SNI.
+ items:
+ description: IngressTLS describes the transport
layer security
+ associated with an Ingress.
+ properties:
+ hosts:
+ description: Hosts are a list of hosts included
in the
+ TLS certificate. The values in this list must
match
+ the name/s used in the tlsSecret. Defaults to
the
+ wildcard host setting for the loadbalancer
controller
+ fulfilling this Ingress, if left unspecified.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ secretName:
+ description: SecretName is the name of the
secret used
+ to terminate TLS traffic on port 443. Field is
left
+ optional to allow TLS routing based on SNI
hostname
+ alone. If the SNI host in a listener conflicts
with
+ the "Host" header field used by an
IngressRule, the
+ SNI host is used for termination and value of
the
+ Host header is used for routing.
+ type: string
+ type: object
+ type: array
+ type: object
+ template:
+ description: ServiceTemplate defines the behavior of a
service.
+ properties:
+ clusterIP:
+ description: clusterIP is the IP address of the
service and
+ is usually assigned randomly.
+ type: string
+ externalIPs:
+ description: externalIPs is a list of IP addresses for
which
+ nodes in the cluster will also accept traffic for
this service.
+ items:
+ type: string
+ type: array
+ loadBalancerIP:
+ description: 'Only applies to Service Type:
LoadBalancer LoadBalancer
+ will get created with the IP specified in this
field.'
+ type: string
+ loadBalancerSourceRanges:
+ description: If specified and supported by the
platform, this
+ will restrict traffic through the cloud-provider
load-balancer
+ will be restricted to the specified client IPs.
+ items:
+ type: string
+ type: array
+ type:
+ description: type determines how the Service is
exposed.
+ type: string
+ type: object
+ type: object
+ image:
+ description: Pod template of each BanyanDB instance
+ type: string
+ storages:
+ description: BanyanDB Storage
+ items:
+ properties:
+ name:
+ description: the name of storage config
+ type: string
+ path:
+ description: mount path of the volume
+ type: string
+ persistentVolumeClaimSpec:
+ description: the persistent volume spec for the storage
+ properties:
+ accessModes:
+ description: 'accessModes contains the desired
access modes
+ the volume should have. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
+ items:
+ type: string
+ type: array
+ dataSource:
+ description: 'dataSource field can be used to
specify either:
+ * An existing VolumeSnapshot object
(snapshot.storage.k8s.io/VolumeSnapshot)
+ * An existing PVC (PersistentVolumeClaim) If the
provisioner
+ or an external controller can support the
specified data
+ source, it will create a new volume based on the
contents
+ of the specified data source. If the
AnyVolumeDataSource
+ feature gate is enabled, this field will always
have the
+ same contents as the DataSourceRef field.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the
resource
+ being referenced. If APIGroup is not
specified, the
+ specified Kind must be in the core API group.
For
+ any other third-party types, APIGroup is
required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
referenced
+ type: string
+ name:
+ description: Name is the name of resource being
referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ dataSourceRef:
+ description: 'dataSourceRef specifies the object
from which
+ to populate the volume with data, if a non-empty
volume
+ is desired. This may be any local object from a
non-empty
+ API group (non core object) or a
PersistentVolumeClaim
+ object. When this field is specified, volume
binding will
+ only succeed if the type of the specified object
matches
+ some installed volume populator or dynamic
provisioner.
+ This field will replace the functionality of the
DataSource
+ field and as such if both fields are non-empty,
they must
+ have the same value. For backwards compatibility,
both
+ fields (DataSource and DataSourceRef) will be set
to the
+ same value automatically if one of them is empty
and the
+ other is non-empty. There are two important
differences
+ between DataSource and DataSourceRef: * While
DataSource
+ only allows two specific types of objects,
DataSourceRef allows
+ any non-core object, as well as
PersistentVolumeClaim
+ objects. * While DataSource ignores disallowed
values
+ (dropping them), DataSourceRef preserves all
values,
+ and generates an error if a disallowed value is
specified.
+ (Beta) Using this field requires the
AnyVolumeDataSource
+ feature gate to be enabled.'
+ properties:
+ apiGroup:
+ description: APIGroup is the group for the
resource
+ being referenced. If APIGroup is not
specified, the
+ specified Kind must be in the core API group.
For
+ any other third-party types, APIGroup is
required.
+ type: string
+ kind:
+ description: Kind is the type of resource being
referenced
+ type: string
+ name:
+ description: Name is the name of resource being
referenced
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ description: 'resources represents the minimum
resources
+ the volume should have. If
RecoverVolumeExpansionFailure
+ feature is enabled users are allowed to specify
resource
+ requirements that are lower than previous value
but must
+ still be higher than capacity recorded in the
status field
+ of the claim. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources'
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern:
^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum
amount of
+ compute resources allowed. More info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern:
^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum
amount
+ of compute resources required. If Requests is
omitted
+ for a container, it defaults to Limits if that
is
+ explicitly specified, otherwise to an
implementation-defined
+ value. More info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ selector:
+ description: selector is a label query over volumes
to consider
+ for binding.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
selector
+ requirements. The requirements are ANDed.
+ items:
+ description: A label selector requirement is a
selector
+ that contains values, a key, and an operator
that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
selector
+ applies to.
+ type: string
+ operator:
+ description: operator represents a key's
relationship
+ to a set of values. Valid operators are
In,
+ NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: values is an array of string
values.
+ If the operator is In or NotIn, the
values array
+ must be non-empty. If the operator is
Exists
+ or DoesNotExist, the values array must
be empty.
+ This array is replaced during a
strategic merge
+ patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: matchLabels is a map of {key,value}
pairs.
+ A single {key,value} in the matchLabels map is
equivalent
+ to an element of matchExpressions, whose key
field
+ is "key", the operator is "In", and the values
array
+ contains only "value". The requirements are
ANDed.
+ type: object
+ type: object
+ storageClassName:
+ description: 'storageClassName is the name of the
StorageClass
+ required by the claim. More info:
https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+ type: string
+ volumeMode:
+ description: volumeMode defines what type of volume
is required
+ by the claim. Value of Filesystem is implied when
not
+ included in claim spec.
+ type: string
+ volumeName:
+ description: volumeName is the binding reference to
the
+ PersistentVolume backing this claim.
+ type: string
+ type: object
+ type: object
+ type: array
+ version:
+ description: Version of BanyanDB.
+ type: string
+ required:
+ - counts
+ - image
+ - version
+ type: object
+ status:
+ description: BanyanDBStatus defines the observed state of BanyanDB
+ properties:
+ available_pods:
+ format: int32
+ type: integer
+ conditions:
+ description: Represents the latest available observations of
the underlying
+ statefulset's current state.
+ items:
+ description: DeploymentCondition describes the state of a
deployment
+ at a certain point.
+ properties:
+ lastTransitionTime:
+ description: Last time the condition transitioned from
one status
+ to another.
+ format: date-time
+ type: string
+ lastUpdateTime:
+ description: The last time this condition was updated.
+ format: date-time
+ type: string
+ message:
+ description: A human readable message indicating details
about
+ the transition.
+ type: string
+ reason:
+ description: The reason for the condition's last
transition.
+ type: string
+ status:
+ description: Status of the condition, one of True,
False, Unknown.
+ type: string
+ type:
+ description: Type of deployment condition.
+ type: string
+ required:
+ - status
+ - type
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git
a/operator/config/crd/bases/operator.skywalking.apache.org_swagents.yaml
b/operator/config/crd/bases/operator.skywalking.apache.org_swagents.yaml
index 0be60ff..4c5d3a6 100644
--- a/operator/config/crd/bases/operator.skywalking.apache.org_swagents.yaml
+++ b/operator/config/crd/bases/operator.skywalking.apache.org_swagents.yaml
@@ -57,7 +57,7 @@ spec:
which is to be injected.
type: string
javaSidecar:
- description: Java defines Java agent special configs.
+ description: JavaSidecar defines Java agent special configs.
properties:
args:
description: Args is the args for initContainer.
diff --git a/operator/config/crd/kustomization.yaml
b/operator/config/crd/kustomization.yaml
index 578d342..468804a 100644
--- a/operator/config/crd/kustomization.yaml
+++ b/operator/config/crd/kustomization.yaml
@@ -28,6 +28,7 @@ resources:
- bases/operator.skywalking.apache.org_swagents.yaml
- bases/operator.skywalking.apache.org_oapserverconfigs.yaml
- bases/operator.skywalking.apache.org_oapserverdynamicconfigs.yaml
+- bases/operator.skywalking.apache.org_banyandbs.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge:
@@ -42,6 +43,7 @@ patchesStrategicMerge:
- patches/webhook_in_oapserverconfigs.yaml
#- patches/webhook_in_oapserverdynamicconfigs.yaml
#- patches/webhook_in_swagents.yaml
+#- patches/webhook_in_banyandbs.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with
[CERTMANAGER] prefix.
@@ -55,6 +57,7 @@ patchesStrategicMerge:
- patches/cainjection_in_oapserverconfigs.yaml
#- patches/cainjection_in_oapserverdynamicconfigs.yaml
#- patches/cainjection_in_swagents.yaml
+#- patches/cainjection_in_banyandbs.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for
CRDs.
diff --git a/operator/config/rbac/role.yaml b/operator/config/rbac/role.yaml
index 7b6d617..95f31ec 100644
--- a/operator/config/rbac/role.yaml
+++ b/operator/config/rbac/role.yaml
@@ -49,6 +49,20 @@ rules:
verbs:
- create
- patch
+- apiGroups:
+ - ""
+ resources:
+ - persistentvolumeclaims
+ - serviceaccounts
+ - services
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
- apiGroups:
- ""
resources:
@@ -147,6 +161,32 @@ rules:
- patch
- update
- watch
+- apiGroups:
+ - operator.skywalking.apache.org
+ resources:
+ - banyandbs
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - operator.skywalking.apache.org
+ resources:
+ - banyandbs/finalizers
+ verbs:
+ - update
+- apiGroups:
+ - operator.skywalking.apache.org
+ resources:
+ - banyandbs/status
+ verbs:
+ - get
+ - patch
+ - update
- apiGroups:
- operator.skywalking.apache.org
resources:
diff --git a/operator/config/samples/banyandb.yaml
b/operator/config/samples/banyandb.yaml
new file mode 100644
index 0000000..4f00cd2
--- /dev/null
+++ b/operator/config/samples/banyandb.yaml
@@ -0,0 +1,37 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+apiVersion: operator.skywalking.apache.org/v1alpha1
+kind: BanyanDB
+metadata:
+ name: banyandb-sample
+spec:
+ version: 1.0.9
+ counts: 1
+ image: apache/skywalking-banyandb:latest
+ config:
+ - "standalone"
+
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: storage
+ operator: In
+ values:
+ - banyandb
diff --git a/operator/config/webhook/manifests.yaml
b/operator/config/webhook/manifests.yaml
index f69f2fa..5c1811c 100644
--- a/operator/config/webhook/manifests.yaml
+++ b/operator/config/webhook/manifests.yaml
@@ -22,6 +22,26 @@ metadata:
creationTimestamp: null
name: mutating-webhook-configuration
webhooks:
+- admissionReviewVersions:
+ - v1
+ clientConfig:
+ service:
+ name: webhook-service
+ namespace: system
+ path: /mutate-operator-skywalking-apache-org-v1alpha1-banyandb
+ failurePolicy: Fail
+ name: mbanyandb.kb.io
+ rules:
+ - apiGroups:
+ - operator.skywalking.apache.org
+ apiVersions:
+ - v1alpha1
+ operations:
+ - CREATE
+ - UPDATE
+ resources:
+ - banyandbs
+ sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
@@ -230,6 +250,26 @@ metadata:
creationTimestamp: null
name: validating-webhook-configuration
webhooks:
+- admissionReviewVersions:
+ - v1
+ clientConfig:
+ service:
+ name: webhook-service
+ namespace: system
+ path: /validate-operator-skywalking-apache-org-v1alpha1-banyandb
+ failurePolicy: Fail
+ name: vbanyandb.kb.io
+ rules:
+ - apiGroups:
+ - operator.skywalking.apache.org
+ apiVersions:
+ - v1alpha1
+ operations:
+ - CREATE
+ - UPDATE
+ resources:
+ - banyandbs
+ sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
diff --git a/operator/controllers/operator/satellite_controller.go
b/operator/controllers/operator/banyandb_controller.go
similarity index 51%
copy from operator/controllers/operator/satellite_controller.go
copy to operator/controllers/operator/banyandb_controller.go
index 46eafb7..7d2dc62 100644
--- a/operator/controllers/operator/satellite_controller.go
+++ b/operator/controllers/operator/banyandb_controller.go
@@ -23,8 +23,8 @@ import (
"github.com/go-logr/logr"
apps "k8s.io/api/apps/v1"
- core "k8s.io/api/core/v1"
apiequal "k8s.io/apimachinery/pkg/api/equality"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/retry"
@@ -32,30 +32,34 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
runtimelog "sigs.k8s.io/controller-runtime/pkg/log"
+ "github.com/apache/skywalking-swck/operator/apis/operator/v1alpha1"
operatorv1alpha1
"github.com/apache/skywalking-swck/operator/apis/operator/v1alpha1"
"github.com/apache/skywalking-swck/operator/pkg/kubernetes"
)
-// SatelliteReconciler reconciles a Satellite object
-type SatelliteReconciler struct {
+// BanyanDBReconciler reconciles a BanyanDB object
+type BanyanDBReconciler struct {
client.Client
Scheme *runtime.Scheme
FileRepo kubernetes.Repo
Recorder record.EventRecorder
}
-//+kubebuilder:rbac:groups=operator.skywalking.apache.org,resources=satellites,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups=operator.skywalking.apache.org,resources=satellites/status,verbs=get;update;patch
-//+kubebuilder:rbac:groups=operator.skywalking.apache.org,resources=satellites/finalizers,verbs=update
+//+kubebuilder:rbac:groups=operator.skywalking.apache.org,resources=banyandbs,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=operator.skywalking.apache.org,resources=banyandbs/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=operator.skywalking.apache.org,resources=banyandbs/finalizers,verbs=update
+//+kubebuilder:rbac:groups="",resources=services;serviceaccounts;persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=*
-func (r *SatelliteReconciler) Reconcile(ctx context.Context, req ctrl.Request)
(ctrl.Result, error) {
+func (r *BanyanDBReconciler) Reconcile(ctx context.Context, req ctrl.Request)
(ctrl.Result, error) {
log := runtimelog.FromContext(ctx)
- log.Info("=====================satellite reconcile
started================================")
+ log.Info("=====================reconcile
started================================")
- satellite := operatorv1alpha1.Satellite{}
- if err := r.Client.Get(ctx, req.NamespacedName, &satellite); err != nil
{
+ var banyanDB v1alpha1.BanyanDB
+ if err := r.Get(ctx, req.NamespacedName, &banyanDB); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
+
ff, err := r.FileRepo.GetFilesRecursive("templates")
if err != nil {
log.Error(err, "failed to load resource templates")
@@ -63,9 +67,9 @@ func (r *SatelliteReconciler) Reconcile(ctx context.Context,
req ctrl.Request) (
}
app := kubernetes.Application{
Client: r.Client,
+ CR: &banyanDB,
FileRepo: r.FileRepo,
- CR: &satellite,
- GVK: operatorv1alpha1.GroupVersion.WithKind("Satellite"),
+ GVK: operatorv1alpha1.GroupVersion.WithKind("BanyanDB"),
Recorder: r.Recorder,
}
@@ -73,7 +77,7 @@ func (r *SatelliteReconciler) Reconcile(ctx context.Context,
req ctrl.Request) (
return ctrl.Result{}, err
}
- if err := r.checkState(ctx, log, &satellite); err != nil {
+ if err := r.checkState(ctx, log, &banyanDB); err != nil {
log.Error(err, "failed to check sub resources state")
return ctrl.Result{}, err
}
@@ -81,61 +85,51 @@ func (r *SatelliteReconciler) Reconcile(ctx
context.Context, req ctrl.Request) (
return ctrl.Result{RequeueAfter: schedDuration}, nil
}
-func (r *SatelliteReconciler) checkState(ctx context.Context, log logr.Logger,
satellite *operatorv1alpha1.Satellite) error {
- overlay := operatorv1alpha1.SatelliteStatus{}
+func (r *BanyanDBReconciler) checkState(ctx context.Context, log logr.Logger,
banyanDB *operatorv1alpha1.BanyanDB) error {
+ overlay := operatorv1alpha1.BanyanDBStatus{}
deployment := apps.Deployment{}
errCol := new(kubernetes.ErrorCollector)
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace:
satellite.Namespace, Name: satellite.Name + "-satellite"}, &deployment); err !=
nil {
- errCol.Collect(fmt.Errorf("failed to get deployment :%v", err))
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace:
banyanDB.Namespace, Name: banyanDB.Name + "-banyandb"}, &deployment); err !=
nil && !apierrors.IsNotFound(err) {
+ errCol.Collect(fmt.Errorf("failed to get deployment: %w", err))
} else {
overlay.Conditions = deployment.Status.Conditions
overlay.AvailableReplicas = deployment.Status.AvailableReplicas
}
- service := core.Service{}
- if err := r.Client.Get(ctx, client.ObjectKey{Namespace:
satellite.Namespace, Name: satellite.Name + "-satellite"}, &service); err !=
nil {
- errCol.Collect(fmt.Errorf("failed to get service :%v", err))
- } else {
- overlay.Address = fmt.Sprintf("%s.%s", service.Name,
service.Namespace)
- }
- if apiequal.Semantic.DeepDerivative(overlay, satellite.Status) {
+ if apiequal.Semantic.DeepDerivative(overlay, banyanDB.Status) {
log.Info("Status keeps the same as before")
- }
- satellite.Status = overlay
- satellite.Kind = "Satellite"
- if err := kubernetes.ApplyOverlay(satellite,
&operatorv1alpha1.Satellite{Status: overlay}); err != nil {
- errCol.Collect(fmt.Errorf("failed to apply overlay: %w", err))
return errCol.Error()
}
- if err := r.updateStatus(ctx, satellite, overlay, errCol); err != nil {
- errCol.Collect(fmt.Errorf("failed to update status of
satellite: %w", err))
+
+ if err := r.updateStatus(ctx, banyanDB, overlay, errCol); err != nil {
+ errCol.Collect(fmt.Errorf("failed to update status of banyanDB:
%w", err))
}
+
log.Info("updated Status sub resource")
return errCol.Error()
}
-func (r *SatelliteReconciler) updateStatus(ctx context.Context, satellite
*operatorv1alpha1.Satellite,
- overlay operatorv1alpha1.SatelliteStatus, errCol
*kubernetes.ErrorCollector) error {
- // avoid resource conflict
+func (r *BanyanDBReconciler) updateStatus(ctx context.Context, banyanDB
*operatorv1alpha1.BanyanDB,
+ overlay operatorv1alpha1.BanyanDBStatus, errCol
*kubernetes.ErrorCollector) error {
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
- if err := r.Client.Get(ctx, client.ObjectKey{Name:
satellite.Name, Namespace: satellite.Namespace}, satellite); err != nil {
- errCol.Collect(fmt.Errorf("failed to get satellite:
%w", err))
+ if err := r.Client.Get(ctx, client.ObjectKey{Namespace:
banyanDB.Namespace, Name: banyanDB.Name}, banyanDB); err != nil {
+ errCol.Collect(fmt.Errorf("failed to get banyanDB: %w",
err))
}
- satellite.Status = overlay
- satellite.Kind = "Satellite"
- if err := kubernetes.ApplyOverlay(satellite,
&operatorv1alpha1.Satellite{Status: overlay}); err != nil {
+ banyanDB.Status = overlay
+ banyanDB.Kind = "BanyanDB"
+ if err := kubernetes.ApplyOverlay(banyanDB,
&operatorv1alpha1.BanyanDB{Status: overlay}); err != nil {
errCol.Collect(fmt.Errorf("failed to apply overlay:
%w", err))
}
- if err := r.Status().Update(ctx, satellite); err != nil {
- errCol.Collect(fmt.Errorf("failed to update status of
satellite: %w", err))
+ if err := r.Status().Update(ctx, banyanDB); err != nil {
+ errCol.Collect(fmt.Errorf("failed to update status of
banyandb: %w", err))
}
return errCol.Error()
})
}
// SetupWithManager sets up the controller with the Manager.
-func (r *SatelliteReconciler) SetupWithManager(mgr ctrl.Manager) error {
+func (r *BanyanDBReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
- For(&operatorv1alpha1.Satellite{}).
+ For(&operatorv1alpha1.BanyanDB{}).
Complete(r)
}
diff --git a/operator/controllers/operator/oapserver_controller.go
b/operator/controllers/operator/oapserver_controller.go
index 02fb940..1315f24 100644
--- a/operator/controllers/operator/oapserver_controller.go
+++ b/operator/controllers/operator/oapserver_controller.go
@@ -113,6 +113,7 @@ func (r *OAPServerReconciler) checkState(ctx
context.Context, log logr.Logger, o
}
if apiequal.Semantic.DeepDerivative(overlay, oapServer.Status) {
log.Info("Status keeps the same as before")
+ return errCol.Error()
}
if err := r.updateStatus(ctx, oapServer, overlay, errCol); err != nil {
diff --git a/operator/controllers/operator/satellite_controller.go
b/operator/controllers/operator/satellite_controller.go
index 46eafb7..4735aa4 100644
--- a/operator/controllers/operator/satellite_controller.go
+++ b/operator/controllers/operator/satellite_controller.go
@@ -99,6 +99,7 @@ func (r *SatelliteReconciler) checkState(ctx context.Context,
log logr.Logger, s
}
if apiequal.Semantic.DeepDerivative(overlay, satellite.Status) {
log.Info("Status keeps the same as before")
+ return errCol.Error()
}
satellite.Status = overlay
satellite.Kind = "Satellite"
diff --git a/operator/controllers/operator/storage_controller.go
b/operator/controllers/operator/storage_controller.go
index 1458595..4bb4136 100644
--- a/operator/controllers/operator/storage_controller.go
+++ b/operator/controllers/operator/storage_controller.go
@@ -138,6 +138,7 @@ func (r *StorageReconciler) checkState(ctx context.Context,
log logr.Logger, sto
if apiequal.Semantic.DeepDerivative(overlay, storage.Status) {
log.Info("Status keeps the same as before")
+ return errCol.Error()
}
storage.Status = overlay
storage.Kind = "Storage"
diff --git a/operator/controllers/operator/ui_controller.go
b/operator/controllers/operator/ui_controller.go
index f03a20a..924e07d 100644
--- a/operator/controllers/operator/ui_controller.go
+++ b/operator/controllers/operator/ui_controller.go
@@ -110,6 +110,7 @@ func (r *UIReconciler) checkState(ctx context.Context, log
logr.Logger, ui *uiv1
}
if apiequal.Semantic.DeepDerivative(overlay, ui.Status) {
log.Info("Status keeps the same as before")
+ return errCol.Error()
}
ui.Status = overlay
ui.Kind = "UI"
diff --git a/operator/main.go b/operator/main.go
index 97fab46..1da407f 100644
--- a/operator/main.go
+++ b/operator/main.go
@@ -165,6 +165,15 @@ func main() {
os.Exit(1)
}
+ if err = (&operatorcontrollers.BanyanDBReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ FileRepo: manifests.NewRepo("banyandb"),
+ Recorder: mgr.GetEventRecorderFor("banyandb-controller"),
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller",
"controller", "BanyanDB")
+ os.Exit(1)
+ }
//+kubebuilder:scaffold:builder
if os.Getenv("ENABLE_WEBHOOKS") != "false" {
if err =
(&operatorv1alpha1.OAPServer{}).SetupWebhookWithManager(mgr); err != nil {
@@ -203,6 +212,10 @@ func main() {
setupLog.Error(err, "unable to create webhook",
"webhook", "OAPServerDynamicConfig")
os.Exit(1)
}
+ if err =
(&operatorv1alpha1.BanyanDB{}).SetupWebhookWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create webhook",
"webhook", "BanyanDB")
+ os.Exit(1)
+ }
// register a webhook to enable the java agent injector
setupLog.Info("registering /mutate-v1-pod webhook")
mgr.GetWebhookServer().Register("/mutate-v1-pod",
diff --git a/operator/pkg/operator/manifests/banyandb/templates/deployment.yaml
b/operator/pkg/operator/manifests/banyandb/templates/deployment.yaml
new file mode 100644
index 0000000..b0662ee
--- /dev/null
+++ b/operator/pkg/operator/manifests/banyandb/templates/deployment.yaml
@@ -0,0 +1,118 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ .Name }}-banyandb
+ namespace: {{ .Namespace }}
+ labels:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ operator.skywalking.apache.org/application: banyandb
+ operator.skywalking.apache.org/component: deployment
+spec:
+ replicas: {{ .Spec.Counts }}
+ selector:
+ matchLabels:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ template:
+ metadata:
+ labels:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ operator.skywalking.apache.org/application: banyandb
+ operator.skywalking.apache.org/component: pod
+ spec:
+ serviceAccountName: {{ .Name }}-banyandb
+
+ {{- if .Spec.Storages }}
+ volumes:
+ {{- range $storage := .Spec.Storages }}
+ - name: {{ $storage.Name }}
+ persistentVolumeClaim:
+ claimName: {{ $storage.Name }}-banyandb
+ {{- end }}
+ {{- end}}
+ containers:
+ - name: banyandb-container
+ image: {{ .Spec.Image }}
+ imagePullPolicy: IfNotPresent
+ args:
+ {{- range $value := .Spec.Config }}
+ - {{ $value }}
+ {{- end }}
+ ports:
+ - containerPort: 17912
+ name: grpc
+ - containerPort: 17913
+ name: http
+ - containerPort: 2121
+ name: observability
+ - containerPort: 6060
+ name: pprof
+
+ {{- if .Spec.Storages }}
+ volumeMounts:
+ {{- range $storage := .Spec.Storages }}
+ - mountPath: {{ $storage.Path }}
+ name: {{ $storage.Name }}
+ {{- end }}
+ {{- end }}
+
+ {{- if .Spec.Affinity }}
+ {{- $affinity := .Spec.Affinity }}
+ affinity:
+ {{- if $affinity.NodeAffinity }}
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ {{- range $requirement :=
$affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms}}
+ {{- range $matchExpression := $requirement.MatchExpressions }}
+ - matchExpressions:
+ - key: {{ $matchExpression.Key }}
+ operator: {{ $matchExpression.Operator }}
+ values:
+ {{- range $v := $matchExpression.Values }}
+ - {{ $v }}
+ {{- end}}
+ {{- end}}
+ {{- end}}
+ {{- end}}
+
+ {{- if $affinity.PodAffinity }}
+ podAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ {{- range $term :=
$affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution }}
+ - topologyKey: {{ $term.TopologyKey }}
+ namespaces:
+ {{- range $ns := $term.Namespaces }}
+ - {{ $ns }}
+ {{- end }}
+ labelSelector:
+ MatchLabels:
+ {{- range $key, $value := $term.LabelSelector.MatchLabels }}
+ {{ $key }} : {{ $value }}
+ {{- end}}
+ {{- end}}
+
+ {{- end}}
+ {{- end}}
+
+
+
diff --git
a/operator/pkg/operator/manifests/banyandb/templates/grpc_service.yaml
b/operator/pkg/operator/manifests/banyandb/templates/grpc_service.yaml
new file mode 100644
index 0000000..2869bf2
--- /dev/null
+++ b/operator/pkg/operator/manifests/banyandb/templates/grpc_service.yaml
@@ -0,0 +1,58 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+{{- if .Spec.GRPCSvc }}
+
+{{- $svc := .Spec.GRPCSvc.Template }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Name }}-banyandb-grpc
+ namespace: {{ .Namespace }}
+ labels:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ operator.skywalking.apache.org/application: banyandb
+ operator.skywalking.apache.org/component: service
+spec:
+ type: {{ $svc.Type }}
+ selector:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ ports:
+ - port: 17912
+ name: grpc
+
+ {{- if $svc.ExternalIPs }}
+ externalIPs:
+ {{- range $value := $svc.ExternalIPs }}
+ - {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+
+ {{- if $svc.LoadBalancerIP }}
+ loadBalancerIP: {{ $svc.LoadBalancerIP }}
+ {{- end }}
+
+ {{- if $svc.LoadBalancerSourceRanges }}
+ loadBalancerSourceRanges:
+ {{- range $value := $svc.LoadBalancerSourceRanges }}
+ - {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+
+{{- end }}
diff --git
a/operator/pkg/operator/manifests/banyandb/templates/http_service.yaml
b/operator/pkg/operator/manifests/banyandb/templates/http_service.yaml
new file mode 100644
index 0000000..f57aadc
--- /dev/null
+++ b/operator/pkg/operator/manifests/banyandb/templates/http_service.yaml
@@ -0,0 +1,58 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+{{- if .Spec.HTTPSvc}}
+
+{{- $svc := .Spec.HTTPSvc.Template }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Name }}-banyandb-http
+ namespace: {{ .Namespace }}
+ labels:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ operator.skywalking.apache.org/application: banyandb
+ operator.skywalking.apache.org/component: service
+spec:
+ type: {{ $svc.Type }}
+ selector:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ ports:
+ - port: 17913
+ name: http
+
+ {{- if $svc.ExternalIPs }}
+ externalIPs:
+ {{- range $value := $svc.ExternalIPs }}
+ - {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+
+ {{- if $svc.LoadBalancerIP }}
+ loadBalancerIP: {{ $svc.LoadBalancerIP }}
+ {{- end }}
+
+ {{- if $svc.LoadBalancerSourceRanges }}
+ loadBalancerSourceRanges:
+ {{- range $value := $svc.LoadBalancerSourceRanges }}
+ - {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+
+{{- end}}
\ No newline at end of file
diff --git a/operator/pkg/operator/manifests/banyandb/templates/ingress.yaml
b/operator/pkg/operator/manifests/banyandb/templates/ingress.yaml
new file mode 100644
index 0000000..0d09d86
--- /dev/null
+++ b/operator/pkg/operator/manifests/banyandb/templates/ingress.yaml
@@ -0,0 +1,53 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+{{- $ingress := .Spec.HTTPSvc.Ingress }}
+{{ if $ingress.Host }}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ .Name }}-banyandb
+ namespace: {{ .Namespace }}
+ labels:
+ app: ui
+ operator.skywalking.apache.org/ui-name: {{ .Name }}
+ operator.skywalking.apache.org/application: ui
+ operator.skywalking.apache.org/component: deployment
+ annotations:
+ {{- range $key, $value := $ingress.Annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ rules:
+ - host: {{ $ingress.Host }}
+ http:
+ paths:
+ - backend:
+ service:
+ name: {{ .Name }}-banyandb-http
+ port:
+ number: 17913
+ path: /
+ pathType: Prefix
+ {{- if $ingress.IngressClassName }}
+ ingressClassName: {{ $ingress.IngressClassName }}
+ {{end}}
+ {{- if $ingress.TLS }}
+ tls:
+ {{ toYAML $ingress.TLS | indent 4 }}
+ {{end}}
+ {{end}}
\ No newline at end of file
diff --git a/operator/pkg/operator/manifests/banyandb/templates/pvc.yaml
b/operator/pkg/operator/manifests/banyandb/templates/pvc.yaml
new file mode 100644
index 0000000..19c555c
--- /dev/null
+++ b/operator/pkg/operator/manifests/banyandb/templates/pvc.yaml
@@ -0,0 +1,64 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+{{- $banyandb := .}}
+{{- range $storage := .Spec.Storages }}
+
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: {{ $storage.Name }}-banyandb
+ namespace: {{ $banyandb.Namespace }}
+ labels:
+ app: banyandb
+ operator.skywalking.apache.org/banyandb-name: {{ .Name }}
+ operator.skywalking.apache.org/application: banyandb
+ operator.skywalking.apache.org/component: persistentVolumeClaim
+spec:
+ {{- $spec := $storage.PersistentVolumeClaimSpec }}
+
+ {{- if $spec.AccessModes }}
+ accessModes:
+ {{- range $spec.AccessModes }}
+ - {{ . }}
+ {{- end }}
+ {{- end }}
+
+ {{- if $spec.Resources }}
+ resources:
+ {{- if $spec.Resources.Requests }}
+ requests:
+ {{- if $spec.Resources.Requests.Storage }}
+ storage: {{ $spec.Resources.Requests.Storage }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+
+ {{- if $spec.VolumeName }}
+ volumeName: {{ $spec.VolumeName }}
+ {{- end }}
+
+ {{- if $spec.StorageClassName }}
+ storageClassName: {{ $spec.StorageClassName }}
+ {{- end }}
+
+ {{- if $spec.VolumeMode }}
+ volumeMode: {{ $spec.VolumeMode }}
+ {{- end }}
+
+{{- end }}
\ No newline at end of file
diff --git
a/operator/pkg/operator/manifests/banyandb/templates/service_account.yaml
b/operator/pkg/operator/manifests/banyandb/templates/service_account.yaml
new file mode 100644
index 0000000..078d8d9
--- /dev/null
+++ b/operator/pkg/operator/manifests/banyandb/templates/service_account.yaml
@@ -0,0 +1,27 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ .Name }}-banyandb
+ namespace: {{ .Namespace }}
+ labels:
+ operator.skywalking.apache.org/oap-server-name: {{ .Name }}
+ operator.skywalking.apache.org/application: banyandb
+ operator.skywalking.apache.org/component: rbac
+
diff --git a/operator/pkg/operator/manifests/repo.go
b/operator/pkg/operator/manifests/repo.go
index a263b6f..769697f 100644
--- a/operator/pkg/operator/manifests/repo.go
+++ b/operator/pkg/operator/manifests/repo.go
@@ -28,7 +28,7 @@ import (
var _ kubernetes.Repo = &AssetsRepo{}
-//go:embed fetcher injector oapserver satellite storage ui
+//go:embed fetcher injector oapserver satellite storage ui banyandb
var manifests embed.FS
// AssetsRepo provides templates through assets
diff --git a/test/e2e/banyandb/e2e.yaml b/test/e2e/banyandb/e2e.yaml
new file mode 100644
index 0000000..3b95616
--- /dev/null
+++ b/test/e2e/banyandb/e2e.yaml
@@ -0,0 +1,110 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+setup:
+ env: kind
+ file: ../kind.yaml
+ steps:
+ - name: prepare e2e.yaml
+ command: bash hack/prepare-e2e.sh
+ - name: install cert-manager
+ command: |
+ # kind k8s cluster is in $TMPDIR
+ export KUBECONFIG=$TMPDIR/e2e-k8s.config
+ kubectl apply -f
https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml
+ wait:
+ - namespace: cert-manager
+ resource: pod
+ for: condition=Ready
+ - name: install operator
+ command: |
+ export OPERATOR_IMG=controller
+ make -C operator docker-build
+ kind load docker-image controller
+ make -C operator install
+ make -C operator deploy
+ wait:
+ - namespace: skywalking-swck-system
+ resource: pod
+ for: condition=Ready
+ - name: label control plane for banyandb affinity test
+ command: |
+ kubectl label nodes kind-control-plane storage=banyandb
+ - name: remove taint on control plane and enable shedule
+ command: |
+ kubectl taint nodes kind-control-plane node-role.kubernetes.io/master-
+ - name: setup banyandb
+ command: |
+ kubectl apply -f test/e2e/deploy-banyandb.yaml
+ - name: setup oapserver and ui
+ command: |
+ kubectl create namespace skywalking-system
+ kubectl apply -f test/e2e/skywalking-components-with-banyandb.yaml
+ wait:
+ - namespace: default
+ resource: OAPServer/default
+ for: condition=Available
+ - namespace: skywalking-system
+ resource: UI/skywalking-system
+ for: condition=Available
+ - name: setup java agent demo
+ command: |
+ kubectl label namespace skywalking-system swck-injection=enabled
+ sed 's/oap-service/default-oap.default/' test/e2e/demo.yaml | kubectl
create -f -
+ wait:
+ - namespace: skywalking-system
+ resource: deployment/demo
+ for: condition=Available
+ kind:
+ expose-ports:
+ - namespace: skywalking-system
+ resource: service/demo
+ port: 8085
+ - namespace: default
+ resource: service/default-oap
+ port: 12800
+ - namespace: default
+ resource: service/banyandb-test-banyandb-grpc
+ port: 17912
+ - namespace: skywalking-system
+ resource: service/skywalking-system-ui
+ port: 80
+ timeout: 20m
+
+cleanup:
+ on: always
+
+trigger:
+ action: http
+ interval: 10s
+ times: 5
+ url: http://${service_demo_host}:${service_demo_8085}/hello
+ method: GET
+
+verify:
+ # verify with retry strategy
+ retry:
+ # max retry count
+ count: 10
+ # the interval between two attempts, e.g. 10s, 1m.
+ interval: 10s
+ cases:
+ - includes:
+ - ../oapserver-cases.yaml
+ - ../ui-cases.yaml
+
+ # verify the affinity works: banyandb is scheduled to control-plane
+ - query: kubectl get pods -l app=banyandb -o yaml | yq e
''.items[0].spec.nodeName''
+ expected: ../verify/affinity.yaml
\ No newline at end of file
diff --git a/test/e2e/deploy-banyandb.yaml b/test/e2e/deploy-banyandb.yaml
new file mode 100644
index 0000000..81252a5
--- /dev/null
+++ b/test/e2e/deploy-banyandb.yaml
@@ -0,0 +1,66 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+apiVersion: operator.skywalking.apache.org/v1alpha1
+kind: BanyanDB
+metadata:
+ name: banyandb-test
+spec:
+ version: 1.0.0
+ counts: 1
+ image: apache/skywalking-banyandb:latest
+ config:
+ - "standalone"
+ - "--measure-root-path=/data/banyandb"
+ - "--metadata-root-path=/data/banyandb"
+ storages:
+ - name: banyandb-volume
+ path: "/data/banyandb"
+ persistentVolumeClaimSpec:
+ resources:
+ requests:
+ storage: 1Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: storage
+ operator: In
+ values:
+ - banyandb
+
+
+---
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: banyandb-pv
+ labels:
+ type: local
+spec:
+ capacity:
+ storage: 1Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Recycle
+ hostPath:
+ path: "/tmp/banyandb/data1"
diff --git a/test/e2e/skywalking-components-with-banyandb.yaml
b/test/e2e/skywalking-components-with-banyandb.yaml
new file mode 100644
index 0000000..1d8ba20
--- /dev/null
+++ b/test/e2e/skywalking-components-with-banyandb.yaml
@@ -0,0 +1,50 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+apiVersion: operator.skywalking.apache.org/v1alpha1
+kind: OAPServer
+metadata:
+ name: default
+spec:
+ version: 9.2.0
+ instances: 1
+ image: apache/skywalking-oap-server:9.2.0
+ service:
+ template:
+ type: ClusterIP
+ config:
+ - name: SW_STORAGE_BANYANDB_HOST
+ value: banyandb-test-banyandb-grpc.default.svc.cluster.local
+ - name: SW_STORAGE
+ value: banyandb
+---
+apiVersion: operator.skywalking.apache.org/v1alpha1
+kind: UI
+metadata:
+ name: skywalking-system
+ namespace: skywalking-system
+spec:
+ version: 9.0.0
+ instances: 1
+ image: apache/skywalking-ui:9.0.0
+ OAPServerAddress: http://default-oap.default:12800
+ service:
+ template:
+ type: ClusterIP
+ ingress:
+ host: demo.ui.skywalking
+
\ No newline at end of file
diff --git a/test/e2e/verify/affinity.yaml b/test/e2e/verify/affinity.yaml
new file mode 100644
index 0000000..c33ae72
--- /dev/null
+++ b/test/e2e/verify/affinity.yaml
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+kind-control-plane