Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/codecov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: manual
Expand All @@ -44,6 +44,6 @@ jobs:
make build

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"
2 changes: 1 addition & 1 deletion .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:

steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
SOURCE_TAG: ${{ github.ref }}
steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: '0'

Expand Down
17 changes: 8 additions & 9 deletions .mockery.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
with-expecter: True
inpackage: False
dir: "{{.InterfaceDir}}/mocks"
mockname: "Mock{{.InterfaceName}}"
outpkg: "mocks"
filename: "{{.InterfaceName | lower}}_mock.go"
issue-845-fix: True
disable-version-string: True
resolve-type-alias: False
all: true
dir: '{{.InterfaceDir}}/mocks'
structname: Mock{{.InterfaceName}}
pkgname: mocks
template: testify
filename: "{{ .InterfaceName | snakecase }}_generated.mock.go"
template-data:
unroll-variadic: true
packages:
github.com/epam/edp-codebase-operator/v2/controllers/cdstagedeploy/chain:
interfaces:
Expand Down
28 changes: 18 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ validate-docs: api-docs helm-docs ## Validate helm and api docs
@git diff -s --exit-code docs/api.md || (echo " Run 'make api-docs' to address the issue." && git diff && exit 1)

# Run tests
test: fmt vet envtest
test: fmt vet setup-envtest
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" \
KUBECONFIG=${CURRENT_DIR}/hack/kubecfg-stub.yaml go test ./... -coverprofile=coverage.out

Expand Down Expand Up @@ -142,16 +142,16 @@ install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~
##@ Build Dependencies

## Tool Versions
KUSTOMIZE_VERSION ?= v5.4.3
CONTROLLER_TOOLS_VERSION ?= v0.16.5
ENVTEST_VERSION ?= release-0.19
KUSTOMIZE_VERSION ?= v5.6.0
CONTROLLER_TOOLS_VERSION ?= v0.18.0
ENVTEST_VERSION ?= $(shell go list -m -f "{{ .Version }}" sigs.k8s.io/controller-runtime | awk -F'[v.]' '{printf "release-%d.%d", $$2, $$3}')
ENVTEST_K8S_VERSION ?= $(shell go list -m -f "{{ .Version }}" k8s.io/api | awk -F'[v.]' '{printf "1.%d", $$3}')
GOLANGCI_LINT_VERSION ?= v1.64.7
MOCKERY_VERSION ?= v2.53.2
MOCKERY_VERSION ?= v3.6.2
HELMDOCS_VERSION ?= v1.14.2
GITCHGLOG_VERSION ?= v0.15.4
CRDOC_VERSION ?= v0.6.4
ENVTEST_K8S_VERSION = 1.31.0
OPERATOR_SDK_VERSION ?= v1.39.2
OPERATOR_SDK_VERSION ?= v1.42.0

KUSTOMIZE ?= $(LOCALBIN)/kustomize
.PHONY: kustomize
Expand Down Expand Up @@ -202,9 +202,17 @@ bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metada
$(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS)
$(OPERATOR_SDK) bundle validate ./bundle

ENVTEST=$(LOCALBIN)/setup-envtest
.PHONY: setup-envtest
setup-envtest: envtest ## Download the binaries required for ENVTEST in the local bin directory.
@echo "Setting up envtest binaries for Kubernetes version $(ENVTEST_K8S_VERSION)..."
@$(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path || { \
echo "Error: Failed to set up envtest binaries for version $(ENVTEST_K8S_VERSION)."; \
exit 1; \
}

ENVTEST ?= $(LOCALBIN)/setup-envtest
.PHONY: envtest
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
envtest: $(ENVTEST) ## Download setup-envtest locally if necessary.
$(ENVTEST): $(LOCALBIN)
$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION))

Expand All @@ -214,7 +222,7 @@ mocks: mockery
MOCKERY = $(LOCALBIN)/mockery
.PHONY: mockery
mockery: ## Download mockery locally if necessary.
$(call go-install-tool,$(MOCKERY),github.com/vektra/mockery/v2,$(MOCKERY_VERSION))
$(call go-install-tool,$(MOCKERY),github.com/vektra/mockery/v3,$(MOCKERY_VERSION))

.PHONY: operator-sdk
OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk
Expand Down
137 changes: 121 additions & 16 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"flag"
"os"
"path/filepath"
"strconv"
"time"

Expand All @@ -21,9 +22,12 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
ctrlwebhook "sigs.k8s.io/controller-runtime/pkg/webhook"

