Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Horreum realm import for keycloak and improved app init script #21

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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 Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ $(ENVTEST): $(LOCALBIN)
bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files.
operator-sdk generate kustomize manifests -q
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
$(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS)
$(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS)
operator-sdk bundle validate ./bundle

.PHONY: bundle-build
Expand Down
14 changes: 14 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rules:
- persistentvolumeclaims
- pods
- secrets
- serviceaccounts
- services
- services/finalizers
verbs:
Expand Down Expand Up @@ -65,6 +66,18 @@ rules:
verbs:
- create
- get
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterroles
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- route.openshift.io
resources:
Expand All @@ -81,6 +94,7 @@ rules:
- apiGroups:
- security.openshift.io
resourceNames:
- anyuid
- nonroot
resources:
- securitycontextconstraints
Expand Down
103 changes: 101 additions & 2 deletions controllers/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,34 @@ import (
hyperfoilv1alpha1 "github.com/Hyperfoil/horreum-operator/api/v1alpha1"
routev1 "github.com/openshift/api/route/v1"
corev1 "k8s.io/api/core/v1"
// rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func appinitConfigMap(cr *hyperfoilv1alpha1.Horreum) *corev1.ConfigMap {
return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: cr.Name + "-app-init",
Namespace: cr.Namespace,
Labels: map[string]string{
"app": cr.Name,
},
},
Data: map[string]string{
// Note: 0.7.11 of Horreum used here still has grafana in the k8s-setup.sh script
"app_init.sh": `
echo 'Injecting service-ca certificate ...'
keytool -noprompt -import -alias service-ca -file /etc/ssl/certs/service-ca.crt -cacerts -storepass changeit
until cat /deployments/k8s-setup.sh | sed '/grafana/d' | sh -x
do
echo 'Re-trying init ...'
sleep 10
done
`,
},
}
}

