Skip to content

Commit

Permalink
feat(insights): optionally deploy a proxy for Insights (#670)
Browse files Browse the repository at this point in the history
* feat(insights): mount Insights token in Cryostat container

Signed-off-by: Elliott Baron <ebaron@redhat.com>

* Use 0440 mode for mounted token

* Envtest based tests for controller watch changes

* Fix hardcoded OpenShift module version

* clean up test

* Create HTTP proxy for communicating with Insights

* Handle deletion case, add tests

* Set INSIGHTS_PROXY, additional testing

* cleanup

* Convert filter test to unit test

* Move setup to its own test file

* cleanup

* Add resource requirements and more tests

* Fix license

* Check the rest of the deployment too

* Update log message

* Add Bearer to Authentication header

* Fix AllNamespaces install mode handling

* Regenerate bundle

---------

Signed-off-by: Elliott Baron <ebaron@redhat.com>
  • Loading branch information
ebaron committed Nov 7, 2023
1 parent a9c8d89 commit d719e43
Show file tree
Hide file tree
Showing 35 changed files with 2,411 additions and 134 deletions.
22 changes: 19 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,19 @@ ifneq ("$(wildcard $(GINKGO))","")
GO_TEST="$(GINKGO)" -cover -output-dir=.
endif

# Optional Red Hat Insights integration
ENABLE_INSIGHTS ?= false
ifeq ($(ENABLE_INSIGHTS), true)
KUSTOMIZE_DIR ?= config/insights
INSIGHTS_PROXY_NAMESPACE ?= quay.io/3scale
INSIGHTS_PROXY_NAME ?= apicast
INSIGHTS_PROXY_VERSION ?= insights-01
export INSIGHTS_PROXY_IMG ?= $(INSIGHTS_PROXY_NAMESPACE)/$(INSIGHTS_PROXY_NAME):$(INSIGHTS_PROXY_VERSION)
export INSIGHTS_BACKEND ?= cert.console.redhat.com
else
KUSTOMIZE_DIR ?= config/default
endif

##@ General

.PHONY: all
Expand Down Expand Up @@ -275,6 +288,9 @@ manifests: controller-gen ## Generate manifests e.g. CRD, RBAC, etc.
$(CONTROLLER_GEN) rbac:roleName=role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
envsubst < hack/image_tag_patch.yaml.in > config/default/image_tag_patch.yaml
envsubst < hack/image_pull_patch.yaml.in > config/default/image_pull_patch.yaml
ifeq ($(ENABLE_INSIGHTS), true)
envsubst < hack/insights_patch.yaml.in > config/insights/insights_patch.yaml
endif

.PHONY: fmt
fmt: add-license ## Run go fmt against code.
Expand Down Expand Up @@ -435,11 +451,11 @@ predeploy:

.PHONY: print_deploy_config
print_deploy_config: predeploy ## Print deployment configurations for the controller.
$(KUSTOMIZE) build config/default
$(KUSTOMIZE) build $(KUSTOMIZE_DIR)

.PHONY: deploy
deploy: check_cert_manager manifests kustomize predeploy ## Deploy controller in the configured cluster in ~/.kube/config
$(KUSTOMIZE) build config/default | $(CLUSTER_CLIENT) apply -f -
$(KUSTOMIZE) build $(KUSTOMIZE_DIR) | $(CLUSTER_CLIENT) apply -f -
ifeq ($(DISABLE_SERVICE_TLS), true)
@echo "Disabling TLS for in-cluster communication between Services"
@$(CLUSTER_CLIENT) -n $(DEPLOY_NAMESPACE) set env deployment/cryostat-operator-controller-manager DISABLE_SERVICE_TLS=true
Expand All @@ -449,7 +465,7 @@ endif
undeploy: ## Undeploy controller from the configured cluster in ~/.kube/config.
- $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f config/samples/operator_v1beta1_cryostat.yaml
- $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f config/samples/operator_v1beta1_clustercryostat.yaml
- $(KUSTOMIZE) build config/default | $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f -
- $(KUSTOMIZE) build $(KUSTOMIZE_DIR) | $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f -

.PHONY: deploy_bundle
deploy_bundle: check_cert_manager undeploy_bundle ## Deploy the controller in the bundle format with OLM.
Expand Down
22 changes: 21 additions & 1 deletion bundle/manifests/cryostat-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ metadata:
capabilities: Seamless Upgrades
categories: Monitoring, Developer Tools
containerImage: quay.io/cryostat/cryostat-operator:2.5.0-dev
createdAt: "2023-10-11T14:49:05Z"
createdAt: "2023-11-07T20:18:21Z"
description: JVM monitoring and profiling tool
operatorframework.io/initialization-resource: |-
{
Expand Down Expand Up @@ -879,6 +879,15 @@ spec:
spec:
clusterPermissions:
- rules:
- apiGroups:
- ""
resources:
- configmaps
- configmaps/finalizers
- secrets
- services
verbs:
- '*'
- apiGroups:
- ""
resources:
Expand Down Expand Up @@ -916,6 +925,13 @@ spec:
- statefulsets
verbs:
- '*'
- apiGroups:
- apps
resources:
- deployments
- deployments/finalizers
verbs:
- '*'
- apiGroups:
- apps.openshift.io
resources:
Expand Down Expand Up @@ -1084,6 +1100,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.annotations['olm.targetNamespaces']
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/cryostat/cryostat-operator:2.5.0-dev
imagePullPolicy: Always
livenessProbe:
Expand Down
17 changes: 17 additions & 0 deletions config/insights/insights_patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
env:
- name: RELATED_IMAGE_INSIGHTS_PROXY
value: "quay.io/3scale/apicast:insights-01"
- name: INSIGHTS_ENABLED
value: "true"
- name: INSIGHTS_BACKEND_DOMAIN
value: "cert.console.redhat.com"
5 changes: 5 additions & 0 deletions config/insights/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resources:
- ../default

patchesStrategicMerge:
- insights_patch.yaml
4 changes: 4 additions & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ spec:
env:
- name: WATCH_NAMESPACE
value: ""
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
resources:
limits:
cpu: 1000m
Expand Down
16 changes: 16 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ metadata:
creationTimestamp: null
name: role
rules:
- apiGroups:
- ""
resources:
- configmaps
- configmaps/finalizers
- secrets
- services
verbs:
- '*'
- apiGroups:
- ""
resources:
Expand Down Expand Up @@ -42,6 +51,13 @@ rules:
- statefulsets
verbs:
- '*'
- apiGroups:
- apps
resources:
- deployments
- deployments/finalizers
verbs:
- '*'
- apiGroups:
- apps.openshift.io
resources:
Expand Down
17 changes: 17 additions & 0 deletions hack/insights_patch.yaml.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
env:
- name: RELATED_IMAGE_INSIGHTS_PROXY
value: "${INSIGHTS_PROXY_IMG}"
- name: INSIGHTS_ENABLED
value: "true"
- name: INSIGHTS_BACKEND_DOMAIN
value: "${INSIGHTS_BACKEND}"
14 changes: 8 additions & 6 deletions internal/controllers/clustercryostat_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ type ClusterCryostatReconciler struct {
*ReconcilerConfig
}

func NewClusterCryostatReconciler(config *ReconcilerConfig) *ClusterCryostatReconciler {
func NewClusterCryostatReconciler(config *ReconcilerConfig) (*ClusterCryostatReconciler, error) {
delegate, err := newReconciler(config, &operatorv1beta1.ClusterCryostat{}, false)
if err != nil {
return nil, err
}
return &ClusterCryostatReconciler{
ReconcilerConfig: config,
delegate: &Reconciler{
ReconcilerConfig: config,
},
}
delegate: delegate,
}, nil
}

// +kubebuilder:rbac:groups="",resources=pods;services;services/finalizers;endpoints;persistentvolumeclaims;events;configmaps;secrets;serviceaccounts,verbs=*
Expand Down Expand Up @@ -94,7 +96,7 @@ func (r *ClusterCryostatReconciler) Reconcile(ctx context.Context, request ctrl.

// SetupWithManager sets up the controller with the Manager.
func (r *ClusterCryostatReconciler) SetupWithManager(mgr ctrl.Manager) error {
return r.delegate.setupWithManager(mgr, &operatorv1beta1.ClusterCryostat{}, r)
return r.delegate.setupWithManager(mgr, r)
}

func (r *ClusterCryostatReconciler) GetConfig() *ReconcilerConfig {
Expand Down
2 changes: 1 addition & 1 deletion internal/controllers/clustercryostat_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,6 @@ func (t *cryostatTestInput) expectTargetNamespaces() {
Expect(*cr.TargetNamespaceStatus).To(ConsistOf(t.TargetNamespaces))
}

func newClusterCryostatController(config *controllers.ReconcilerConfig) controllers.CommonReconciler {
func newClusterCryostatController(config *controllers.ReconcilerConfig) (controllers.CommonReconciler, error) {
return controllers.NewClusterCryostatReconciler(config)
}
34 changes: 27 additions & 7 deletions internal/controllers/common/common_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import (
"strings"
"time"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
logf "sigs.k8s.io/controller-runtime/pkg/log"
)
Expand All @@ -37,21 +39,21 @@ type OSUtils interface {
GenPasswd(length int) string
}

type defaultOSUtils struct{}
type DefaultOSUtils struct{}

// GetEnv returns the value of the environment variable with the provided name. If no such
// variable exists, the empty string is returned.
func (o *defaultOSUtils) GetEnv(name string) string {
func (o *DefaultOSUtils) GetEnv(name string) string {
return os.Getenv(name)
}

// GetFileContents reads and returns the entire file contents specified by the path
func (o *defaultOSUtils) GetFileContents(path string) ([]byte, error) {
func (o *DefaultOSUtils) GetFileContents(path string) ([]byte, error) {
return ioutil.ReadFile(path)
}

// GenPasswd generates a psuedorandom password of a given length.
func (o *defaultOSUtils) GenPasswd(length int) string {
func (o *DefaultOSUtils) GenPasswd(length int) string {
rand.Seed(time.Now().UnixNano())
chars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
b := make([]byte, length)
Expand All @@ -63,13 +65,16 @@ func (o *defaultOSUtils) GenPasswd(length int) string {

// ClusterUniqueName returns a name for cluster-scoped objects that is
// uniquely identified by a namespace and name.
func ClusterUniqueName(kind string, name string, namespace string) string {
func ClusterUniqueName(gvk *schema.GroupVersionKind, name string, namespace string) string {
// Use the SHA256 checksum of the namespaced name as a suffix
nn := types.NamespacedName{Namespace: namespace, Name: name}
suffix := fmt.Sprintf("%x", sha256.Sum256([]byte(nn.String())))
return strings.ToLower(kind) + "-" + suffix
return strings.ToLower(gvk.Kind) + "-" + suffix
}

// MergeLabelsAndAnnotations copies labels and annotations from a source
// to the destination ObjectMeta, overwriting any existing labels and
// annotations of the same key.
func MergeLabelsAndAnnotations(dest *metav1.ObjectMeta, srcLabels, srcAnnotations map[string]string) {
// Check and create labels/annotations map if absent
if dest.Labels == nil {
Expand All @@ -83,8 +88,23 @@ func MergeLabelsAndAnnotations(dest *metav1.ObjectMeta, srcLabels, srcAnnotation
for k, v := range srcLabels {
dest.Labels[k] = v
}

for k, v := range srcAnnotations {
dest.Annotations[k] = v
}
}

// SeccompProfile returns a SeccompProfile for the restricted
// Pod Security Standard that, on OpenShift, is backwards-compatible
// with OpenShift < 4.11.
// TODO Remove once OpenShift < 4.11 support is dropped
func SeccompProfile(openshift bool) *corev1.SeccompProfile {
// For backward-compatibility with OpenShift < 4.11,
// leave the seccompProfile empty. In OpenShift >= 4.11,
// the restricted-v2 SCC will populate it for us.
if openshift {
return nil
}
return &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
}
}
Loading

0 comments on commit d719e43

Please sign in to comment.