diff --git a/Makefile b/Makefile
index 063f7cd..72dcc81 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ GIT_COMMIT=$(shell git rev-parse HEAD)
GIT_TAG=$(shell if [ -z "`git status --porcelain`" ]; then git describe --exact-match --tags HEAD 2>/dev/null; fi)
KUBECTL_VERSION=$(shell go list -m all | grep k8s.io/client-go| cut -d' ' -f2)
ENVTEST ?= $(LOCALBIN)/setup-envtest
-ENVTEST_K8S_VERSION = 1.23.5
+ENVTEST_K8S_VERSION = 1.31.0
override LDFLAGS += \
-X ${PACKAGE}.version=${VERSION} \
@@ -204,7 +204,7 @@ ENVTEST=$(LOCALBIN)/setup-envtest
.PHONY: envtest
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
$(ENVTEST): $(LOCALBIN)
- $(call go-get-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,release-0.16)
+ $(call go-get-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,release-0.19)
.PHONY: bundle
bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files.
diff --git a/api/common/common.go b/api/common/common.go
index 29164b4..3cd4a0c 100644
--- a/api/common/common.go
+++ b/api/common/common.go
@@ -1,5 +1,9 @@
package common
+import (
+ corev1 "k8s.io/api/core/v1"
+)
+
// StatusCreated is success status for Sonar resources.
const StatusCreated = "created"
@@ -18,3 +22,29 @@ type SonarRef struct {
type HasSonarRef interface {
GetSonarRef() SonarRef
}
+
+// SourceRef is a reference to a key in a ConfigMap or a Secret.
+// +kubebuilder:object:generate=true
+type SourceRef struct {
+ // Selects a key of a ConfigMap.
+ // +optional
+ ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
+
+ // Selects a key of a secret.
+ // +optional
+ SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"`
+}
+
+type ConfigMapKeySelector struct {
+ // The ConfigMap to select from.
+ corev1.LocalObjectReference `json:",inline"`
+ // The key to select.
+ Key string `json:"key"`
+}
+
+type SecretKeySelector struct {
+ // The name of the secret.
+ corev1.LocalObjectReference `json:",inline"`
+ // The key of the secret to select from.
+ Key string `json:"key"`
+}
diff --git a/api/common/zz_generated.deepcopy.go b/api/common/zz_generated.deepcopy.go
new file mode 100644
index 0000000..1cfbabb
--- /dev/null
+++ b/api/common/zz_generated.deepcopy.go
@@ -0,0 +1,32 @@
+//go:build !ignore_autogenerated
+
+// Code generated by controller-gen. DO NOT EDIT.
+
+package common
+
+import ()
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SourceRef) DeepCopyInto(out *SourceRef) {
+ *out = *in
+ if in.ConfigMapKeyRef != nil {
+ in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef
+ *out = new(ConfigMapKeySelector)
+ **out = **in
+ }
+ if in.SecretKeyRef != nil {
+ in, out := &in.SecretKeyRef, &out.SecretKeyRef
+ *out = new(SecretKeySelector)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceRef.
+func (in *SourceRef) DeepCopy() *SourceRef {
+ if in == nil {
+ return nil
+ }
+ out := new(SourceRef)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/api/v1alpha1/sonar_types.go b/api/v1alpha1/sonar_types.go
index 92c5827..4805998 100644
--- a/api/v1alpha1/sonar_types.go
+++ b/api/v1alpha1/sonar_types.go
@@ -2,6 +2,8 @@ package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ "github.com/epam/edp-sonar-operator/api/common"
)
// SonarSpec defines the desired state of Sonar.
@@ -45,6 +47,11 @@ type SonarSetting struct {
// +optional
// +kubebuilder:example={beginBlockRegexp: ".*", endBlockRegexp: ".*"}
FieldValues map[string]string `json:"fieldValues,omitempty"`
+
+ // ValueRef is a reference to a key in a ConfigMap or a Secret.
+ // +optional
+ // +kubebuilder:example={secretKeyRef: {name: my-secret, key: my-key}}
+ ValueRef *common.SourceRef `json:"valueRef,omitempty"`
}
// SonarStatus defines the observed state of Sonar.
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 9f5fbe2..f155a85 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -5,6 +5,7 @@
package v1alpha1
import (
+ "github.com/epam/edp-sonar-operator/api/common"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -507,6 +508,11 @@ func (in *SonarSetting) DeepCopyInto(out *SonarSetting) {
(*out)[key] = val
}
}
+ if in.ValueRef != nil {
+ in, out := &in.ValueRef, &out.ValueRef
+ *out = new(common.SourceRef)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SonarSetting.
diff --git a/config/crd/bases/edp.epam.com_sonars.yaml b/config/crd/bases/edp.epam.com_sonars.yaml
index 12091f4..cb23b56 100644
--- a/config/crd/bases/edp.epam.com_sonars.yaml
+++ b/config/crd/bases/edp.epam.com_sonars.yaml
@@ -78,6 +78,47 @@ spec:
example: https://my-sonarqube-instance.com
maxLength: 4000
type: string
+ valueRef:
+ description: ValueRef is a reference to a key in a ConfigMap
+ or a Secret.
+ example:
+ secretKeyRef:
+ key: my-key
+ name: my-secret
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret.
+ properties:
+ key:
+ description: The key of the secret to select from.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
values:
description: Setting multi value. To set several values, the
parameter must be called once for each value.
diff --git a/controllers/permission_template/sonarpermissiontemplate_controller_integration_test.go b/controllers/permission_template/sonarpermissiontemplate_controller_integration_test.go
index ad5b027..1d14c97 100644
--- a/controllers/permission_template/sonarpermissiontemplate_controller_integration_test.go
+++ b/controllers/permission_template/sonarpermissiontemplate_controller_integration_test.go
@@ -27,7 +27,7 @@ var _ = Describe("PermissionTemplate controller", func() {
ProjectKeyPattern: ".*.finance",
Default: true,
GroupsPermissions: map[string][]string{
- "sonar-developers": {"scan", "codeviewer"},
+ "sonar-users": {"scan", "codeviewer"},
},
SonarRef: common.SonarRef{
Name: sonarName,
@@ -35,15 +35,14 @@ var _ = Describe("PermissionTemplate controller", func() {
},
}
Expect(k8sClient.Create(ctx, newPermissionTemplate)).Should(Succeed())
- Eventually(func() bool {
+ Eventually(func(g Gomega) {
createdPermissionTemplate := &sonarApi.SonarPermissionTemplate{}
err := k8sClient.Get(ctx, types.NamespacedName{Name: permissionTemplateCRName, Namespace: namespace}, createdPermissionTemplate)
- if err != nil {
- return false
- }
- return createdPermissionTemplate.Status.Value == common.StatusCreated && createdPermissionTemplate.Status.Error == ""
- }, timeout, interval).Should(BeTrue())
+ g.Expect(err).ShouldNot(HaveOccurred())
+ g.Expect(createdPermissionTemplate.Status.Error).Should(Equal(""), "Error should be empty")
+ g.Expect(createdPermissionTemplate.Status.Value).Should(Equal(common.StatusCreated), "Status should be created")
+ }).WithTimeout(timeout).WithPolling(interval).Should(Succeed())
})
It("Should delete PermissionTemplate object", func() {
By("By creating not default PermissionTemplate object")
diff --git a/controllers/sonar/chain/factory.go b/controllers/sonar/chain/factory.go
index 58c8ce6..d4c20d4 100644
--- a/controllers/sonar/chain/factory.go
+++ b/controllers/sonar/chain/factory.go
@@ -1,13 +1,15 @@
package chain
import (
+ "sigs.k8s.io/controller-runtime/pkg/client"
+
"github.com/epam/edp-sonar-operator/pkg/client/sonar"
)
-func MakeChain(sonarApiClient sonar.ClientInterface) SonarHandler {
+func MakeChain(sonarApiClient sonar.ClientInterface, k8sClient client.Client) SonarHandler {
ch := &chain{}
ch.Use(NewCheckConnection(sonarApiClient))
- ch.Use(NewUpdateSettings(sonarApiClient))
+ ch.Use(NewUpdateSettings(sonarApiClient, k8sClient))
ch.Use(NewSetDefaultPermissionTemplate(sonarApiClient))
return ch
diff --git a/controllers/sonar/chain/update_settings.go b/controllers/sonar/chain/update_settings.go
index 2f9e1af..b225eea 100644
--- a/controllers/sonar/chain/update_settings.go
+++ b/controllers/sonar/chain/update_settings.go
@@ -9,17 +9,20 @@ import (
"strings"
ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
sonarApi "github.com/epam/edp-sonar-operator/api/v1alpha1"
"github.com/epam/edp-sonar-operator/pkg/client/sonar"
+ "github.com/epam/edp-sonar-operator/pkg/sourceref"
)
type UpdateSettings struct {
sonarApiClient sonar.Settings
+ k8sClient client.Client
}
-func NewUpdateSettings(sonarApiClient sonar.Settings) *UpdateSettings {
- return &UpdateSettings{sonarApiClient: sonarApiClient}
+func NewUpdateSettings(sonarApiClient sonar.Settings, k8sClient client.Client) *UpdateSettings {
+ return &UpdateSettings{sonarApiClient: sonarApiClient, k8sClient: k8sClient}
}
func (h *UpdateSettings) ServeRequest(ctx context.Context, sonar *sonarApi.Sonar) error {
@@ -32,7 +35,12 @@ func (h *UpdateSettings) ServeRequest(ctx context.Context, sonar *sonarApi.Sonar
processedSettings := make([]string, 0, len(sonar.Spec.Settings))
for _, s := range sonar.Spec.Settings {
- if err := h.sonarApiClient.SetSetting(ctx, makeSetting(s)); err != nil {
+ setting, err := h.makeSetting(ctx, s, sonar.Namespace)
+ if err != nil {
+ return err
+ }
+
+ if err = h.sonarApiClient.SetSetting(ctx, setting); err != nil {
return fmt.Errorf("failed to set setting %s: %w", s.Key, err)
}
@@ -77,7 +85,11 @@ func settingsKeysMapToSlice(m map[string]struct{}) []string {
return s
}
-func makeSetting(setting sonarApi.SonarSetting) url.Values {
+func (h *UpdateSettings) makeSetting(
+ ctx context.Context,
+ setting sonarApi.SonarSetting,
+ namespace string,
+) (url.Values, error) {
if setting.FieldValues != nil {
// nolint:errchkjson //we can skip error for marshal map[string]string
fv, _ := json.Marshal(setting.FieldValues)
@@ -85,19 +97,32 @@ func makeSetting(setting sonarApi.SonarSetting) url.Values {
return url.Values{
"key": []string{setting.Key},
"fieldValues": []string{string(fv)},
- }
+ }, nil
}
if setting.Values != nil {
return url.Values{
"key": []string{setting.Key},
"values": setting.Values,
+ }, nil
+ }
+
+ if setting.ValueRef != nil {
+ val, err := sourceref.GetValueFromSourceRef(ctx, setting.ValueRef, namespace, h.k8sClient)
+ if err != nil {
+ return url.Values{}, fmt.Errorf("failed to get sonar setting from source ref: %w", err)
}
+
+ return newSettingValue(setting.Key, val), nil
}
+ return newSettingValue(setting.Key, setting.Value), nil
+}
+
+func newSettingValue(key, value string) url.Values {
return url.Values{
- "key": []string{setting.Key},
- "value": []string{setting.Value},
+ "key": []string{key},
+ "value": []string{value},
}
}
diff --git a/controllers/sonar/chain/update_settings_test.go b/controllers/sonar/chain/update_settings_test.go
index 0059096..08232c4 100644
--- a/controllers/sonar/chain/update_settings_test.go
+++ b/controllers/sonar/chain/update_settings_test.go
@@ -9,9 +9,14 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+ corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
+ "github.com/epam/edp-sonar-operator/api/common"
sonarApi "github.com/epam/edp-sonar-operator/api/v1alpha1"
"github.com/epam/edp-sonar-operator/pkg/client/sonar"
"github.com/epam/edp-sonar-operator/pkg/client/sonar/mocks"
@@ -20,10 +25,14 @@ import (
func TestUpdateSettings_ServeRequest(t *testing.T) {
t.Parallel()
+ scheme := runtime.NewScheme()
+ require.NoError(t, corev1.AddToScheme(scheme))
+
tests := []struct {
name string
sonarApiClient func(t *testing.T) sonar.Settings
sonar *sonarApi.Sonar
+ k8sClient func(t *testing.T) client.Client
wantErr require.ErrorAssertionFunc
wantStatus sonarApi.SonarStatus
}{
@@ -31,7 +40,8 @@ func TestUpdateSettings_ServeRequest(t *testing.T) {
name: "settings is set",
sonar: &sonarApi.Sonar{
ObjectMeta: metav1.ObjectMeta{
- Name: "sonar",
+ Name: "sonar",
+ Namespace: "default",
},
Spec: sonarApi.SonarSpec{
Settings: []sonarApi.SonarSetting{
@@ -50,19 +60,42 @@ func TestUpdateSettings_ServeRequest(t *testing.T) {
"field2": "value2",
},
},
+ {
+ Key: "sonar.secret",
+ ValueRef: &common.SourceRef{
+ SecretKeyRef: &common.SecretKeySelector{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: "sonar-secret",
+ },
+ Key: "secret-key",
+ },
+ },
+ },
},
},
},
sonarApiClient: func(t *testing.T) sonar.Settings {
m := mocks.NewClientInterface(t)
m.On("SetSetting", mock.Anything, mock.Anything).
- Return(nil).Times(3)
+ Return(nil).Times(4)
return m
},
+ k8sClient: func(t *testing.T) client.Client {
+ return fake.NewClientBuilder().
+ WithScheme(scheme).
+ WithObjects(&corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "sonar-secret",
+ Namespace: "default",
+ },
+ Data: map[string][]byte{"secret-key": []byte("secret-value")},
+ }).
+ Build()
+ },
wantErr: require.NoError,
wantStatus: sonarApi.SonarStatus{
- ProcessedSettings: "sonar.core.a,sonar.core.b,sonar.core.c",
+ ProcessedSettings: "sonar.core.a,sonar.core.b,sonar.core.c,sonar.secret",
},
},
{
@@ -92,6 +125,9 @@ func TestUpdateSettings_ServeRequest(t *testing.T) {
return m
},
+ k8sClient: func(t *testing.T) client.Client {
+ return fake.NewClientBuilder().WithScheme(scheme).Build()
+ },
wantErr: require.NoError,
wantStatus: sonarApi.SonarStatus{
ProcessedSettings: "sonar.core.a",
@@ -124,6 +160,9 @@ func TestUpdateSettings_ServeRequest(t *testing.T) {
return m
},
+ k8sClient: func(t *testing.T) client.Client {
+ return fake.NewClientBuilder().WithScheme(scheme).Build()
+ },
wantErr: func(t require.TestingT, err error, i ...interface{}) {
require.Error(t, err)
require.Contains(t, err.Error(), "failed to unset settings")
@@ -154,6 +193,9 @@ func TestUpdateSettings_ServeRequest(t *testing.T) {
return m
},
+ k8sClient: func(t *testing.T) client.Client {
+ return fake.NewClientBuilder().WithScheme(scheme).Build()
+ },
wantErr: func(t require.TestingT, err error, i ...interface{}) {
require.Error(t, err)
require.Contains(t, err.Error(), "failed to set setting")
@@ -167,8 +209,9 @@ func TestUpdateSettings_ServeRequest(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
- h := NewUpdateSettings(tt.sonarApiClient(t))
+ h := NewUpdateSettings(tt.sonarApiClient(t), tt.k8sClient(t))
err := h.ServeRequest(ctrl.LoggerInto(context.Background(), logr.Discard()), tt.sonar)
+
tt.wantErr(t, err)
assert.Equal(t, tt.wantStatus, tt.sonar.Status)
})
diff --git a/controllers/sonar/sonar_controller.go b/controllers/sonar/sonar_controller.go
index 39c62eb..e444ee7 100644
--- a/controllers/sonar/sonar_controller.go
+++ b/controllers/sonar/sonar_controller.go
@@ -80,7 +80,7 @@ func (r *ReconcileSonar) Reconcile(ctx context.Context, request reconcile.Reques
return reconcile.Result{RequeueAfter: defaultRequeueTime}, err
}
- if err = chain.MakeChain(sonarApiClient).ServeRequest(ctx, sonar); err != nil {
+ if err = chain.MakeChain(sonarApiClient, r.client).ServeRequest(ctx, sonar); err != nil {
sonar.Status.Error = err.Error()
if statusErr := r.updateSonarStatus(ctx, sonar, oldStatus); statusErr != nil {
diff --git a/controllers/sonar/sonar_controller_integration_test.go b/controllers/sonar/sonar_controller_integration_test.go
index 061c55b..13f3af6 100644
--- a/controllers/sonar/sonar_controller_integration_test.go
+++ b/controllers/sonar/sonar_controller_integration_test.go
@@ -1,6 +1,7 @@
package sonar
import (
+ "github.com/epam/edp-sonar-operator/api/common"
"time"
. "github.com/onsi/ginkgo/v2"
@@ -30,8 +31,9 @@ var _ = Describe("Sonar controller", func() {
Namespace: namespace,
},
Data: map[string][]byte{
- "user": []byte(sonarUser),
- "password": []byte(sonarPassword),
+ "user": []byte(sonarUser),
+ "password": []byte(sonarPassword),
+ "smtp-pass": []byte("smtp-password"),
},
}
Expect(k8sClient.Create(ctx, secret)).Should(Succeed())
@@ -60,24 +62,34 @@ var _ = Describe("Sonar controller", func() {
Key: "sonar.global.exclusions",
Values: []string{"**/*.js", "**/*.ts", "**/*.tsx", "**/*.jsx"},
},
+ {
+ Key: "email.smtp_password.secured",
+ ValueRef: &common.SourceRef{
+ SecretKeyRef: &common.SecretKeySelector{
+ LocalObjectReference: v1.LocalObjectReference{
+ Name: secret.Name,
+ },
+ Key: "smtp-pass",
+ },
+ },
+ },
},
},
}
Expect(k8sClient.Create(ctx, newSonar)).Should(Succeed())
- Eventually(func() bool {
+ Eventually(func(g Gomega) {
createdSonar := &sonarApi.Sonar{}
err := k8sClient.Get(ctx, types.NamespacedName{Name: sonarName, Namespace: namespace}, createdSonar)
- if err != nil {
- return false
- }
-
- processedSettings := "sonar.dbcleaner.hoursBeforeKeepingOnlyOneSnapshotByDay,sonar.global.exclusions,sonar.issue.ignore.block"
-
- return createdSonar.Status.Connected &&
- createdSonar.Status.Error == "" &&
- createdSonar.Status.Value != "" &&
- createdSonar.Status.ProcessedSettings == processedSettings
+ g.Expect(err).ShouldNot(HaveOccurred())
- }, timeout, interval).Should(BeTrue())
+ g.Expect(createdSonar.Status.Connected).Should(BeTrue(), "Sonar should be connected")
+ g.Expect(createdSonar.Status.Error).Should(BeEmpty(), "Error should be empty")
+ g.Expect(createdSonar.Status.Value).ShouldNot(BeEmpty(), "Value should not be empty")
+ g.Expect(createdSonar.Status.ProcessedSettings).
+ Should(
+ Equal("email.smtp_password.secured,sonar.dbcleaner.hoursBeforeKeepingOnlyOneSnapshotByDay,sonar.global.exclusions,sonar.issue.ignore.block"),
+ "Processed settings should be equal",
+ )
+ }).WithTimeout(timeout).WithPolling(interval).Should(Succeed())
})
})
diff --git a/deploy-templates/_crd_examples/sonar.yaml b/deploy-templates/_crd_examples/sonar.yaml
index c38595f..88a3c6d 100644
--- a/deploy-templates/_crd_examples/sonar.yaml
+++ b/deploy-templates/_crd_examples/sonar.yaml
@@ -17,3 +17,16 @@ spec:
endBlockRegexp: ".*"
- key: sonar.dbcleaner.hoursBeforeKeepingOnlyOneSnapshotByDay
value: "20"
+ - key: email.smtp_password.secured
+ valueRef:
+ secretKeyRef:
+ key: password
+ name: sonar-smtp
+
+---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: sonar-smtp
+data:
+ password: c29uYXItcGFzc3dvcmQ=
diff --git a/deploy-templates/crds/edp.epam.com_sonars.yaml b/deploy-templates/crds/edp.epam.com_sonars.yaml
index 12091f4..cb23b56 100644
--- a/deploy-templates/crds/edp.epam.com_sonars.yaml
+++ b/deploy-templates/crds/edp.epam.com_sonars.yaml
@@ -78,6 +78,47 @@ spec:
example: https://my-sonarqube-instance.com
maxLength: 4000
type: string
+ valueRef:
+ description: ValueRef is a reference to a key in a ConfigMap
+ or a Secret.
+ example:
+ secretKeyRef:
+ key: my-key
+ name: my-secret
+ properties:
+ configMapKeyRef:
+ description: Selects a key of a ConfigMap.
+ properties:
+ key:
+ description: The key to select.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ secretKeyRef:
+ description: Selects a key of a secret.
+ properties:
+ key:
+ description: The key of the secret to select from.
+ type: string
+ name:
+ description: |-
+ Name of the referent.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?
+ type: string
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
values:
description: Setting multi value. To set several values, the
parameter must be called once for each value.
diff --git a/docs/api.md b/docs/api.md
index 23f11d9..15c7b62 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -962,6 +962,13 @@ SonarSetting defines the setting of sonar.
Value is the value of the setting.
Name | +Type | +Description | +Required | +
---|---|---|---|
configMapKeyRef | +object | +
+ Selects a key of a ConfigMap. + |
+ false | +
secretKeyRef | +object | +
+ Selects a key of a secret. + |
+ false | +
Name | +Type | +Description | +Required | +
---|---|---|---|
key | +string | +
+ The key to select. + |
+ true | +
name | +string | +
+ Name of the referent.
+More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+TODO: Add other useful fields. apiVersion, kind, uid? + |
+ false | +
Name | +Type | +Description | +Required | +
---|---|---|---|
key | +string | +
+ The key of the secret to select from. + |
+ true | +
name | +string | +
+ Name of the referent.
+More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+TODO: Add other useful fields. apiVersion, kind, uid? + |
+ false | +