Skip to content

Commit 08a8d8c

Browse files
authored
Merge pull request #899 from RedHatInsights/psav/upgrade_keycloak
Upgrade Keycloak
2 parents 02384b8 + 10f7a93 commit 08a8d8c

File tree

13 files changed

+514
-294
lines changed

13 files changed

+514
-294
lines changed

apis/cloud.redhat.com/v1alpha1/clowdenvironment_types.go

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ type WebConfig struct {
8888
// Optional keycloak version override -- used only in (*_local_*) mode -- if not set, a hard-coded default is used.
8989
KeycloakVersion string `json:"keycloakVersion,omitempty"`
9090

91+
// Optionally use PVC storage for keycloak db
92+
KeycloakPVC bool `json:"keycloakPVC,omitempty"`
93+
9194
// Optional images to use for web provider components -- only applies when running in (*_local_*) mode.
9295
Images WebImages `json:"images,omitempty"`
9396

config/crd/bases/cloud.redhat.com_clowdenvironments.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,9 @@ spec:
753753
ingressClass:
754754
description: Ingress Class Name used only in (*_local_*) mode.
755755
type: string
756+
keycloakPVC:
757+
description: Optionally use PVC storage for keycloak db
758+
type: boolean
756759
keycloakVersion:
757760
description: Optional keycloak version override -- used only
758761
in (*_local_*) mode -- if not set, a hard-coded default

controllers/cloud.redhat.com/providers/featureflags/localfeatureflags.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ var LocalFFDeployment = rc.NewSingleResourceIdent(ProvName, "ff_deployment", &ap
2929
// LocalFFService is the ident referring to the local Feature Flags service object.
3030
var LocalFFService = rc.NewSingleResourceIdent(ProvName, "ff_service", &core.Service{})
3131

32+
// LocalFFSecret is the ident referring to the local Feature Flags secret object.
33+
var LocalFFSecret = rc.NewSingleResourceIdent(ProvName, "ff_secret", &core.Secret{})
34+
3235
// LocalFFDBDeployment is the ident referring to the local Feature Flags DB deployment object.
3336
var LocalFFDBDeployment = rc.NewSingleResourceIdent(ProvName, "ff_db_deployment", &apps.Deployment{})
3437

@@ -41,18 +44,16 @@ var LocalFFDBPVC = rc.NewSingleResourceIdent(ProvName, "ff_db_pvc", &core.Persis
4144
// LocalFFDBSecret is the ident referring to the local Feature Flags DB secret object.
4245
var LocalFFDBSecret = rc.NewSingleResourceIdent(ProvName, "ff_db_secret", &core.Secret{})
4346

44-
// LocalFFSecret is the ident referring to the local Feature Flags secret object.
45-
var LocalFFSecret = rc.NewSingleResourceIdent(ProvName, "ff_secret", &core.Secret{})
46-
4747
type localFeatureFlagsProvider struct {
4848
providers.Provider
4949
}
5050

5151
// NewLocalFeatureFlagsProvider returns a new local featureflags provider object.
5252
func NewLocalFeatureFlagsProvider(p *providers.Provider) (providers.ClowderProvider, error) {
5353
p.Cache.AddPossibleGVKFromIdent(
54-
LocalFFDBDeployment,
54+
LocalFFDeployment,
5555
LocalFFService,
56+
LocalFFSecret,
5657
LocalFFDBDeployment,
5758
LocalFFDBService,
5859
LocalFFDBPVC,

controllers/cloud.redhat.com/providers/utils/utils.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import (
2424
var DefaultImageCaddySideCar = "quay.io/cloudservices/crc-caddy-plugin:a988cd2"
2525
var DefaultImageCaddyGateway = DefaultImageCaddySideCar
2626
var DefaultImageMBOP = "quay.io/cloudservices/mbop:959d00d"
27-
var DefaultImageMocktitlements = "quay.io/cloudservices/mocktitlements:e24820c"
28-
var DefaultKeyCloakVersion = "15.0.2"
27+
var DefaultImageMocktitlements = "quay.io/cloudservices/mocktitlements:81fd80e"
28+
var DefaultKeyCloakVersion = "23.0.1"
2929
var DefaultImageKeyCloak = fmt.Sprintf("quay.io/keycloak/keycloak:%s", DefaultKeyCloakVersion)
3030

3131
// MakeLocalDB populates the given deployment object with the local DB struct.

controllers/cloud.redhat.com/providers/web/local.go

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ func NewLocalWebProvider(p *providers.Provider) (providers.ClowderProvider, erro
3939
WebKeycloakService,
4040
WebKeycloakIngress,
4141
WebKeycloakImportSecret,
42+
WebKeycloakDBDeployment,
43+
WebKeycloakDBPVC,
44+
WebKeycloakDBService,
45+
WebKeycloakDBSecret,
4246
WebBOPDeployment,
4347
WebBOPService,
4448
WebMocktitlementsDeployment,
@@ -68,6 +72,10 @@ func (web *localWebProvider) EnvProvide() error {
6872
}
6973
}
7074

75+
if err := configureKeycloakDB(web); err != nil {
76+
return err
77+
}
78+
7179
if err := configureKeycloak(web); err != nil {
7280
return err
7381
}

controllers/cloud.redhat.com/providers/web/resources_keycloak.go

+177-10
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import (
66
"strings"
77

88
crd "github.com/RedHatInsights/clowder/apis/cloud.redhat.com/v1alpha1"
9+
"github.com/RedHatInsights/clowder/controllers/cloud.redhat.com/config"
910
"github.com/RedHatInsights/clowder/controllers/cloud.redhat.com/errors"
1011
obj "github.com/RedHatInsights/clowder/controllers/cloud.redhat.com/object"
1112
"github.com/RedHatInsights/clowder/controllers/cloud.redhat.com/providers"
13+
"github.com/RedHatInsights/clowder/controllers/cloud.redhat.com/providers/sizing"
1214
provutils "github.com/RedHatInsights/clowder/controllers/cloud.redhat.com/providers/utils"
1315

1416
rc "github.com/RedHatInsights/rhc-osdk-utils/resourceCache"
@@ -38,6 +40,113 @@ var WebKeycloakImportSecret = rc.NewSingleResourceIdent(ProvName, "web_keycloak_
3840
// WebKeycloakSecret is the mocked secret config
3941
var WebKeycloakSecret = rc.NewSingleResourceIdent(ProvName, "web_keycloak_secret", &core.Secret{}, rc.ResourceOptions{WriteNow: true})
4042

43+
// WebKeycloakDBDeployment is the ident referring to the local Feature Flags DB deployment object.
44+
var WebKeycloakDBDeployment = rc.NewSingleResourceIdent(ProvName, "web_keycloak_db_deployment", &apps.Deployment{})
45+
46+
// WebKeycloakDBService is the ident referring to the local Feature Flags DB service object.
47+
var WebKeycloakDBService = rc.NewSingleResourceIdent(ProvName, "web_keycloak_db_service", &core.Service{})
48+
49+
// WebKeycloakDBPVC is the ident referring to the local Feature Flags DB PVC object.
50+
var WebKeycloakDBPVC = rc.NewSingleResourceIdent(ProvName, "web_keycloak_db_pvc", &core.PersistentVolumeClaim{})
51+
52+
// WebKeycloakDBSecret is the ident referring to the local Feature Flags DB secret object.
53+
var WebKeycloakDBSecret = rc.NewSingleResourceIdent(ProvName, "web_keycloak_db_secret", &core.Secret{})
54+
55+
func configureKeycloakDB(web *localWebProvider) error {
56+
namespacedNameDb := types.NamespacedName{
57+
Name: "keycloak-db",
58+
Namespace: web.Env.Status.TargetNamespace,
59+
}
60+
61+
dd := &apps.Deployment{}
62+
if err := web.Cache.Create(WebKeycloakDBDeployment, namespacedNameDb, dd); err != nil {
63+
return err
64+
}
65+
66+
dbCfg := config.DatabaseConfig{}
67+
68+
password, err := utils.RandPassword(16, provutils.RCharSet)
69+
if err != nil {
70+
return errors.Wrap("password generate failed", err)
71+
}
72+
73+
pgPassword, err := utils.RandPassword(16, provutils.RCharSet)
74+
if err != nil {
75+
return errors.Wrap("pgPassword generate failed", err)
76+
}
77+
78+
username := utils.RandString(16)
79+
hostname := fmt.Sprintf("%v.%v.svc", namespacedNameDb.Name, namespacedNameDb.Namespace)
80+
81+
dataInitDb := func() map[string]string {
82+
83+
return map[string]string{
84+
"hostname": hostname,
85+
"port": "5432",
86+
"username": username,
87+
"password": password,
88+
"pgPass": pgPassword,
89+
"name": "keycloak",
90+
}
91+
}
92+
93+
secMapDb, err := providers.MakeOrGetSecret(web.Env, web.Cache, WebKeycloakDBSecret, namespacedNameDb, dataInitDb)
94+
if err != nil {
95+
return errors.Wrap("Couldn't set/get secret", err)
96+
}
97+
98+
err = dbCfg.Populate(secMapDb)
99+
if err != nil {
100+
return errors.Wrap("couldn't convert to int", err)
101+
}
102+
dbCfg.AdminUsername = "postgres"
103+
104+
labels := &map[string]string{"sub": "keycloak"}
105+
106+
res := core.ResourceRequirements{
107+
Limits: core.ResourceList{
108+
"memory": resource.MustParse("200Mi"),
109+
"cpu": resource.MustParse("100m"),
110+
},
111+
Requests: core.ResourceList{
112+
"memory": resource.MustParse("100Mi"),
113+
"cpu": resource.MustParse("50m"),
114+
},
115+
}
116+
117+
provutils.MakeLocalDB(dd, namespacedNameDb, web.Env, labels, &dbCfg, "quay.io/cloudservices/postgresql-rds:15-53ac80c", web.Env.Spec.Providers.Web.KeycloakPVC, "keycloak", &res)
118+
119+
if err = web.Cache.Update(WebKeycloakDBDeployment, dd); err != nil {
120+
return err
121+
}
122+
123+
s := &core.Service{}
124+
if err := web.Cache.Create(WebKeycloakDBService, namespacedNameDb, s); err != nil {
125+
return err
126+
}
127+
128+
provutils.MakeLocalDBService(s, namespacedNameDb, web.Env, labels)
129+
130+
if err = web.Cache.Update(WebKeycloakDBService, s); err != nil {
131+
return err
132+
}
133+
134+
if web.Env.Spec.Providers.Web.KeycloakPVC {
135+
pvc := &core.PersistentVolumeClaim{}
136+
if err = web.Cache.Create(WebKeycloakDBPVC, namespacedNameDb, pvc); err != nil {
137+
return err
138+
}
139+
140+
provutils.MakeLocalDBPVC(pvc, namespacedNameDb, web.Env, sizing.GetDefaultVolCapacity())
141+
142+
if err = web.Cache.Update(WebKeycloakDBPVC, pvc); err != nil {
143+
return err
144+
}
145+
}
146+
147+
return nil
148+
}
149+
41150
func configureKeycloak(web *localWebProvider) error {
42151
nn := providers.GetNamespacedName(web.Env, "keycloak")
43152

@@ -140,15 +249,63 @@ func makeKeycloak(o obj.ClowdObject, objMap providers.ObjectMap, _ bool, nodePor
140249

141250
envVars := []core.EnvVar{
142251
{
143-
Name: "DB_VENDOR",
144-
Value: "h2",
252+
Name: "KC_DB",
253+
Value: "postgres",
254+
},
255+
{
256+
Name: "KC_DB_USERNAME",
257+
ValueFrom: &core.EnvVarSource{
258+
SecretKeyRef: &core.SecretKeySelector{
259+
LocalObjectReference: core.LocalObjectReference{
260+
Name: "keycloak-db",
261+
},
262+
Key: "username",
263+
},
264+
},
265+
},
266+
{
267+
Name: "KC_DB_PASSWORD",
268+
ValueFrom: &core.EnvVarSource{
269+
SecretKeyRef: &core.SecretKeySelector{
270+
LocalObjectReference: core.LocalObjectReference{
271+
Name: "keycloak-db",
272+
},
273+
Key: "password",
274+
},
275+
},
276+
},
277+
{
278+
Name: "KC_DB_URL_DATABASE",
279+
ValueFrom: &core.EnvVarSource{
280+
SecretKeyRef: &core.SecretKeySelector{
281+
LocalObjectReference: core.LocalObjectReference{
282+
Name: "keycloak-db",
283+
},
284+
Key: "name",
285+
},
286+
},
287+
},
288+
{
289+
Name: "KC_DB_URL_HOST",
290+
ValueFrom: &core.EnvVarSource{
291+
SecretKeyRef: &core.SecretKeySelector{
292+
LocalObjectReference: core.LocalObjectReference{
293+
Name: "keycloak-db",
294+
},
295+
Key: "hostname",
296+
},
297+
},
298+
},
299+
{
300+
Name: "KC_DB_URL_PORT",
301+
Value: "5432",
145302
},
146303
{
147304
Name: "PROXY_ADDRESS_FORWARDING",
148305
Value: "true",
149306
},
150307
{
151-
Name: "KEYCLOAK_USER",
308+
Name: "KEYCLOAK_ADMIN",
152309
ValueFrom: &core.EnvVarSource{
153310
SecretKeyRef: &core.SecretKeySelector{
154311
LocalObjectReference: core.LocalObjectReference{
@@ -159,7 +316,7 @@ func makeKeycloak(o obj.ClowdObject, objMap providers.ObjectMap, _ bool, nodePor
159316
},
160317
},
161318
{
162-
Name: "KEYCLOAK_PASSWORD",
319+
Name: "KEYCLOAK_ADMIN_PASSWORD",
163320
ValueFrom: &core.EnvVarSource{
164321
SecretKeyRef: &core.SecretKeySelector{
165322
LocalObjectReference: core.LocalObjectReference{
@@ -194,15 +351,15 @@ func makeKeycloak(o obj.ClowdObject, objMap providers.ObjectMap, _ bool, nodePor
194351

195352
livenessProbe := core.Probe{
196353
ProbeHandler: probeHandler,
197-
InitialDelaySeconds: 10,
354+
InitialDelaySeconds: 60,
198355
TimeoutSeconds: 2,
199356
PeriodSeconds: 10,
200357
SuccessThreshold: 1,
201358
FailureThreshold: 3,
202359
}
203360
readinessProbe := core.Probe{
204361
ProbeHandler: probeHandler,
205-
InitialDelaySeconds: 20,
362+
InitialDelaySeconds: 60,
206363
TimeoutSeconds: 2,
207364
PeriodSeconds: 10,
208365
SuccessThreshold: 1,
@@ -213,9 +370,19 @@ func makeKeycloak(o obj.ClowdObject, objMap providers.ObjectMap, _ bool, nodePor
213370
image := provutils.GetKeycloakImage(env)
214371

215372
c := core.Container{
216-
Name: nn.Name,
217-
Image: image,
218-
Env: envVars,
373+
Name: nn.Name,
374+
Image: image,
375+
Env: envVars,
376+
Args: []string{
377+
"start",
378+
"--import-realm",
379+
"--hostname-strict",
380+
"false",
381+
"--http-enabled",
382+
"true",
383+
"--http-relative-path",
384+
"/auth",
385+
},
219386
Ports: ports,
220387
LivenessProbe: &livenessProbe,
221388
ReadinessProbe: &readinessProbe,
@@ -235,7 +402,7 @@ func makeKeycloak(o obj.ClowdObject, objMap providers.ObjectMap, _ bool, nodePor
235402
VolumeMounts: []core.VolumeMount{
236403
{
237404
Name: "realm-import",
238-
MountPath: "/json",
405+
MountPath: "/opt/keycloak/data/import/",
239406
},
240407
},
241408
}

deploy-mutate.yml

+3
Original file line numberDiff line numberDiff line change
@@ -6966,6 +6966,9 @@ objects:
69666966
description: Ingress Class Name used only in (*_local_*)
69676967
mode.
69686968
type: string
6969+
keycloakPVC:
6970+
description: Optionally use PVC storage for keycloak db
6971+
type: boolean
69696972
keycloakVersion:
69706973
description: Optional keycloak version override -- used
69716974
only in (*_local_*) mode -- if not set, a hard-coded default

deploy.yml

+3
Original file line numberDiff line numberDiff line change
@@ -6966,6 +6966,9 @@ objects:
69666966
description: Ingress Class Name used only in (*_local_*)
69676967
mode.
69686968
type: string
6969+
keycloakPVC:
6970+
description: Optionally use PVC storage for keycloak db
6971+
type: boolean
69696972
keycloakVersion:
69706973
description: Optional keycloak version override -- used
69716974
only in (*_local_*) mode -- if not set, a hard-coded default

docs/antora/modules/ROOT/pages/api_reference.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -1617,6 +1617,7 @@ WebConfig configures the Clowder provider controlling the creation of web servic
16171617
| *`bopURL`* __string__ | The URL of BOP - only used in (*_none_*/*_operator_*) mode.
16181618
| *`ingressClass`* __string__ | Ingress Class Name used only in (*_local_*) mode.
16191619
| *`keycloakVersion`* __string__ | Optional keycloak version override -- used only in (*_local_*) mode -- if not set, a hard-coded default is used.
1620+
| *`keycloakPVC`* __boolean__ | Optionally use PVC storage for keycloak db
16201621
| *`images`* __xref:{anchor_prefix}-6github.com-redhatinsights-clowder-apis-cloud-redhat-com-v1alpha1-webimages[$$WebImages$$]__ | Optional images to use for web provider components -- only applies when running in (*_local_*) mode.
16211622
| *`tls`* __xref:{anchor_prefix}-6github.com-redhatinsights-clowder-apis-cloud-redhat-com-v1alpha1-tls[$$TLS$$]__ | TLS sidecar enablement
16221623
| *`gatewayCert`* __xref:{anchor_prefix}-6github.com-redhatinsights-clowder-apis-cloud-redhat-com-v1alpha1-gatewaycert[$$GatewayCert$$]__ | Gateway cert

0 commit comments

Comments
 (0)