cdPipeApi "github.com/epam/edp-cd-pipeline-operator/v2/api/v1"
buildInfo "github.com/epam/edp-common/pkg/config"
Expand Down Expand Up @@ -59,20 +63,31 @@ const (

func main() {
var (
metricsAddr string
enableLeaderElection bool
probeAddr string
secureMetrics bool
enableHTTP2 bool
metricsAddr string
metricsCertPath, metricsCertName, metricsCertKey string
webhookCertPath, webhookCertName, webhookCertKey string
enableLeaderElection bool
probeAddr string
secureMetrics bool
enableHTTP2 bool
tlsOpts []func(*tls.Config)
)

flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.BoolVar(&secureMetrics, "metrics-secure", false,
"If set the metrics endpoint is served securely")
flag.BoolVar(&secureMetrics, "metrics-secure", true,
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
flag.StringVar(&webhookCertPath, "webhook-cert-path", "", "The directory that contains the webhook certificate.")
flag.StringVar(&webhookCertName, "webhook-cert-name", "tls.crt", "The name of the webhook certificate file.")
flag.StringVar(&webhookCertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.")
flag.StringVar(&metricsCertPath, "metrics-cert-path", "",
"The directory that contains the metrics server certificate.")
flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt", "The name of the metrics server certificate file.")
flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.")
flag.BoolVar(&enableHTTP2, "enable-http2", false,
"If set, HTTP/2 will be enabled for the metrics and webhook servers")

Expand All @@ -90,7 +105,7 @@ func main() {

// 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
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
// Rapid Reset CVEs. For more information see:
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
// - https://github.com/advisories/GHSA-4374-p667-p6c8
Expand All @@ -100,11 +115,86 @@ func main() {
c.NextProtos = []string{"http/1.1"}
}

var tlsOpts []func(*tls.Config)
if !enableHTTP2 {
tlsOpts = append(tlsOpts, disableHTTP2)
}

// Create watchers for metrics and webhooks certificates
var metricsCertWatcher, webhookCertWatcher *certwatcher.CertWatcher

// Initial webhook TLS options
webhookTLSOpts := tlsOpts

if len(webhookCertPath) > 0 {
setupLog.Info("Initializing webhook certificate watcher using provided certificates",
"webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey)

var err error

webhookCertWatcher, err = certwatcher.New(
filepath.Join(webhookCertPath, webhookCertName),
filepath.Join(webhookCertPath, webhookCertKey),
)
if err != nil {
setupLog.Error(err, "Failed to initialize webhook certificate watcher")
os.Exit(1)
}

webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) {
config.GetCertificate = webhookCertWatcher.GetCertificate
})
}

webhookServer := ctrlwebhook.NewServer(ctrlwebhook.Options{
TLSOpts: webhookTLSOpts,
})

// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
// More info:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/server
// - https://book.kubebuilder.io/reference/metrics.html
metricsServerOptions := metricsserver.Options{
BindAddress: metricsAddr,
SecureServing: secureMetrics,
TLSOpts: tlsOpts,
}

if secureMetrics {
// FilterProvider is used to protect the metrics endpoint with authn/authz.
// These configurations ensure that only authorized users and service accounts
// can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
// https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/filters#WithAuthenticationAndAuthorization
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
}

// If the certificate is not specified, controller-runtime will automatically
// generate self-signed certificates for the metrics server. While convenient for development and testing,
// this setup is not recommended for production.
//
// TODO(user): If you enable certManager, uncomment the following lines:
// - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates
// managed by cert-manager for the metrics server.
// - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification.
if len(metricsCertPath) > 0 {
setupLog.Info("Initializing metrics certificate watcher using provided certificates",
"metrics-cert-path", metricsCertPath, "metrics-cert-name", metricsCertName, "metrics-cert-key", metricsCertKey)

var err error

metricsCertWatcher, err = certwatcher.New(
filepath.Join(metricsCertPath, metricsCertName),
filepath.Join(metricsCertPath, metricsCertKey),
)
if err != nil {
setupLog.Error(err, "to initialize metrics certificate watcher", "error", err)
os.Exit(1)
}

metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) {
config.GetCertificate = metricsCertWatcher.GetCertificate
})
}

setupLog.Info("Starting the Codebase Operator",
"version", v.Version,
"git-commit", v.GitCommit,
Expand Down Expand Up @@ -132,12 +222,9 @@ func main() {
cfg := ctrl.GetConfigOrDie()

mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{
BindAddress: metricsAddr,
SecureServing: secureMetrics,
TLSOpts: tlsOpts,
},
Scheme: scheme,
Metrics: metricsServerOptions,
WebhookServer: webhookServer,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: codebaseOperatorLock,
Expand Down Expand Up @@ -208,6 +295,24 @@ func main() {

// +kubebuilder:scaffold:builder

if metricsCertWatcher != nil {
setupLog.Info("Adding metrics certificate watcher to manager")

if err := mgr.Add(metricsCertWatcher); err != nil {
setupLog.Error(err, "Unable to add metrics certificate watcher to manager")
os.Exit(1)
}
}

if webhookCertWatcher != nil {
setupLog.Info("Adding webhook certificate watcher to manager")

if err := mgr.Add(webhookCertWatcher); err != nil {
setupLog.Error(err, "Unable to add webhook certificate watcher to manager")
os.Exit(1)
}
}

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "failed to set up health check")
os.Exit(1)
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/v2.edp.epam.com_cdstagedeployments.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.18.0
name: cdstagedeployments.v2.edp.epam.com
spec:
group: v2.edp.epam.com
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/v2.edp.epam.com_codebasebranches.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.18.0
name: codebasebranches.v2.edp.epam.com
spec:
group: v2.edp.epam.com
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.18.0
name: codebaseimagestreams.v2.edp.epam.com
spec:
group: v2.edp.epam.com
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/v2.edp.epam.com_codebases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.18.0
name: codebases.v2.edp.epam.com
spec:
group: v2.edp.epam.com
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/v2.edp.epam.com_gitservers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.18.0
name: gitservers.v2.edp.epam.com
spec:
group: v2.edp.epam.com
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/v2.edp.epam.com_jiraissuemetadatas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.18.0
name: jiraissuemetadatas.v2.edp.epam.com
spec:
group: v2.edp.epam.com
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/v2.edp.epam.com_jiraservers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.18.0
name: jiraservers.v2.edp.epam.com
spec:
group: v2.edp.epam.com
Expand Down
Loading