func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl string) *corev1.Pod {
keycloakInternalURL := keycloakInternalURL(cr)

Expand Down Expand Up @@ -58,6 +83,17 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin
})
}
volumes := []corev1.Volume{
{
Name: "app-init",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: cr.Name + "-app-init",
},
DefaultMode: func(i int32) *int32 { return &i }(0555),
},
},
},
{
Name: "imports",
VolumeSource: corev1.VolumeSource{
Expand Down Expand Up @@ -115,7 +151,9 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin
if routeType == "reencrypt" || routeType == "" {
caCertArg = "--cacert /etc/ssl/certs/service-ca.crt"
}
// userId := int64(0)
return &corev1.Pod{

ObjectMeta: metav1.ObjectMeta{
Name: cr.Name + "-app",
Namespace: cr.Namespace,
Expand All @@ -125,14 +163,18 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin
},
},
Spec: corev1.PodSpec{
// ServiceAccountName: "horreum-init",
TerminationGracePeriodSeconds: &[]int64{0}[0],
InitContainers: []corev1.Container{
{
Name: "init",
Image: appImage(cr),
ImagePullPolicy: corev1.PullAlways,
// SecurityContext: &corev1.SecurityContext{
// RunAsUser: &[]int64{userId}[0],
// },
Command: []string{
"sh", "-x", "-c", "/deployments/k8s-setup.sh",
"sh", "-x", "-c", "/deployments/app_init.sh;",
},
Env: []corev1.EnvVar{
secretEnv("KEYCLOAK_USER", keycloakAdminSecret(cr), corev1.BasicAuthUsernameKey),
Expand All @@ -153,6 +195,11 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin
},
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "app-init",
MountPath: "/deployments/app_init.sh",
SubPath: "app_init.sh",
},
{
Name: "imports",
MountPath: "/etc/horreum/imports",
Expand All @@ -171,7 +218,6 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin
Image: appImage(cr),
Command: []string{
"sh", "-c", `
keytool -noprompt -import -alias service-ca -file /etc/ssl/certs/service-ca.crt -cacerts -storepass changeit
export QUARKUS_OIDC_CREDENTIALS_SECRET=$$(cat /etc/horreum/imports/clientsecret)
/deployments/horreum.sh
`,
Expand Down Expand Up @@ -210,3 +256,56 @@ func appService(cr *hyperfoilv1alpha1.Horreum, r *HorreumReconciler) *corev1.Ser
func appRoute(cr *hyperfoilv1alpha1.Horreum, r *HorreumReconciler) (*routev1.Route, error) {
return route(cr.Spec.Route, "", cr, r)
}

func appServiceAccount(cr *hyperfoilv1alpha1.Horreum) *corev1.ServiceAccount {
return &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "horreum-init",
Namespace: cr.Namespace,
},
}
}

// func appClusterRole(cr *hyperfoilv1alpha1.Horreum) *rbacv1.ClusterRole {
// return &rbacv1.ClusterRole{
// ObjectMeta: metav1.ObjectMeta{
// Name: "horreum-init-cluster-role",
// },
// Rules: []rbacv1.PolicyRule{
// {
// APIGroups: []string{
// "security.openshift.io",
// },
// ResourceNames: []string{
// "anyuid",
// },
// Resources: []string{
// "securitycontextconstraints",
// },
// Verbs: []string{
// "use",
// },
// },
// },
// }
// }

// func appClusterRoleBinding(cr *hyperfoilv1alpha1.Horreum) *rbacv1.ClusterRoleBinding {
// return &rbacv1.ClusterRoleBinding{
// ObjectMeta: metav1.ObjectMeta{
// Name: "horreum-init-cluster-role-binding",
// },
// RoleRef: rbacv1.RoleRef{
// APIGroup: "rbac.authorization.k8s.io",
// Kind: "ClusterRole",
// Name: "horreum-init-cluster-role",
// },
// Subjects: []rbacv1.Subject{
// {
// Kind: "ServiceAccount",
// Name: "horreum-init",
// Namespace: cr.Namespace,
// },
// },
// }
// }
30 changes: 27 additions & 3 deletions controllers/horreum_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (

routev1 "github.com/openshift/api/route/v1"
corev1 "k8s.io/api/core/v1"
// rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -63,7 +64,8 @@ var nocheck = func(interface{}) (bool, string, string) {
//+kubebuilder:rbac:groups=hyperfoil.io,resources=horreums,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=hyperfoil.io,resources=horreums/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=hyperfoil.io,resources=horreums/finalizers,verbs=update
//+kubebuilder:rbac:groups=core,resources=pods;services;services/finalizers;endpoints;persistentvolumeclaims;events;configmaps;secrets,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=pods;services;services/finalizers;endpoints;persistentvolumeclaims;events;configmaps;secrets;serviceaccounts,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;create
//+kubebuilder:rbac:groups=apps,resourceNames=horreum-operator,resources=deployments/finalizers,verbs=update
//+kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=get;list;watch;create;update;patch;delete
Expand Down Expand Up @@ -225,6 +227,10 @@ func (r *HorreumReconciler) Reconcile(ctx context.Context, request ctrl.Request)
}
cr.Status.KeycloakUrl = keycloakPublicUrl

keycloakConfigMap := keycloakConfigMap(cr)
if err := ensureSame(r, cr, logger, keycloakConfigMap, &corev1.ConfigMap{}, compareConfigMap, nocheck); err != nil {
return reconcile.Result{}, err
}
keycloakPod := keycloakPod(cr, keycloakPublicUrl)
if cr.Spec.Keycloak.External.PublicUri != "" {
if err := ensureDeleted(r, cr, keycloakPod, &corev1.Pod{}); err != nil {
Expand All @@ -238,10 +244,16 @@ func (r *HorreumReconciler) Reconcile(ctx context.Context, request ctrl.Request)
return reconcile.Result{}, err
}
}
} else if err := ensureSame(r, cr, logger, keycloakPod, &corev1.Pod{}, comparePods, checkPod); err != nil {
return reconcile.Result{}, err
} else {
if err := ensureSame(r, cr, logger, keycloakPod, &corev1.Pod{}, comparePods, checkPod); err != nil {
return reconcile.Result{}, err
}
}

appinitConfigMap := appinitConfigMap(cr)
if err := ensureSame(r, cr, logger, appinitConfigMap, &corev1.ConfigMap{}, compareConfigMap, nocheck); err != nil {
return reconcile.Result{}, err
}
appService := appService(cr, r)
appRoute, err := appRoute(cr, r)
if err != nil {
Expand Down Expand Up @@ -282,6 +294,18 @@ func (r *HorreumReconciler) Reconcile(ctx context.Context, request ctrl.Request)
}
cr.Status.PublicUrl = appPublicUrl

appServiceAccount := appServiceAccount(cr)
if err := ensureSame(r, cr, logger, appServiceAccount, &corev1.ServiceAccount{}, nocompare, nocheck); err != nil {
return reconcile.Result{}, err
}
// appClusterRole := appClusterRole(cr)
// if err := ensureSame(r, cr, logger, appClusterRole, &rbacv1.ClusterRole{}, nocompare, nocheck); err != nil {
// return reconcile.Result{}, err
// }
// appClusterRoleBinding := appClusterRoleBinding(cr)
// if err := ensureSame(r, cr, logger, appClusterRoleBinding, &rbacv1.ClusterRoleBinding{}, nocompare, nocheck); err != nil {
// return reconcile.Result{}, err
// }
appPod := appPod(cr, keycloakPublicUrl, appPublicUrl)
if err := ensureSame(r, cr, logger, appPod, &corev1.Pod{}, comparePods, checkPod); err != nil {
return reconcile.Result{}, err
Expand Down
Loading