Skip to content

Commit

Permalink
✨ support for setting decision export (#352)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdjgs authored Aug 27, 2024
1 parent 1bb634b commit b999f8b
Show file tree
Hide file tree
Showing 14 changed files with 405 additions and 68 deletions.
24 changes: 24 additions & 0 deletions api/config/v2alpha2/projectconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ type ProjectConfig struct {
// SystemUserRoles is a list of Styra DAS system level roles which the subjects of
// a system will be granted.
SystemUserRoles []string `json:"systemUserRoles"`

DecisionsExporter *DecisionsExporterConfig `json:"decisionsExporter,omitempty"`
}

// LeaderElectionConfig contains configuration for leader election
Expand Down Expand Up @@ -186,6 +188,28 @@ type GitCredential struct {
RepoPrefix string `json:"repoPrefix"`
}

// DecisionsExporterConfig contains configuration for decisions export
type DecisionsExporterConfig struct {
Interval string `json:"interval"`
Kafka *KafkaConfig `json:"kafka,omitempty"`
}

// KafkaConfig contains configuration for exporting decisions to Kafka
type KafkaConfig struct {
Brokers []string `json:"brokers"`
Topic string `json:"topic"`
RequiredAcks string `json:"requiredAcks"`
TLS *TLSConfig `json:"tls,omitempty"`
}

// TLSConfig contains TLS configuration for Kafka decisions export.
type TLSConfig struct {
ClientCertificateName string `json:"clientCertificateName"`
ClientCertificate string `json:"clientCertificate"`
ClientKey string `json:"clientKey"`
RootCA string `json:"rootCA"`
}

// GetGitCredentialForRepo determines which default GitCredential to use for checking out the
// policy repository based on the URL to the policy repository.
func (c *ProjectConfig) GetGitCredentialForRepo(repo string) *GitCredential {
Expand Down
65 changes: 65 additions & 0 deletions api/config/v2alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 52 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ limitations under the License.
package main

import (
"context"
"flag"
"fmt"
"os"
"strings"
"time"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
Expand Down Expand Up @@ -148,6 +150,11 @@ func main() {

styraClient := styra.New(ctrlConfig.Styra.Address, styraToken)

if err := configureDecisionExporter(styraClient, ctrlConfig); err != nil {
log.Error(err, "unable to configure decision export")
exit(err)
}

// System Controller
metric := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Expand All @@ -166,7 +173,7 @@ func main() {
r1 := &controllers.SystemReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Styra: styra.New(ctrlConfig.Styra.Address, styraToken),
Styra: styraClient,
Recorder: mgr.GetEventRecorderFor("system-controller"),
Metric: metric,
Config: ctrlConfig,
Expand Down Expand Up @@ -249,3 +256,47 @@ func exit(err error) {
sentry.Flush(2 * time.Second)
os.Exit(1)
}

// Issue: https://github.com/Bankdata/styra-controller/issues/353
func configureDecisionExporter(styraClient styra.ClientInterface, ctrlConfig *configv2alpha2.ProjectConfig) error {
if ctrlConfig.DecisionsExporter == nil {
ctrl.Log.Info("no decisions exporter configuration found")
return nil
}
ctrl.Log.Info("configuring decisions exporter")

clientCertName := ctrlConfig.DecisionsExporter.Kafka.TLS.ClientCertificateName

_, err := styraClient.CreateUpdateSecret(context.Background(), clientCertName, &styra.CreateUpdateSecretsRequest{
Description: "Client certificate for Kafka",
// Secret name should be client cert and secret should be client key
Name: strings.TrimSuffix(ctrlConfig.DecisionsExporter.Kafka.TLS.ClientCertificate, "\n"),
Secret: strings.TrimSuffix(ctrlConfig.DecisionsExporter.Kafka.TLS.ClientKey, "\n"),
},
)
if err != nil {
ctrl.Log.Error(err, "could not upload client certificate and key")
return err
}

_, err = styraClient.UpdateWorkspace(context.Background(), &styra.UpdateWorkspaceRequest{
DecisionsExporter: &styra.DecisionExportConfig{
Interval: ctrlConfig.DecisionsExporter.Interval,
Kafka: &styra.KafkaConfig{
Authentication: "TLS",
Brokers: ctrlConfig.DecisionsExporter.Kafka.Brokers,
RequredAcks: ctrlConfig.DecisionsExporter.Kafka.RequiredAcks,
Topic: ctrlConfig.DecisionsExporter.Kafka.Topic,
TLS: &styra.KafkaTLS{
ClientCert: clientCertName,
RootCA: strings.TrimSuffix(ctrlConfig.DecisionsExporter.Kafka.TLS.RootCA, "\n"),
}},
}})
if err != nil {
ctrl.Log.Error(err, "could not update workspace configuration")
return err
}

ctrl.Log.Info("successfully configured decisions exporter")
return nil
}
2 changes: 1 addition & 1 deletion config/crd/bases/styra.bankdata.dk_globaldatasources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.15.0
controller-gen.kubebuilder.io/version: v0.16.1
name: globaldatasources.styra.bankdata.dk
spec:
group: styra.bankdata.dk
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/styra.bankdata.dk_libraries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.15.0
controller-gen.kubebuilder.io/version: v0.16.1
name: libraries.styra.bankdata.dk
spec:
group: styra.bankdata.dk
Expand Down
2 changes: 1 addition & 1 deletion config/crd/bases/styra.bankdata.dk_systems.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.15.0
controller-gen.kubebuilder.io/version: v0.16.1
name: systems.styra.bankdata.dk
spec:
group: styra.bankdata.dk
Expand Down
2 changes: 2 additions & 0 deletions config/default/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ systemUserRoles:
- SystemOwner
- SystemMetadataManager

#decisionsExporter:

#opa:
# decision_logs:
# request_context:
Expand Down
2 changes: 1 addition & 1 deletion config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ kind: Kustomization
images:
- name: controller
newName: controller
newTag: latest
newTag: latest
67 changes: 5 additions & 62 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ rules:
- ""
resources:
- configmaps
- secrets
verbs:
- create
- delete
Expand All @@ -23,73 +24,11 @@ rules:
verbs:
- create
- patch
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- styra.bankdata.dk
resources:
- globaldatasources
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- styra.bankdata.dk
resources:
- globaldatasources/finalizers
verbs:
- update
- apiGroups:
- styra.bankdata.dk
resources:
- globaldatasources/status
verbs:
- get
- patch
- update
- apiGroups:
- styra.bankdata.dk
resources:
- libraries
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- styra.bankdata.dk
resources:
- libraries/finalizers
verbs:
- update
- apiGroups:
- styra.bankdata.dk
resources:
- libraries/status
verbs:
- get
- patch
- update
- apiGroups:
- styra.bankdata.dk
resources:
- systems
verbs:
- create
Expand All @@ -102,12 +41,16 @@ rules:
- apiGroups:
- styra.bankdata.dk
resources:
- globaldatasources/finalizers
- libraries/finalizers
- systems/finalizers
verbs:
- update
- apiGroups:
- styra.bankdata.dk
resources:
- globaldatasources/status
- libraries/status
- systems/status
verbs:
- get
Expand Down
32 changes: 31 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This document describes the different configuration options for the Styra Contro
* `systemPrefix`
* `systemSuffix`
* `systemUserRoles`
* `decisionsExporter`

## Observability

Expand Down Expand Up @@ -108,4 +109,33 @@ Styra Systems can be read-only, meaning they cannot be changed in the Styra GUI.
An annotation that allows configuring Systems in Kubernetes to link to a specific system in Styra. The ID that the system in Kubernetes should link to is configured by setting `styra-contoller/migration-id: [styra system id]` annotation on Kubernetes system resource. Should only be set while migrating.

## Leader Election
If multiple instances of the controller are running together, leader election can be configured by setting `leaderElection.leaseDuration`, `leaderElection.renewDeadline`, `leaderElection.retryPeriod`.
If multiple instances of the controller are running together, leader election can be configured by setting `leaderElection.leaseDuration`, `leaderElection.renewDeadline`, `leaderElection.retryPeriod`.

## Decisions Exporter
It is possible to configure all decisions to be exported to a Kafka cluster. This is achieved by setting the `decisionsExporter` in the controller configuration. For example, if `decisionsExporter` is set to this:

```yaml
decisionsExporter:
interval: 30s
kafka:
brokers:
- broker1.com:1111
- broker2.com:2222
requiredAcks: WaitForAll
topic: bd-styra-opa-dev
tls:
clientCertificateName: kafka-client-cert
clientCertificate: |
-----BEGIN CERTIFICATE-----
Client Certificate
-----END CERTIFICATE-----
clientKey: |
-----BEGIN PRIVATE KEY-----
Client Key
-----END PRIVATE KEY-----
rootCA: |
-----BEGIN CERTIFICATE-----
Root Certificate
-----END CERTIFICATE-----
```
It will configure Styra to export all decisions to the brokers and connect via mTLS using the provided certs and key. The decision exporter configuration will be uploaded to Styra each time the controller boots.
Loading

0 comments on commit b999f8b

Please sign in to comment.