-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Add Go operator (#7)
This is the 1st version of the operator written in Go. Using these operator, users can interact with the cluster. The operator consists of CustomResource, represented by CustomResourceDefinition and controller loop, also called reconciliation loop. Coordinators and data instances are created as StatefulSets. Each coordinator and data instance have two services attached to it, ClusterIP and NodePort. ClusterIP is used for internal communication between instances and NodePort for external access to the Bolt server. Controller tests are deleted since they weren't used. Setup job runs as Deployment. License and organization name should be user-provided in the form of Kubernetes Secret.
Showing
37 changed files
with
2,875 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file | ||
# Ignore build and test binaries. | ||
bin/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
as51340 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,5 @@ bin | |
*.swp | ||
*.swo | ||
*~ | ||
|
||
./manager |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
[submodule "helm-charts"] | ||
path = helm-charts | ||
url = https://github.com/memgraph/helm-charts.git | ||
url = https://github.com/memgraph/helm-charts.git | ||
branch = main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
run: | ||
deadline: 5m | ||
allow-parallel-runners: true | ||
|
||
issues: | ||
# don't skip warning about doc comments | ||
# don't exclude the default set of lint | ||
exclude-use-default: false | ||
# restore some of the defaults | ||
# (fill in the rest as needed) | ||
exclude-rules: | ||
- path: "api/*" | ||
linters: | ||
- lll | ||
- path: "internal/*" | ||
linters: | ||
- dupl | ||
- lll | ||
linters: | ||
disable-all: true | ||
enable: | ||
- dupl | ||
- errcheck | ||
- exportloopref | ||
- goconst | ||
- gocyclo | ||
- gofmt | ||
- goimports | ||
- gosimple | ||
- govet | ||
- ineffassign | ||
- lll | ||
- misspell | ||
- nakedret | ||
- prealloc | ||
- staticcheck | ||
- typecheck | ||
- unconvert | ||
- unparam | ||
- unused |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,33 @@ | ||
# Build the manager binary | ||
FROM quay.io/operator-framework/helm-operator:v1.35.0 | ||
FROM golang:1.22 AS builder | ||
ARG TARGETOS | ||
ARG TARGETARCH | ||
|
||
ENV HOME=/opt/helm | ||
COPY watches.yaml ${HOME}/watches.yaml | ||
COPY helm-charts ${HOME}/helm-charts | ||
WORKDIR ${HOME} | ||
WORKDIR /workspace | ||
# Copy the Go Modules manifests | ||
COPY go.mod go.mod | ||
COPY go.sum go.sum | ||
# cache deps before building and copying source so that we don't need to re-download as much | ||
# and so that source changes don't invalidate our downloaded layer | ||
RUN go mod download | ||
|
||
# Copy the go source | ||
COPY cmd/main.go cmd/main.go | ||
COPY api/ api/ | ||
COPY internal/controller/ internal/controller/ | ||
|
||
# Build | ||
# the GOARCH has not a default value to allow the binary be built according to the host where the command | ||
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO | ||
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, | ||
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. | ||
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go | ||
|
||
# Use distroless as minimal base image to package the manager binary | ||
# Refer to https://github.com/GoogleContainerTools/distroless for more details | ||
FROM gcr.io/distroless/static:nonroot | ||
WORKDIR / | ||
COPY --from=builder /workspace/manager . | ||
USER 65532:65532 | ||
|
||
ENTRYPOINT ["/manager"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
// Package v1 contains API Schema definitions for the memgraph v1 API group | ||
// +kubebuilder:object:generate=true | ||
// +groupName=memgraph.com | ||
package v1 | ||
|
||
import ( | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
"sigs.k8s.io/controller-runtime/pkg/scheme" | ||
) | ||
|
||
var ( | ||
// GroupVersion is group version used to register these objects | ||
GroupVersion = schema.GroupVersion{Group: "memgraph.com", Version: "v1"} | ||
|
||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme | ||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} | ||
|
||
/* AddToScheme adds the types in this group-version to the given scheme. | ||
Scheme is an abstraction used in the API Machinery to create a mapping between Go | ||
structures and Group-Version-Kinds. | ||
*/ | ||
AddToScheme = SchemeBuilder.AddToScheme | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
/* | ||
In some way this file simulates types.go from k8s.io/api/apps/v1 to define new resources | ||
we are using. | ||
*/ | ||
|
||
package v1 | ||
|
||
import ( | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! | ||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. | ||
|
||
// MemgraphHASpec defines the desired state of MemgraphHA | ||
type MemgraphHASpec struct { | ||
Coordinators []Coordinator `json:"coordinators"` | ||
Data []DataItem `json:"data"` | ||
Memgraph MemgraphConfig `json:"memgraph"` | ||
} | ||
|
||
type Coordinator struct { | ||
ID string `json:"id"` | ||
BoltPort int `json:"boltPort"` | ||
ManagementPort int `json:"managementPort"` | ||
CoordinatorPort int `json:"coordinatorPort"` | ||
Args []string `json:"args"` | ||
} | ||
|
||
type DataItem struct { | ||
ID string `json:"id"` | ||
BoltPort int `json:"boltPort"` | ||
ManagementPort int `json:"managementPort"` | ||
ReplicationPort int `json:"replicationPort"` | ||
Args []string `json:"args"` | ||
} | ||
|
||
type MemgraphConfig struct { | ||
Data MemgraphDataConfig `json:"data"` | ||
Coordinators MemgraphCoordinatorsConfig `json:"coordinators"` | ||
Env map[string]string `json:"env"` | ||
Image ImageConfig `json:"image"` | ||
Probes MemgraphProbesConfig `json:"probes"` | ||
} | ||
|
||
type MemgraphDataConfig struct { | ||
VolumeClaim VolumeClaimConfig `json:"volumeClaim"` | ||
} | ||
|
||
type MemgraphCoordinatorsConfig struct { | ||
VolumeClaim VolumeClaimConfig `json:"volumeClaim"` | ||
} | ||
|
||
type VolumeClaimConfig struct { | ||
StoragePVCClassName string `json:"storagePVCClassName"` | ||
StoragePVC bool `json:"storagePVC"` | ||
StoragePVCSize string `json:"storagePVCSize"` | ||
LogPVCClassName string `json:"logPVCClassName"` | ||
LogPVC bool `json:"logPVC"` | ||
LogPVCSize string `json:"logPVCSize"` | ||
} | ||
|
||
type ImageConfig struct { | ||
PullPolicy string `json:"pullPolicy"` | ||
Repository string `json:"repository"` | ||
Tag string `json:"tag"` | ||
} | ||
|
||
type MemgraphProbesConfig struct { | ||
Liveness ProbeConfig `json:"liveness"` | ||
Readiness ProbeConfig `json:"readiness"` | ||
Startup ProbeConfig `json:"startup"` | ||
} | ||
|
||
// ProbeConfig configures individual probes | ||
type ProbeConfig struct { | ||
InitialDelaySeconds int `json:"initialDelaySeconds"` | ||
PeriodSeconds int `json:"periodSeconds"` | ||
FailureThreshold int `json:"failureThreshold,omitempty"` | ||
} | ||
|
||
// MemgraphHAStatus defines the observed state of MemgraphHA | ||
type MemgraphHAStatus struct { | ||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster | ||
// Important: Run "make" to regenerate code after modifying this file | ||
} | ||
|
||
//+kubebuilder:object:root=true | ||
//+kubebuilder:subresource:status | ||
|
||
// MemgraphHA is the Schema for the memgraphhas API | ||
/* | ||
Every Kind needs to have two structures: metav1.TypeMeta and metav1.ObjectMeta. | ||
TypeMeta structure contains information about the GVK of the Kind. | ||
ObjectMeta contains metadata for the Kind. | ||
*/ | ||
type MemgraphHA struct { | ||
metav1.TypeMeta `json:",inline"` | ||
metav1.ObjectMeta `json:"metadata,omitempty"` | ||
|
||
Spec MemgraphHASpec `json:"spec,omitempty"` | ||
Status MemgraphHAStatus `json:"status,omitempty"` | ||
} | ||
|
||
//+kubebuilder:object:root=true | ||
|
||
// MemgraphHAList contains a list of MemgraphHA | ||
type MemgraphHAList struct { | ||
metav1.TypeMeta `json:",inline"` | ||
metav1.ListMeta `json:"metadata,omitempty"` | ||
Items []MemgraphHA `json:"items"` | ||
} | ||
|
||
func init() { | ||
SchemeBuilder.Register(&MemgraphHA{}, &MemgraphHAList{}) | ||
} |
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"crypto/tls" | ||
"flag" | ||
"os" | ||
|
||
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) | ||
// to ensure that exec-entrypoint and run can make use of them. | ||
_ "k8s.io/client-go/plugin/pkg/client/auth" | ||
|
||
"k8s.io/apimachinery/pkg/runtime" | ||
utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||
clientgoscheme "k8s.io/client-go/kubernetes/scheme" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/healthz" | ||
"sigs.k8s.io/controller-runtime/pkg/log/zap" | ||
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" | ||
"sigs.k8s.io/controller-runtime/pkg/webhook" | ||
|
||
memgraphv1 "github.com/memgraph/kubernetes-operator/api/v1" | ||
"github.com/memgraph/kubernetes-operator/internal/controller" | ||
//+kubebuilder:scaffold:imports | ||
) | ||
|
||
var ( | ||
scheme = runtime.NewScheme() | ||
setupLog = ctrl.Log.WithName("setup") | ||
) | ||
|
||
func init() { | ||
utilruntime.Must(clientgoscheme.AddToScheme(scheme)) | ||
|
||
utilruntime.Must(memgraphv1.AddToScheme(scheme)) | ||
//+kubebuilder:scaffold:scheme | ||
} | ||
|
||
func main() { | ||
var metricsAddr string | ||
var probeAddr string | ||
var secureMetrics bool | ||
var enableHTTP2 bool | ||
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") | ||
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") | ||
flag.BoolVar(&secureMetrics, "metrics-secure", false, | ||
"If set the metrics endpoint is served securely") | ||
flag.BoolVar(&enableHTTP2, "enable-http2", false, | ||
"If set, HTTP/2 will be enabled for the metrics and webhook servers") | ||
opts := zap.Options{ | ||
Development: true, | ||
} | ||
opts.BindFlags(flag.CommandLine) | ||
flag.Parse() | ||
|
||
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) | ||
|
||
// if the enable-http2 flag is false (the default), http/2 should be disabled | ||
// due to its vulnerabilities. More specifically, disabling http/2 will | ||
// prevent from being vulnerable to the HTTP/2 Stream Cancelation and | ||
// Rapid Reset CVEs. For more information see: | ||
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 | ||
// - https://github.com/advisories/GHSA-4374-p667-p6c8 | ||
disableHTTP2 := func(c *tls.Config) { | ||
setupLog.Info("disabling http/2") | ||
c.NextProtos = []string{"http/1.1"} | ||
} | ||
|
||
tlsOpts := []func(*tls.Config){} | ||
if !enableHTTP2 { | ||
tlsOpts = append(tlsOpts, disableHTTP2) | ||
} | ||
|
||
webhookServer := webhook.NewServer(webhook.Options{ | ||
TLSOpts: tlsOpts, | ||
}) | ||
|
||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ | ||
Scheme: scheme, | ||
Metrics: metricsserver.Options{ | ||
BindAddress: metricsAddr, | ||
SecureServing: secureMetrics, | ||
TLSOpts: tlsOpts, | ||
}, | ||
WebhookServer: webhookServer, | ||
HealthProbeBindAddress: probeAddr, | ||
}) | ||
if err != nil { | ||
setupLog.Error(err, "unable to start manager") | ||
os.Exit(1) | ||
} | ||
|
||
if err = (&controller.MemgraphHAReconciler{ | ||
Client: mgr.GetClient(), | ||
Scheme: mgr.GetScheme(), | ||
}).SetupWithManager(mgr); err != nil { | ||
setupLog.Error(err, "unable to create controller", "controller", "MemgraphHA") | ||
os.Exit(1) | ||
} | ||
//+kubebuilder:scaffold:builder | ||
|
||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { | ||
setupLog.Error(err, "unable to set up health check") | ||
os.Exit(1) | ||
} | ||
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { | ||
setupLog.Error(err, "unable to set up ready check") | ||
os.Exit(1) | ||
} | ||
|
||
setupLog.Info("starting manager") | ||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { | ||
setupLog.Error(err, "problem running manager") | ||
os.Exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# This file is for teaching kustomize how to substitute name and namespace reference in CRD | ||
nameReference: | ||
- kind: Service | ||
version: v1 | ||
fieldSpecs: | ||
- kind: CustomResourceDefinition | ||
version: v1 | ||
group: apiextensions.k8s.io | ||
path: spec/conversion/webhook/clientConfig/service/name | ||
|
||
namespace: | ||
- kind: CustomResourceDefinition | ||
version: v1 | ||
group: apiextensions.k8s.io | ||
path: spec/conversion/webhook/clientConfig/service/namespace | ||
create: false | ||
|
||
varReference: | ||
- path: metadata/annotations |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
resources: | ||
- namespace.yaml | ||
- manager.yaml | ||
- namespace.yaml | ||
apiVersion: kustomize.config.k8s.io/v1beta1 | ||
kind: Kustomization | ||
images: | ||
- name: controller | ||
newName: memgraph/kubernetes-operator | ||
newTag: 0.0.4 | ||
- name: memgraph-kubernetes-operator | ||
newName: memgraph/kubernetes-operator | ||
newTag: 0.0.3 | ||
newTag: 0.0.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
module github.com/memgraph/kubernetes-operator | ||
|
||
go 1.22.0 | ||
|
||
toolchain go1.22.5 | ||
|
||
require ( | ||
github.com/go-logr/logr v1.4.2 | ||
github.com/onsi/ginkgo/v2 v2.19.0 | ||
github.com/onsi/gomega v1.33.1 | ||
k8s.io/api v0.30.3 | ||
k8s.io/apimachinery v0.30.3 | ||
k8s.io/client-go v0.30.3 | ||
sigs.k8s.io/controller-runtime v0.18.4 | ||
) | ||
|
||
require ( | ||
github.com/beorn7/perks v1.0.1 // indirect | ||
github.com/cespare/xxhash/v2 v2.3.0 // indirect | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/emicklei/go-restful/v3 v3.12.1 // indirect | ||
github.com/evanphx/json-patch/v5 v5.9.0 // indirect | ||
github.com/fsnotify/fsnotify v1.7.0 // indirect | ||
github.com/go-logr/zapr v1.3.0 // indirect | ||
github.com/go-openapi/jsonpointer v0.21.0 // indirect | ||
github.com/go-openapi/jsonreference v0.21.0 // indirect | ||
github.com/go-openapi/swag v0.23.0 // indirect | ||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect | ||
github.com/gogo/protobuf v1.3.2 // indirect | ||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | ||
github.com/golang/protobuf v1.5.4 // indirect | ||
github.com/google/gnostic-models v0.6.8 // indirect | ||
github.com/google/go-cmp v0.6.0 // indirect | ||
github.com/google/gofuzz v1.2.0 // indirect | ||
github.com/google/pprof v0.0.0-20240722153945-304e4f0156b8 // indirect | ||
github.com/google/uuid v1.6.0 // indirect | ||
github.com/imdario/mergo v0.3.16 // indirect | ||
github.com/josharian/intern v1.0.0 // indirect | ||
github.com/json-iterator/go v1.1.12 // indirect | ||
github.com/mailru/easyjson v0.7.7 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/prometheus/client_golang v1.19.1 // indirect | ||
github.com/prometheus/client_model v0.6.1 // indirect | ||
github.com/prometheus/common v0.55.0 // indirect | ||
github.com/prometheus/procfs v0.15.1 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
go.uber.org/multierr v1.11.0 // indirect | ||
go.uber.org/zap v1.27.0 // indirect | ||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect | ||
golang.org/x/net v0.27.0 // indirect | ||
golang.org/x/oauth2 v0.21.0 // indirect | ||
golang.org/x/sys v0.22.0 // indirect | ||
golang.org/x/term v0.22.0 // indirect | ||
golang.org/x/text v0.16.0 // indirect | ||
golang.org/x/time v0.5.0 // indirect | ||
golang.org/x/tools v0.23.0 // indirect | ||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect | ||
google.golang.org/protobuf v1.34.2 // indirect | ||
gopkg.in/inf.v0 v0.9.1 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
k8s.io/apiextensions-apiserver v0.30.3 // indirect | ||
k8s.io/klog/v2 v2.130.1 // indirect | ||
k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f // indirect | ||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect | ||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect | ||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect | ||
sigs.k8s.io/yaml v1.4.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | ||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | ||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= | ||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= | ||
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= | ||
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= | ||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= | ||
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= | ||
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= | ||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= | ||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= | ||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= | ||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= | ||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= | ||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= | ||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= | ||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= | ||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= | ||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= | ||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= | ||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= | ||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= | ||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= | ||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= | ||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= | ||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= | ||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= | ||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= | ||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= | ||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= | ||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= | ||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= | ||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||
github.com/google/pprof v0.0.0-20240722153945-304e4f0156b8 h1:ssNFCCVmib/GQSzx3uCWyfMgOamLGWuGqlMS77Y1m3Y= | ||
github.com/google/pprof v0.0.0-20240722153945-304e4f0156b8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= | ||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | ||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= | ||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= | ||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= | ||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= | ||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= | ||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= | ||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= | ||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | ||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | ||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= | ||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= | ||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= | ||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= | ||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= | ||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= | ||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= | ||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= | ||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= | ||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= | ||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= | ||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= | ||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= | ||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= | ||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= | ||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= | ||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= | ||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= | ||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= | ||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= | ||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= | ||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= | ||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= | ||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | ||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= | ||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= | ||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= | ||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= | ||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= | ||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= | ||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= | ||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= | ||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= | ||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= | ||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= | ||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= | ||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= | ||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= | ||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ= | ||
k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04= | ||
k8s.io/apiextensions-apiserver v0.30.3 h1:oChu5li2vsZHx2IvnGP3ah8Nj3KyqG3kRSaKmijhB9U= | ||
k8s.io/apiextensions-apiserver v0.30.3/go.mod h1:uhXxYDkMAvl6CJw4lrDN4CPbONkF3+XL9cacCT44kV4= | ||
k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc= | ||
k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= | ||
k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k= | ||
k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U= | ||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= | ||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= | ||
k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f h1:2sXuKesAYbRHxL3aE2PN6zX/gcJr22cjrsej+W784Tc= | ||
k8s.io/kube-openapi v0.0.0-20240709000822-3c01b740850f/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= | ||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= | ||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= | ||
sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= | ||
sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= | ||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= | ||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= | ||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= | ||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= | ||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= | ||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package controller | ||
|
||
var boltPort int = 7687 | ||
var coordinatorPort int = 12000 | ||
var mgmtPort int = 10000 | ||
var replicationPort int = 20000 | ||
var image string = "memgraph/memgraph:2.18.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package controller | ||
|
||
import ( | ||
"context" | ||
|
||
"k8s.io/apimachinery/pkg/api/errors" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/log" | ||
|
||
memgraphv1 "github.com/memgraph/kubernetes-operator/api/v1" | ||
) | ||
|
||
//+kubebuilder:rbac:groups=memgraph.com,resources=memgraphhas,verbs=get;list;watch;create;update;patch;delete | ||
//+kubebuilder:rbac:groups=memgraph.com,resources=memgraphhas/status,verbs=get;update;patch | ||
//+kubebuilder:rbac:groups=memgraph.com,resources=memgraphhas/finalizers,verbs=update | ||
|
||
// For more details, check Reconcile and its Result here: | ||
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.3/pkg/reconcile | ||
func (r *MemgraphHAReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { | ||
logger := log.FromContext(ctx) | ||
|
||
memgraphha := &memgraphv1.MemgraphHA{} | ||
err := r.Get(ctx, req.NamespacedName, memgraphha) | ||
if err != nil { | ||
if errors.IsNotFound(err) { | ||
logger.Info("MemgraphHA resource not found. Ignoring since object must be deleted.") | ||
return ctrl.Result{}, nil | ||
} | ||
logger.Error(err, "Failed to get MemgraphHA") | ||
return ctrl.Result{}, err | ||
} | ||
|
||
logger.Info("Started reconciliation MemgrahHA") | ||
|
||
for coordId := 1; coordId <= 3; coordId++ { | ||
// ClusterIP | ||
coordClusterIPStatus, coordClusterIPErr := r.reconcileCoordClusterIPService(ctx, memgraphha, &logger, coordId) | ||
if coordClusterIPErr != nil { | ||
logger.Info("Error returned when reconciling ClusterIP Returning empty Result with error.", "coordId", coordId) | ||
return ctrl.Result{}, coordClusterIPErr | ||
} | ||
|
||
if coordClusterIPStatus == true { | ||
logger.Info("ClusterIP has been created. Returning Result with the request for requeing with error set to nil.", "coordId", coordId) | ||
return ctrl.Result{Requeue: true}, nil | ||
} | ||
|
||
// NodePort | ||
coordNodePortStatus, coordNodePortErr := r.reconcileCoordNodePortService(ctx, memgraphha, &logger, coordId) | ||
if coordNodePortErr != nil { | ||
logger.Info("Error returned when reconciling NodePort. Returning empty Result with error.", "coordId", coordId) | ||
return ctrl.Result{}, coordNodePortErr | ||
} | ||
|
||
if coordNodePortStatus == true { | ||
logger.Info("NodePort has been created. Returning Result with the request for requeing with error set to nil.", "coordId", coordId) | ||
return ctrl.Result{Requeue: true}, nil | ||
} | ||
|
||
// Coordinator | ||
coordStatus, coordErr := r.reconcileCoordinator(ctx, memgraphha, &logger, coordId) | ||
if coordErr != nil { | ||
logger.Info("Error returned when reconciling coordinator. Returning empty Result with error.", "coordId", coordId) | ||
return ctrl.Result{}, coordErr | ||
} | ||
|
||
if coordStatus == true { | ||
logger.Info("Coordinator has been created. Returning Result with the request for requeing with error set to nil.", "coordId", coordId) | ||
return ctrl.Result{Requeue: true}, nil | ||
} | ||
} | ||
|
||
logger.Info("Reconciliation of coordinators finished without actions needed.") | ||
|
||
for dataInstanceId := 0; dataInstanceId <= 1; dataInstanceId++ { | ||
// ClusterIP | ||
dataInstanceClusterIPStatus, dataInstanceClusterIPErr := r.reconcileDataInstanceClusterIPService(ctx, memgraphha, &logger, dataInstanceId) | ||
if dataInstanceClusterIPErr != nil { | ||
logger.Info("Error returned when reconciling ClusterIP. Returning empty Result with error.", "dataInstanceId", dataInstanceId) | ||
return ctrl.Result{}, dataInstanceClusterIPErr | ||
} | ||
|
||
if dataInstanceClusterIPStatus == true { | ||
logger.Info("ClusterIP has been created. Returning Result with the request for requeing with error set to nil.", "dataInstanceId", dataInstanceId) | ||
return ctrl.Result{Requeue: true}, nil | ||
} | ||
|
||
// NodePort | ||
dataInstanceNodePortStatus, dataInstanceNodePortErr := r.reconcileDataInstanceNodePortService(ctx, memgraphha, &logger, dataInstanceId) | ||
if dataInstanceNodePortErr != nil { | ||
logger.Info("Error returned when reconciling NodePort. Returning empty Result with error.", "dataInstanceId", dataInstanceId) | ||
return ctrl.Result{}, dataInstanceNodePortErr | ||
} | ||
|
||
if dataInstanceNodePortStatus == true { | ||
logger.Info("NodePort has been created. Returning Result with the request for requeing with error set to nil.", "dataInstanceId", dataInstanceId) | ||
return ctrl.Result{Requeue: true}, nil | ||
} | ||
|
||
// Data instance | ||
dataInstancesStatus, dataInstancesErr := r.reconcileDataInstance(ctx, memgraphha, &logger, dataInstanceId) | ||
if dataInstancesErr != nil { | ||
logger.Info("Error returned when reconciling data instance. Returning empty Result with error.", "dataInstanceId", dataInstanceId) | ||
return ctrl.Result{}, dataInstancesErr | ||
} | ||
|
||
if dataInstancesStatus == true { | ||
logger.Info("Data instance has been created. Returning Result with the request for requeing with error=nil.", "dataInstanceId", dataInstanceId) | ||
return ctrl.Result{Requeue: true}, nil | ||
} | ||
} | ||
|
||
logger.Info("Reconciliation of data instances finished without actions needed.") | ||
|
||
setupJobStatus, setupJobErr := r.reconcileSetupJob(ctx, memgraphha, &logger) | ||
if setupJobErr != nil { | ||
logger.Info("Error returned when reconciling coordinator. Returning empty Result with error.") | ||
return ctrl.Result{}, setupJobErr | ||
} | ||
|
||
// Since it is currently the last step, we don't need to requeue | ||
if setupJobStatus == true { | ||
logger.Info("SetupJob has been created.") | ||
} | ||
|
||
logger.Info("Reconciliation of MemgraphHA finished.") | ||
// The resource doesn't need to be reconciled anymore | ||
return ctrl.Result{}, nil | ||
} | ||
|
||
// SetupWithManager sets up the controller with the Manager. | ||
func (r *MemgraphHAReconciler) SetupWithManager(mgr ctrl.Manager) error { | ||
return ctrl.NewControllerManagedBy(mgr). | ||
For(&memgraphv1.MemgraphHA{}). | ||
Complete(r) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
/* | ||
copyright 2024 memgraph ltd. | ||
licensed under the apache license, version 2.0 (the "license"); | ||
you may not use this file except in compliance with the license. | ||
you may obtain a copy of the license at | ||
http://www.apache.org/licenses/license-2.0 | ||
unless required by applicable law or agreed to in writing, software | ||
distributed under the license is distributed on an "as is" basis, | ||
without warranties or conditions of any kind, either express or implied. | ||
see the license for the specific language governing permissions and | ||
limitations under the license. | ||
*/ | ||
|
||
package controller | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/go-logr/logr" | ||
memgraphv1 "github.com/memgraph/kubernetes-operator/api/v1" | ||
appsv1 "k8s.io/api/apps/v1" | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/api/errors" | ||
"k8s.io/apimachinery/pkg/api/resource" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
) | ||
|
||
/* | ||
Returns bool, error tuple. If error exists, the caller should return with error and status will always be set to true. | ||
If there is no error, we must look at bool status which when true will say that the coordinator was createdand we need to requeue | ||
or that nothing was done and we can continue with the next step of reconciliation. | ||
*/ | ||
func (r *MemgraphHAReconciler) reconcileCoordinator(ctx context.Context, memgraphha *memgraphv1.MemgraphHA, logger *logr.Logger, coordId int) (bool, error) { | ||
name := fmt.Sprintf("memgraph-coordinator-%d", coordId) | ||
logger.Info("Started reconciling", "StatefulSet", name) | ||
coordStatefulSet := &appsv1.StatefulSet{} | ||
err := r.Get(ctx, types.NamespacedName{Name: name, Namespace: memgraphha.Namespace}, coordStatefulSet) | ||
|
||
if err == nil { | ||
logger.Info("StatefulSet already exists.", "StatefulSet", name) | ||
return false, nil | ||
} | ||
|
||
if errors.IsNotFound(err) { | ||
coord := r.createStatefulSetForCoord(memgraphha, coordId) | ||
logger.Info("Creating a new StatefulSet", "StatefulSet.Namespace", coord.Namespace, "StatefulSet.Name", coord.Name) | ||
err := r.Create(ctx, coord) | ||
if err != nil { | ||
logger.Error(err, "Failed to create new StatefulSet", "StatefulSet.Namespace", coord.Namespace, "StatefulSet.Name", coord.Name) | ||
return true, err | ||
} | ||
logger.Info("StatefulSet is created.", "StatefulSet", name) | ||
return true, nil | ||
} | ||
|
||
logger.Error(err, "Failed to fetch StatefulSet", "StatefulSet", name) | ||
return true, err | ||
} | ||
|
||
func (r *MemgraphHAReconciler) createStatefulSetForCoord(memgraphha *memgraphv1.MemgraphHA, coordId int) *appsv1.StatefulSet { | ||
coordName := fmt.Sprintf("memgraph-coordinator-%d", coordId) | ||
serviceName := coordName // service has the same name as the coordinator | ||
labels := createCoordLabels(coordName) | ||
replicas := int32(1) | ||
containerName := "memgraph-coordinator" | ||
args := []string{ | ||
fmt.Sprintf("--coordinator-id=%d", coordId), | ||
fmt.Sprintf("--coordinator-port=%d", coordinatorPort), | ||
fmt.Sprintf("--management-port=%d", mgmtPort), | ||
fmt.Sprintf("--bolt-port=%d", boltPort), | ||
fmt.Sprintf("--coordinator-hostname=%s.default.svc.cluster.local", coordName), | ||
"--experimental-enabled=high-availability", | ||
"--also-log-to-stderr", | ||
"--log-level=TRACE", | ||
"--log-file=/var/log/memgraph/memgraph.log", | ||
} | ||
volumeLibName := fmt.Sprintf("%s-lib-storage", coordName) | ||
volumeLibSize := "1Gi" | ||
volumeLogName := fmt.Sprintf("%s-log-storage", coordName) | ||
volumeLogSize := "256Mi" | ||
initContainerName := "init" | ||
initContainerCommand := []string{ | ||
"/bin/sh", | ||
"-c", | ||
} | ||
initContainerArgs := []string{"chown -R memgraph:memgraph /var/log; chown -R memgraph:memgraph /var/lib"} | ||
initContainerPrivileged := true | ||
initContainerReadOnlyRootFilesystem := false | ||
initContainerRunAsNonRoot := false | ||
initContainerRunAsUser := int64(0) | ||
|
||
coord := &appsv1.StatefulSet{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: coordName, | ||
Namespace: memgraphha.Namespace, | ||
}, | ||
Spec: appsv1.StatefulSetSpec{ | ||
ServiceName: serviceName, | ||
Replicas: &replicas, | ||
Selector: &metav1.LabelSelector{ | ||
MatchLabels: labels, | ||
}, | ||
Template: corev1.PodTemplateSpec{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Labels: labels, | ||
}, | ||
Spec: corev1.PodSpec{ | ||
InitContainers: []corev1.Container{ | ||
{ | ||
Name: initContainerName, | ||
Image: image, | ||
VolumeMounts: []corev1.VolumeMount{ | ||
{ | ||
Name: volumeLibName, | ||
MountPath: "/var/lib/memgraph", | ||
}, | ||
{ | ||
Name: volumeLogName, | ||
MountPath: "/var/log/memgraph", | ||
}, | ||
}, | ||
Command: initContainerCommand, | ||
Args: initContainerArgs, | ||
SecurityContext: &corev1.SecurityContext{ | ||
Privileged: &initContainerPrivileged, | ||
ReadOnlyRootFilesystem: &initContainerReadOnlyRootFilesystem, | ||
RunAsNonRoot: &initContainerRunAsNonRoot, | ||
RunAsUser: &initContainerRunAsUser, | ||
Capabilities: &corev1.Capabilities{ | ||
Drop: []corev1.Capability{"all"}, | ||
Add: []corev1.Capability{"CHOWN"}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
Containers: []corev1.Container{{ | ||
Name: containerName, | ||
Image: image, | ||
ImagePullPolicy: corev1.PullAlways, // set to PullIfNotPresent when testing with local image | ||
Ports: []corev1.ContainerPort{ | ||
{ | ||
ContainerPort: int32(boltPort), | ||
Name: "bolt", | ||
}, | ||
{ | ||
ContainerPort: int32(mgmtPort), | ||
Name: "management", | ||
}, | ||
{ | ||
ContainerPort: int32(coordinatorPort), | ||
Name: "coordinator", | ||
}, | ||
}, | ||
Args: args, | ||
Env: []corev1.EnvVar{ | ||
{ | ||
Name: "MEMGRAPH_ENTERPRISE_LICENSE", | ||
ValueFrom: &corev1.EnvVarSource{ | ||
SecretKeyRef: &corev1.SecretKeySelector{ | ||
LocalObjectReference: corev1.LocalObjectReference{ | ||
Name: "memgraph-secrets", | ||
}, | ||
Key: "MEMGRAPH_ENTERPRISE_LICENSE", | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: "MEMGRAPH_ORGANIZATION_NAME", | ||
ValueFrom: &corev1.EnvVarSource{ | ||
SecretKeyRef: &corev1.SecretKeySelector{ | ||
LocalObjectReference: corev1.LocalObjectReference{ | ||
Name: "memgraph-secrets", | ||
}, | ||
Key: "MEMGRAPH_ORGANIZATION_NAME", | ||
}, | ||
}, | ||
}, | ||
}, | ||
VolumeMounts: []corev1.VolumeMount{ | ||
{ | ||
Name: volumeLibName, | ||
MountPath: "/var/lib/memgraph", | ||
}, | ||
{ | ||
Name: volumeLogName, | ||
MountPath: "/var/log/memgraph", | ||
}, | ||
}, | ||
}}, | ||
}, | ||
}, | ||
VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ | ||
{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: volumeLibName, | ||
}, | ||
Spec: corev1.PersistentVolumeClaimSpec{ | ||
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, | ||
Resources: corev1.VolumeResourceRequirements{ | ||
Requests: corev1.ResourceList{ | ||
corev1.ResourceStorage: resource.MustParse(volumeLibSize), | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: volumeLogName, | ||
}, | ||
Spec: corev1.PersistentVolumeClaimSpec{ | ||
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, | ||
Resources: corev1.VolumeResourceRequirements{ | ||
Requests: corev1.ResourceList{ | ||
corev1.ResourceStorage: resource.MustParse(volumeLogSize), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
ctrl.SetControllerReference(memgraphha, coord, r.Scheme) | ||
return coord | ||
} | ||
|
||
func createCoordLabels(coordName string) map[string]string { | ||
return map[string]string{"app": coordName} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package controller | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
|
||
"github.com/go-logr/logr" | ||
memgraphv1 "github.com/memgraph/kubernetes-operator/api/v1" | ||
"k8s.io/apimachinery/pkg/api/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/apimachinery/pkg/util/intstr" | ||
) | ||
|
||
func (r *MemgraphHAReconciler) reconcileCoordNodePortService(ctx context.Context, memgraphha *memgraphv1.MemgraphHA, logger *logr.Logger, coordId int) (bool, error) { | ||
serviceName := fmt.Sprintf("memgraph-coordinator-%d-external", coordId) | ||
logger.Info("Started reconciling NodePort service", "NodePort", serviceName) | ||
|
||
coordNodePortService := &corev1.Service{} | ||
err := r.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: memgraphha.Namespace}, coordNodePortService) | ||
|
||
if err == nil { | ||
logger.Info("NodePort already exists.", "NodePort", serviceName) | ||
return false, nil | ||
} | ||
|
||
if errors.IsNotFound(err) { | ||
nodePort := r.createCoordNodePort(memgraphha, coordId) | ||
logger.Info("Creating a new NodePort", "NodePort.Namespace", nodePort.Namespace, "NodePort.Name", nodePort.Name) | ||
err := r.Create(ctx, nodePort) | ||
if err != nil { | ||
logger.Error(err, "Failed to create new NodePort", "NodePort.Namespace", nodePort.Namespace, "NodePort.Name", nodePort.Name) | ||
return true, err | ||
} | ||
logger.Info("NodePort is created.", "NodePort", serviceName) | ||
return true, nil | ||
} | ||
|
||
logger.Error(err, "Failed to fetch NodePort", "NodePort", serviceName) | ||
return true, err | ||
|
||
} | ||
|
||
func (r *MemgraphHAReconciler) createCoordNodePort(memgraphha *memgraphv1.MemgraphHA, coordId int) *corev1.Service { | ||
serviceName := fmt.Sprintf("memgraph-coordinator-%d-external", coordId) | ||
coordName := fmt.Sprintf("memgraph-coordinator-%d", coordId) | ||
|
||
coordNodePort := &corev1.Service{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: serviceName, | ||
Namespace: memgraphha.Namespace, | ||
}, | ||
Spec: corev1.ServiceSpec{ | ||
Type: corev1.ServiceTypeNodePort, | ||
Selector: createCoordLabels(coordName), | ||
Ports: []corev1.ServicePort{ | ||
{ | ||
Name: "bolt", | ||
Protocol: corev1.ProtocolTCP, | ||
Port: int32(boltPort), | ||
TargetPort: intstr.FromInt(boltPort), | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
ctrl.SetControllerReference(memgraphha, coordNodePort, r.Scheme) | ||
return coordNodePort | ||
} | ||
|
||
func (r *MemgraphHAReconciler) reconcileCoordClusterIPService(ctx context.Context, memgraphha *memgraphv1.MemgraphHA, logger *logr.Logger, coordId int) (bool, error) { | ||
serviceName := fmt.Sprintf("memgraph-coordinator-%d", coordId) | ||
logger.Info("Started reconciling ClusterIP service", "ClusterIP", serviceName) | ||
|
||
coordClusterIPService := &corev1.Service{} | ||
err := r.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: memgraphha.Namespace}, coordClusterIPService) | ||
|
||
if err == nil { | ||
logger.Info("ClusterIP already exists.", "ClusterIP", serviceName) | ||
return false, nil | ||
} | ||
|
||
if errors.IsNotFound(err) { | ||
clusterIP := r.createCoordClusterIP(memgraphha, coordId) | ||
logger.Info("Creating a new ClusterIP", "ClusterIP.Namespace", clusterIP.Namespace, "ClusterIP.Name", clusterIP.Name) | ||
err := r.Create(ctx, clusterIP) | ||
if err != nil { | ||
logger.Error(err, "Failed to create new ClusterIP", "ClusterIP.Namespace", clusterIP.Namespace, "ClusterIP.Name", clusterIP.Name) | ||
return true, err | ||
} | ||
logger.Info("ClusterIP is created.", "ClusterIP", serviceName) | ||
return true, nil | ||
} | ||
|
||
logger.Error(err, "Failed to fetch ClusterIP", "ClusterIP", serviceName) | ||
return true, err | ||
|
||
} | ||
|
||
func (r *MemgraphHAReconciler) createCoordClusterIP(memgraphha *memgraphv1.MemgraphHA, coordId int) *corev1.Service { | ||
serviceName := fmt.Sprintf("memgraph-coordinator-%d", coordId) | ||
coordName := serviceName | ||
|
||
coordClusterIP := &corev1.Service{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: serviceName, | ||
Namespace: memgraphha.Namespace, | ||
}, | ||
Spec: corev1.ServiceSpec{ | ||
Type: corev1.ServiceTypeClusterIP, | ||
Selector: createCoordLabels(coordName), | ||
Ports: []corev1.ServicePort{ | ||
{ | ||
Name: "bolt", | ||
Protocol: corev1.ProtocolTCP, | ||
Port: int32(boltPort), | ||
TargetPort: intstr.FromInt(boltPort), | ||
}, | ||
{ | ||
Name: "coordinator", | ||
Protocol: corev1.ProtocolTCP, | ||
Port: int32(coordinatorPort), | ||
TargetPort: intstr.FromInt(coordinatorPort), | ||
}, | ||
{ | ||
Name: "management", | ||
Protocol: corev1.ProtocolTCP, | ||
Port: int32(mgmtPort), | ||
TargetPort: intstr.FromInt(mgmtPort), | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
ctrl.SetControllerReference(memgraphha, coordClusterIP, r.Scheme) | ||
return coordClusterIP | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
/* | ||
Copyright 2024 Memgraph Ltd. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package controller | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/go-logr/logr" | ||
memgraphv1 "github.com/memgraph/kubernetes-operator/api/v1" | ||
appsv1 "k8s.io/api/apps/v1" | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/api/errors" | ||
"k8s.io/apimachinery/pkg/api/resource" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
) | ||
|
||
func (r *MemgraphHAReconciler) reconcileDataInstance(ctx context.Context, memgraphha *memgraphv1.MemgraphHA, logger *logr.Logger, dataInstanceId int) (bool, error) { | ||
name := fmt.Sprintf("memgraph-data-%d", dataInstanceId) | ||
logger.Info("Started reconciling", "StatefulSet", name) | ||
dataInstanceStatefulSet := &appsv1.StatefulSet{} | ||
err := r.Get(ctx, types.NamespacedName{Name: name, Namespace: memgraphha.Namespace}, dataInstanceStatefulSet) | ||
|
||
if err == nil { | ||
logger.Info("StatefulSet already exists.", "StatefulSet", name) | ||
return false, nil | ||
} | ||
|
||
if errors.IsNotFound(err) { | ||
dataInstance := r.createStatefulSetForDataInstance(memgraphha, dataInstanceId) | ||
logger.Info("Creating a new StatefulSet", "StatefulSet.Namespace", dataInstance.Namespace, "StatefulSet.Name", dataInstance.Name) | ||
err := r.Create(ctx, dataInstance) | ||
if err != nil { | ||
logger.Error(err, "Failed to create new StatefulSet", "StatefulSet.Namespace", dataInstance.Namespace, "StatefulSet.Name", dataInstance.Name) | ||
return true, err | ||
} | ||
logger.Info("StatefulSet is created.", "StatefulSet", name) | ||
return true, nil | ||
} | ||
|
||
logger.Error(err, "Failed to fetch StatefulSet", "StatefulSet", name) | ||
return true, err | ||
|
||
} | ||
|
||
func (r *MemgraphHAReconciler) createStatefulSetForDataInstance(memgraphha *memgraphv1.MemgraphHA, dataInstanceId int) *appsv1.StatefulSet { | ||
dataInstanceName := fmt.Sprintf("memgraph-data-%d", dataInstanceId) | ||
serviceName := dataInstanceName | ||
labels := createDataInstanceLabels(dataInstanceName) | ||
replicas := int32(1) | ||
containerName := "memgraph-data" | ||
args := []string{ | ||
fmt.Sprintf("--management-port=%d", mgmtPort), | ||
fmt.Sprintf("--bolt-port=%d", boltPort), | ||
"--experimental-enabled=high-availability", | ||
"--also-log-to-stderr", | ||
"--log-level=TRACE", | ||
"--log-file=/var/log/memgraph/memgraph.log", | ||
} | ||
volumeLibName := fmt.Sprintf("%s-lib-storage", dataInstanceName) | ||
volumeLibSize := "1Gi" | ||
volumeLogName := fmt.Sprintf("%s-log-storage", dataInstanceName) | ||
volumeLogSize := "256Mi" | ||
initContainerName := "init" | ||
initContainerCommand := []string{ | ||
"/bin/sh", | ||
"-c", | ||
} | ||
initContainerArgs := []string{"chown -R memgraph:memgraph /var/log; chown -R memgraph:memgraph /var/lib"} | ||
initContainerPrivileged := true | ||
initContainerReadOnlyRootFilesystem := false | ||
initContainerRunAsNonRoot := false | ||
initContainerRunAsUser := int64(0) | ||
|
||
data := &appsv1.StatefulSet{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: dataInstanceName, | ||
Namespace: memgraphha.Namespace, | ||
}, | ||
Spec: appsv1.StatefulSetSpec{ | ||
ServiceName: serviceName, | ||
Replicas: &replicas, | ||
Selector: &metav1.LabelSelector{ | ||
MatchLabels: labels, | ||
}, | ||
Template: corev1.PodTemplateSpec{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Labels: labels, | ||
}, | ||
Spec: corev1.PodSpec{ | ||
InitContainers: []corev1.Container{ | ||
{ | ||
Name: initContainerName, | ||
Image: image, | ||
VolumeMounts: []corev1.VolumeMount{ | ||
{ | ||
Name: volumeLibName, | ||
MountPath: "/var/lib/memgraph", | ||
}, | ||
{ | ||
Name: volumeLogName, | ||
MountPath: "/var/log/memgraph", | ||
}, | ||
}, | ||
Command: initContainerCommand, | ||
Args: initContainerArgs, | ||
SecurityContext: &corev1.SecurityContext{ | ||
Privileged: &initContainerPrivileged, | ||
ReadOnlyRootFilesystem: &initContainerReadOnlyRootFilesystem, | ||
RunAsNonRoot: &initContainerRunAsNonRoot, | ||
RunAsUser: &initContainerRunAsUser, | ||
Capabilities: &corev1.Capabilities{ | ||
Drop: []corev1.Capability{"all"}, | ||
Add: []corev1.Capability{"CHOWN"}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
Containers: []corev1.Container{{ | ||
Name: containerName, | ||
Image: image, | ||
ImagePullPolicy: corev1.PullAlways, // set to PullIfNotPresent when testing with local image | ||
Ports: []corev1.ContainerPort{ | ||
{ | ||
ContainerPort: int32(boltPort), | ||
Name: "bolt", | ||
}, | ||
{ | ||
ContainerPort: int32(mgmtPort), | ||
Name: "management", | ||
}, | ||
{ | ||
ContainerPort: int32(replicationPort), | ||
Name: "replication", | ||
}, | ||
}, | ||
Args: args, | ||
Env: []corev1.EnvVar{ | ||
{ | ||
Name: "MEMGRAPH_ENTERPRISE_LICENSE", | ||
ValueFrom: &corev1.EnvVarSource{ | ||
SecretKeyRef: &corev1.SecretKeySelector{ | ||
LocalObjectReference: corev1.LocalObjectReference{ | ||
Name: "memgraph-secrets", | ||
}, | ||
Key: "MEMGRAPH_ENTERPRISE_LICENSE", | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: "MEMGRAPH_ORGANIZATION_NAME", | ||
ValueFrom: &corev1.EnvVarSource{ | ||
SecretKeyRef: &corev1.SecretKeySelector{ | ||
LocalObjectReference: corev1.LocalObjectReference{ | ||
Name: "memgraph-secrets", | ||
}, | ||
Key: "MEMGRAPH_ORGANIZATION_NAME", | ||
}, | ||
}, | ||
}, | ||
}, | ||
VolumeMounts: []corev1.VolumeMount{ | ||
{ | ||
Name: volumeLibName, | ||
MountPath: "/var/lib/memgraph", | ||
}, | ||
{ | ||
Name: volumeLogName, | ||
MountPath: "/var/log/memgraph", | ||
}, | ||
}, | ||
}}, | ||
}, | ||
}, | ||
VolumeClaimTemplates: []corev1.PersistentVolumeClaim{ | ||
{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: volumeLibName, | ||
}, | ||
Spec: corev1.PersistentVolumeClaimSpec{ | ||
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, | ||
Resources: corev1.VolumeResourceRequirements{ | ||
Requests: corev1.ResourceList{ | ||
corev1.ResourceStorage: resource.MustParse(volumeLibSize), | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: volumeLogName, | ||
}, | ||
Spec: corev1.PersistentVolumeClaimSpec{ | ||
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, | ||
Resources: corev1.VolumeResourceRequirements{ | ||
Requests: corev1.ResourceList{ | ||
corev1.ResourceStorage: resource.MustParse(volumeLogSize), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
ctrl.SetControllerReference(memgraphha, data, r.Scheme) | ||
return data | ||
} | ||
|
||
func createDataInstanceLabels(dataInstanceName string) map[string]string { | ||
return map[string]string{"app": dataInstanceName} | ||
} |
Oops, something went wrong.