Skip to content

Commit 2d7b30c

Browse files
cpitstick-lataiChristopher Pitsticktoddbaert
authored
feat: add image pull secrets (#655)
Signed-off-by: Todd Baert <todd.baert@dynatrace.com> Co-authored-by: Christopher Pitstick <cpitstick@bluel3.com> Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
1 parent 3746216 commit 2d7b30c

File tree

12 files changed

+78
-34
lines changed

12 files changed

+78
-34
lines changed

chart/open-feature-operator/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ The command removes all the Kubernetes components associated with the chart and
9696
| Name | Description | Value |
9797
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ |
9898
| `defaultNamespace` | To override the namespace use the `--namespace` flag. This default is provided to ensure that the kustomize build charts in `/templates` deploy correctly when no `namespace` is provided via the `-n` flag. | `open-feature-operator-system` |
99+
| `imagePullSecret` | Secret containing credentials for images pulled by the operator (flagdProxyConfiguration.image, flagdConfiguration.image, controllerManager.manager.image, controllerManager.kubeRbacProxy.image). | `""` |
99100

100101
### Sidecar configuration
101102

@@ -166,7 +167,7 @@ The command removes all the Kubernetes components associated with the chart and
166167
| `controllerManager.kubeRbacProxy.resources.requests.cpu` | Sets cpu resource requests for kube-rbac-proxy. | `5m` |
167168
| `controllerManager.kubeRbacProxy.resources.requests.memory` | Sets memory resource requests for kube-rbac-proxy. | `64Mi` |
168169
| `controllerManager.manager.image.repository` | Sets the image for the operator. | `ghcr.io/open-feature/open-feature-operator` |
169-
| `controllerManager.manager.image.tag` | Sets the version tag for the operator. | `v0.5.7` |
170+
| `controllerManager.manager.image.tag` | Sets the version tag for the operator. | `v0.6.0` |
170171
| `controllerManager.manager.resources.limits.cpu` | Sets cpu resource limits for operator. | `500m` |
171172
| `controllerManager.manager.resources.limits.memory` | Sets memory resource limits for operator. | `128Mi` |
172173
| `controllerManager.manager.resources.requests.cpu` | Sets cpu resource requests for operator. | `10m` |

chart/open-feature-operator/values.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
## @section Global
33
## @param defaultNamespace To override the namespace use the `--namespace` flag. This default is provided to ensure that the kustomize build charts in `/templates` deploy correctly when no `namespace` is provided via the `-n` flag.
44
defaultNamespace: open-feature-operator-system
5+
## @param imagePullSecret Secret containing credentials for images pulled by the operator (flagdProxyConfiguration.image, flagdConfiguration.image, controllerManager.manager.image, controllerManager.kubeRbacProxy.image).
6+
imagePullSecret: ""
57

68
## @section Sidecar configuration
79
sidecarConfiguration:

common/flagdproxy/flagdproxy.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ type FlagdProxyConfiguration struct {
3838
Tag string
3939
Namespace string
4040
OperatorDeploymentName string
41+
ImagePullSecret string
4142
}
4243

43-
func NewFlagdProxyConfiguration(env types.EnvConfig) *FlagdProxyConfiguration {
44+
func NewFlagdProxyConfiguration(env types.EnvConfig, imagePullSecret string) *FlagdProxyConfiguration {
4445
return &FlagdProxyConfiguration{
4546
Image: env.FlagdProxyImage,
4647
Tag: env.FlagdProxyTag,
@@ -49,6 +50,7 @@ func NewFlagdProxyConfiguration(env types.EnvConfig) *FlagdProxyConfiguration {
4950
Port: env.FlagdProxyPort,
5051
ManagementPort: env.FlagdProxyManagementPort,
5152
DebugLogging: env.FlagdProxyDebugLogging,
53+
ImagePullSecret: imagePullSecret,
5254
}
5355
}
5456

@@ -143,6 +145,13 @@ func (f *FlagdProxyHandler) newFlagdProxyManifest(ownerReference *metav1.OwnerRe
143145
if f.config.DebugLogging {
144146
args = append(args, "--debug")
145147
}
148+
imagePullSecrets := []corev1.LocalObjectReference{}
149+
if f.config.ImagePullSecret != "" {
150+
imagePullSecrets = append(imagePullSecrets, corev1.LocalObjectReference{
151+
Name: f.config.ImagePullSecret,
152+
})
153+
}
154+
146155
return &appsV1.Deployment{
147156
ObjectMeta: metav1.ObjectMeta{
148157
Name: FlagdProxyDeploymentName,
@@ -172,6 +181,7 @@ func (f *FlagdProxyHandler) newFlagdProxyManifest(ownerReference *metav1.OwnerRe
172181
},
173182
Spec: corev1.PodSpec{
174183
ServiceAccountName: FlagdProxyServiceAccountName,
184+
ImagePullSecrets: imagePullSecrets,
175185
Containers: []corev1.Container{
176186
{
177187
Image: fmt.Sprintf("%s:%s", f.config.Image, f.config.Tag),

common/flagdproxy/flagdproxy_test.go

+16-8
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,22 @@ import (
1919
"sigs.k8s.io/controller-runtime/pkg/client/fake"
2020
)
2121

22+
const pullSecret = "test-pullSecret"
23+
2224
func TestNewFlagdProxyConfiguration(t *testing.T) {
25+
2326
kpConfig := NewFlagdProxyConfiguration(types.EnvConfig{
2427
FlagdProxyPort: 8015,
2528
FlagdProxyManagementPort: 8016,
26-
})
29+
}, pullSecret)
2730

2831
require.NotNil(t, kpConfig)
2932
require.Equal(t, &FlagdProxyConfiguration{
3033
Port: 8015,
3134
ManagementPort: 8016,
3235
DebugLogging: false,
3336
OperatorDeploymentName: common.OperatorDeploymentName,
37+
ImagePullSecret: pullSecret,
3438
}, kpConfig)
3539
}
3640

@@ -44,7 +48,7 @@ func TestNewFlagdProxyConfiguration_OverrideEnvVars(t *testing.T) {
4448
FlagdProxyDebugLogging: true,
4549
}
4650

47-
kpConfig := NewFlagdProxyConfiguration(env)
51+
kpConfig := NewFlagdProxyConfiguration(env, pullSecret)
4852

4953
require.NotNil(t, kpConfig)
5054
require.Equal(t, &FlagdProxyConfiguration{
@@ -55,11 +59,12 @@ func TestNewFlagdProxyConfiguration_OverrideEnvVars(t *testing.T) {
5559
Tag: "my-tag",
5660
Namespace: "my-namespace",
5761
OperatorDeploymentName: common.OperatorDeploymentName,
62+
ImagePullSecret: pullSecret,
5863
}, kpConfig)
5964
}
6065

6166
func TestNewFlagdProxyHandler(t *testing.T) {
62-
kpConfig := NewFlagdProxyConfiguration(types.EnvConfig{})
67+
kpConfig := NewFlagdProxyConfiguration(types.EnvConfig{}, pullSecret)
6368

6469
require.NotNil(t, kpConfig)
6570

@@ -95,7 +100,7 @@ func TestDoesFlagdProxyExist(t *testing.T) {
95100
},
96101
}
97102

98-
kpConfig := NewFlagdProxyConfiguration(env)
103+
kpConfig := NewFlagdProxyConfiguration(env, pullSecret)
99104

100105
require.NotNil(t, kpConfig)
101106

@@ -123,7 +128,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_ProxyExistsWithBadVersion(t *testing
123128
env := types.EnvConfig{
124129
PodNamespace: "ns",
125130
}
126-
kpConfig := NewFlagdProxyConfiguration(env)
131+
kpConfig := NewFlagdProxyConfiguration(env, pullSecret)
127132

128133
require.NotNil(t, kpConfig)
129134

@@ -182,7 +187,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_ProxyExistsWithoutLabel(t *testing.T
182187
env := types.EnvConfig{
183188
PodNamespace: "ns",
184189
}
185-
kpConfig := NewFlagdProxyConfiguration(env)
190+
kpConfig := NewFlagdProxyConfiguration(env, pullSecret)
186191

187192
require.NotNil(t, kpConfig)
188193

@@ -231,7 +236,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_ProxyExistsWithNewestVersion(t *test
231236
env := types.EnvConfig{
232237
PodNamespace: "ns",
233238
}
234-
kpConfig := NewFlagdProxyConfiguration(env)
239+
kpConfig := NewFlagdProxyConfiguration(env, pullSecret)
235240

236241
require.NotNil(t, kpConfig)
237242

@@ -275,7 +280,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_CreateProxy(t *testing.T) {
275280
FlagdProxyManagementPort: 90,
276281
FlagdProxyDebugLogging: true,
277282
}
278-
kpConfig := NewFlagdProxyConfiguration(env)
283+
kpConfig := NewFlagdProxyConfiguration(env, pullSecret)
279284

280285
require.NotNil(t, kpConfig)
281286

@@ -356,6 +361,9 @@ func TestFlagdProxyHandler_HandleFlagdProxy_CreateProxy(t *testing.T) {
356361
},
357362
Spec: corev1.PodSpec{
358363
ServiceAccountName: FlagdProxyServiceAccountName,
364+
ImagePullSecrets: []corev1.LocalObjectReference{
365+
{Name: pullSecret},
366+
},
359367
Containers: []corev1.Container{
360368
{
361369
Image: "image:tag",

config/crd/bases/core.openfeature.dev_flagds.yaml

+5-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ spec:
6161
Default: /flagd.evaluation.v1.Service
6262
type: string
6363
hosts:
64-
description: Hosts list of hosts to be added to the ingress
64+
description: |-
65+
Hosts list of hosts to be added to the ingress.
66+
Empty string corresponds to rule with no host.
6567
items:
6668
type: string
6769
type: array
@@ -109,6 +111,8 @@ spec:
109111
type: string
110112
type: object
111113
type: array
114+
required:
115+
- hosts
112116
type: object
113117
replicas:
114118
default: 1

config/overlays/helm/manager.yaml

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ metadata:
66
spec:
77
replicas: 0{{ .Values.controllerManager.replicas }}
88
template:
9-
spec:
9+
spec:
10+
imagePullSecrets:
11+
- name: "{{ .Values.imagePullSecret }}"
1012
containers:
1113
- name: manager
1214
image: "{{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag }}"
@@ -17,7 +19,7 @@ spec:
1719
requests:
1820
cpu: "{{ .Values.controllerManager.manager.resources.requests.cpu }}"
1921
memory: "{{ .Values.controllerManager.manager.resources.requests.memory }}"
20-
env:
22+
env:
2123
- name: SIDECAR_MANAGEMENT_PORT
2224
value: "{{ .Values.sidecarConfiguration.managementPort }}"
2325
- name: SIDECAR_PORT
@@ -90,6 +92,7 @@ spec:
9092
- --sidecar-ram-limit={{ .Values.sidecarConfiguration.resources.limits.memory }}
9193
- --sidecar-cpu-request={{ .Values.sidecarConfiguration.resources.requests.cpu }}
9294
- --sidecar-ram-request={{ .Values.sidecarConfiguration.resources.requests.memory }}
95+
- --image-pull-secret={{ .Values.imagePullSecret }}
9396
- name: kube-rbac-proxy
9497
image: "{{ .Values.controllerManager.kubeRbacProxy.image.repository }}:{{ .Values.controllerManager.kubeRbacProxy.image.tag }}"
9598
resources:

controllers/core/featureflagsource/controller_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func TestFeatureFlagSourceReconciler_Reconcile(t *testing.T) {
2727
testNamespace = "test-namespace"
2828
fsConfigName = "test-config"
2929
deploymentName = "test-deploy"
30+
pullSecret = "test-pullsecret"
3031
)
3132

3233
tests := []struct {
@@ -92,7 +93,7 @@ func TestFeatureFlagSourceReconciler_Reconcile(t *testing.T) {
9293
kpConfig := flagdproxy.NewFlagdProxyConfiguration(commontypes.EnvConfig{
9394
FlagdProxyImage: "ghcr.io/open-feature/flagd-proxy",
9495
FlagdProxyTag: flagdProxyTag,
95-
})
96+
}, pullSecret)
9697

9798
kpConfig.Namespace = testNamespace
9899
kph := flagdproxy.NewFlagdProxyHandler(

controllers/core/flagd/common/common.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package resources
22

33
type FlagdConfiguration struct {
4-
FlagdPort int
5-
OFREPPort int
6-
SyncPort int
7-
ManagementPort int
8-
DebugLogging bool
9-
Image string
10-
Tag string
4+
FlagdPort int
5+
OFREPPort int
6+
SyncPort int
7+
ManagementPort int
8+
DebugLogging bool
9+
Image string
10+
Tag string
11+
ImagePullSecret string
1112

1213
OperatorNamespace string
1314
OperatorDeploymentName string

controllers/core/flagd/config.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package flagd
33
import (
44
"github.com/open-feature/open-feature-operator/common"
55
"github.com/open-feature/open-feature-operator/common/types"
6-
"github.com/open-feature/open-feature-operator/controllers/core/flagd/common"
6+
resources "github.com/open-feature/open-feature-operator/controllers/core/flagd/common"
77
)
88

9-
func NewFlagdConfiguration(env types.EnvConfig) resources.FlagdConfiguration {
9+
func NewFlagdConfiguration(env types.EnvConfig, imagePullSecret string) resources.FlagdConfiguration {
1010
return resources.FlagdConfiguration{
1111
Image: env.FlagdImage,
1212
Tag: env.FlagdTag,
@@ -16,5 +16,6 @@ func NewFlagdConfiguration(env types.EnvConfig) resources.FlagdConfiguration {
1616
SyncPort: env.FlagdSyncPort,
1717
ManagementPort: env.FlagdManagementPort,
1818
DebugLogging: env.FlagdDebugLogging,
19+
ImagePullSecret: imagePullSecret,
1920
}
2021
}

controllers/core/flagd/resources/deployment.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
api "github.com/open-feature/open-feature-operator/apis/core/v1beta1"
1111
"github.com/open-feature/open-feature-operator/common"
1212
"github.com/open-feature/open-feature-operator/common/flagdinjector"
13-
"github.com/open-feature/open-feature-operator/controllers/core/flagd/common"
13+
resources "github.com/open-feature/open-feature-operator/controllers/core/flagd/common"
1414
appsv1 "k8s.io/api/apps/v1"
1515
corev1 "k8s.io/api/core/v1"
1616
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -77,6 +77,12 @@ func (r *FlagdDeployment) GetResource(ctx context.Context, flagd *api.Flagd) (cl
7777
}
7878

7979
featureFlagSource := &api.FeatureFlagSource{}
80+
imagePullSecrets := []corev1.LocalObjectReference{}
81+
if r.FlagdConfig.ImagePullSecret != "" {
82+
imagePullSecrets = append(imagePullSecrets, corev1.LocalObjectReference{
83+
Name: r.FlagdConfig.ImagePullSecret,
84+
})
85+
}
8086

8187
if err := r.Client.Get(ctx, client.ObjectKey{
8288
Namespace: flagd.Namespace,
@@ -94,8 +100,9 @@ func (r *FlagdDeployment) GetResource(ctx context.Context, flagd *api.Flagd) (cl
94100
return nil, errors.New("no flagd container has been injected into deployment")
95101
}
96102

97-
// override settings for the injected container for flagd standalone deployment mode
103+
deployment.Spec.Template.Spec.ImagePullSecrets = imagePullSecrets
98104

105+
// override settings for the injected container for flagd standalone deployment mode
99106
deployment.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", r.FlagdConfig.Image, r.FlagdConfig.Tag)
100107

101108
deployment.Spec.Template.Spec.Containers[0].Ports = []corev1.ContainerPort{

docs/crds.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,14 @@ Ingress
925925
</tr>
926926
</thead>
927927
<tbody><tr>
928+
<td><b>hosts</b></td>
929+
<td>[]string</td>
930+
<td>
931+
Hosts list of hosts to be added to the ingress.
932+
Empty string corresponds to rule with no host.<br/>
933+
</td>
934+
<td>true</td>
935+
</tr><tr>
928936
<td><b>annotations</b></td>
929937
<td>map[string]string</td>
930938
<td>
@@ -946,13 +954,6 @@ Ingress
946954
Default: /flagd.evaluation.v1.Service<br/>
947955
</td>
948956
<td>false</td>
949-
</tr><tr>
950-
<td><b>hosts</b></td>
951-
<td>[]string</td>
952-
<td>
953-
Hosts list of hosts to be added to the ingress<br/>
954-
</td>
955-
<td>false</td>
956957
</tr><tr>
957958
<td><b>ingressClassName</b></td>
958959
<td>string</td>

main.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ const (
6565
sidecarRamLimitDefault = "64M"
6666
sidecarCpuRequestDefault = "0.2"
6767
sidecarRamRequestDefault = "32M"
68+
imagePullSecretFlagName = "image-pull-secret"
69+
imagePullSecretDefault = ""
6870
)
6971

7072
var (
@@ -75,6 +77,7 @@ var (
7577
probeAddr string
7678
verbose bool
7779
sidecarCpuLimit, sidecarRamLimit, sidecarCpuRequest, sidecarRamRequest string
80+
imagePullSecret string
7881
)
7982

8083
func init() {
@@ -103,6 +106,8 @@ func main() {
103106
flag.StringVar(&sidecarCpuRequest, sidecarCpuRequestFlagName, sidecarCpuRequestDefault, "sidecar CPU minimum, in cores. (500m = .5 cores)")
104107
flag.StringVar(&sidecarRamRequest, sidecarRamRequestFlagName, sidecarRamRequestDefault, "sidecar memory minimum, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)")
105108

109+
flag.StringVar(&imagePullSecret, imagePullSecretFlagName, imagePullSecretDefault, "secret containing credentials to pull images.")
110+
106111
flag.Parse()
107112

108113
level := zapcore.InfoLevel
@@ -178,7 +183,7 @@ func main() {
178183
}
179184

180185
kph := flagdproxy.NewFlagdProxyHandler(
181-
flagdproxy.NewFlagdProxyConfiguration(env),
186+
flagdproxy.NewFlagdProxyConfiguration(env, imagePullSecret),
182187
mgr.GetClient(),
183188
ctrl.Log.WithName("FeatureFlagSource FlagdProxyHandler"),
184189
)
@@ -210,7 +215,7 @@ func main() {
210215
Scheme: mgr.GetScheme(),
211216
Log: flagdControllerLogger,
212217
}
213-
flagdConfig := flagd.NewFlagdConfiguration(env)
218+
flagdConfig := flagd.NewFlagdConfiguration(env, imagePullSecret)
214219

215220
if err = (&flagd.FlagdReconciler{
216221
Client: mgr.GetClient(),

0 commit comments

Comments
 (0)