Skip to content

Commit

Permalink
operator: Add TLS profile support for Loki server and client HTTP and…
Browse files Browse the repository at this point in the history
… GRPC TLS options (grafana#7322)
  • Loading branch information
Red-GV authored and lxwzy committed Nov 7, 2022
1 parent af7fdee commit a672dd5
Show file tree
Hide file tree
Showing 24 changed files with 545 additions and 280 deletions.
1 change: 1 addition & 0 deletions operator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Main

- [7322](https://github.com/grafana/loki/pull/7322) **Red-GV**: Configuring server and client HTTP and GRPC TLS options
- [7272](https://github.com/grafana/loki/pull/7272) **aminesnow**: Use cluster monitoring alertmanager by default on openshift clusters
- [7295](https://github.com/grafana/loki/pull/7295) **xperimental**: Add extended-validation for rules on OpenShift
- [6951](https://github.com/grafana/loki/pull/6951) **Red-GV**: Adding operational Lokistack alerts
Expand Down
17 changes: 6 additions & 11 deletions operator/apis/config/v1/projectconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ type OpenShiftFeatureGates struct {
// ExtendedRuleValidation enables extended validation of AlertingRule and RecordingRule
// to enforce tenancy in an OpenShift context.
ExtendedRuleValidation bool `json:"ruleExtendedValidation,omitempty"`

// ClusterTLSPolicy enables usage of TLS policies set in the API Server.
// More details: https://docs.openshift.com/container-platform/4.11/security/tls-security-profiles.html
ClusterTLSPolicy bool `json:"clusterTLSPolicy,omitempty"`
}

// FeatureGates is the supported set of all operator feature gates.
Expand Down Expand Up @@ -78,7 +82,8 @@ type FeatureGates struct {
// OpenShift contains a set of feature gates supported only on OpenShift.
OpenShift OpenShiftFeatureGates `json:"openshift,omitempty"`

// TLSProfile allows to chose a TLS security profile.
// TLSProfile allows to chose a TLS security profile. Enforced
// when using HTTPEncryption or GRPCEncryption.
TLSProfile string `json:"tlsProfile,omitempty"`
}

Expand All @@ -98,16 +103,6 @@ const (
TLSProfileModernType TLSProfileType = "Modern"
)

// TLSProfileSpec is the desired behavior of a TLSProfileType.
type TLSProfileSpec struct {
// ciphers is used to specify the cipher algorithms that are negotiated
// during the TLS handshake.
Ciphers []string
// minTLSVersion is used to specify the minimal version of the TLS protocol
// that is negotiated during the TLS handshake.
MinTLSVersion string
}

//+kubebuilder:object:root=true

// ProjectConfig is the Schema for the projectconfigs API
Expand Down
20 changes: 0 additions & 20 deletions operator/apis/config/v1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ data:
servingCertsService: true
gatewayRoute: true
ruleExtendedValidation: true
clusterTLSPolicy: true
kind: ConfigMap
metadata:
labels:
Expand Down
38 changes: 25 additions & 13 deletions operator/cmd/loki-broker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import (
"path"
"strings"

"github.com/ViaQ/logerr/v2/log"
"github.com/go-logr/logr"
configv1 "github.com/grafana/loki/operator/apis/config/v1"
projectconfigv1 "github.com/grafana/loki/operator/apis/config/v1"
lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
"github.com/grafana/loki/operator/internal/manifests"
"github.com/grafana/loki/operator/internal/manifests/storage"

"github.com/ViaQ/logerr/v2/log"
"github.com/go-logr/logr"
openshiftv1 "github.com/openshift/api/config/v1"
"sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -129,29 +130,40 @@ func main() {
}

if cfg.featureFlags.TLSProfile != "" &&
cfg.featureFlags.TLSProfile != string(projectconfigv1.TLSProfileOldType) &&
cfg.featureFlags.TLSProfile != string(projectconfigv1.TLSProfileIntermediateType) &&
cfg.featureFlags.TLSProfile != string(projectconfigv1.TLSProfileModernType) {
cfg.featureFlags.TLSProfile != string(configv1.TLSProfileOldType) &&
cfg.featureFlags.TLSProfile != string(configv1.TLSProfileIntermediateType) &&
cfg.featureFlags.TLSProfile != string(configv1.TLSProfileModernType) {
logger.Error(err, "failed to parse TLS profile. Allowed values: 'Old', 'Intermediate', 'Modern'", "value", cfg.featureFlags.TLSProfile)
os.Exit(1)
}

// Convert config to manifest.Options
opts := manifests.Options{
Name: cfg.Name,
Namespace: cfg.Namespace,
Image: cfg.Image,
Stack: ls.Spec,
Gates: cfg.featureFlags,
ObjectStorage: cfg.objectStorage,
TLSProfileType: projectconfigv1.TLSProfileType(cfg.featureFlags.TLSProfile),
Name: cfg.Name,
Namespace: cfg.Namespace,
Image: cfg.Image,
Stack: ls.Spec,
Gates: cfg.featureFlags,
ObjectStorage: cfg.objectStorage,
}

if optErr := manifests.ApplyDefaultSettings(&opts); optErr != nil {
logger.Error(optErr, "failed to conform options to build settings")
os.Exit(1)
}

var tlsSecurityProfile *openshiftv1.TLSSecurityProfile = nil
if cfg.featureFlags.TLSProfile != "" {
tlsSecurityProfile = &openshiftv1.TLSSecurityProfile{
Type: openshiftv1.TLSProfileType(cfg.featureFlags.TLSProfile),
}
}

if optErr := manifests.ApplyTLSSettings(&opts, tlsSecurityProfile); optErr != nil {
logger.Error(optErr, "failed to conform options to tls profile settings")
os.Exit(1)
}

objects, err := manifests.BuildAll(opts)
if err != nil {
logger.Error(err, "failed to build manifests")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ featureGates:
servingCertsService: true
gatewayRoute: true
ruleExtendedValidation: true
clusterTLSPolicy: true
5 changes: 5 additions & 0 deletions operator/controllers/loki/lokistack_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/grafana/loki/operator/internal/status"
routev1 "github.com/openshift/api/route/v1"

openshiftconfigv1 "github.com/openshift/api/config/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
Expand Down Expand Up @@ -174,5 +175,9 @@ func (r *LokiStackReconciler) buildController(bld k8s.Builder) error {
bld = bld.Owns(&networkingv1.Ingress{}, updateOrDeleteOnlyPred)
}

if r.FeatureGates.OpenShift.ClusterTLSPolicy {
bld = bld.Owns(&openshiftconfigv1.APIServer{}, updateOrDeleteOnlyPred)
}

return bld.Complete(r)
}
96 changes: 60 additions & 36 deletions operator/controllers/loki/lokistack_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/ViaQ/logerr/v2/log"
"github.com/go-logr/logr"
openshiftconfigv1 "github.com/openshift/api/config/v1"
routev1 "github.com/openshift/api/route/v1"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -74,63 +75,74 @@ func TestLokiStackController_RegisterOwnedResourcesForUpdateOrDeleteOnly(t *test

// Require owned resources
type test struct {
obj client.Object
index int
featureGates configv1.FeatureGates
pred builder.OwnsOption
obj client.Object
index int
ownCallsCount int
featureGates configv1.FeatureGates
pred builder.OwnsOption
}
table := []test{
{
obj: &corev1.ConfigMap{},
index: 0,
pred: updateOrDeleteOnlyPred,
obj: &corev1.ConfigMap{},
index: 0,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &corev1.ServiceAccount{},
index: 1,
pred: updateOrDeleteOnlyPred,
obj: &corev1.ServiceAccount{},
index: 1,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &corev1.Service{},
index: 2,
pred: updateOrDeleteOnlyPred,
obj: &corev1.Service{},
index: 2,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &appsv1.Deployment{},
index: 3,
pred: updateOrDeleteOnlyPred,
obj: &appsv1.Deployment{},
index: 3,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &appsv1.StatefulSet{},
index: 4,
pred: updateOrDeleteOnlyPred,
obj: &appsv1.StatefulSet{},
index: 4,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &rbacv1.ClusterRole{},
index: 5,
pred: updateOrDeleteOnlyPred,
obj: &rbacv1.ClusterRole{},
index: 5,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &rbacv1.ClusterRoleBinding{},
index: 6,
pred: updateOrDeleteOnlyPred,
obj: &rbacv1.ClusterRoleBinding{},
index: 6,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &rbacv1.Role{},
index: 7,
pred: updateOrDeleteOnlyPred,
obj: &rbacv1.Role{},
index: 7,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
{
obj: &rbacv1.RoleBinding{},
index: 8,
pred: updateOrDeleteOnlyPred,
obj: &rbacv1.RoleBinding{},
index: 8,
ownCallsCount: 10,
pred: updateOrDeleteOnlyPred,
},
// The next two share the same index, because the
// controller either reconciles an Ingress (i.e. Kubernetes)
// or a Route (i.e. OpenShift).
{
obj: &networkingv1.Ingress{},
index: 9,
obj: &networkingv1.Ingress{},
index: 9,
ownCallsCount: 10,
featureGates: configv1.FeatureGates{
OpenShift: configv1.OpenShiftFeatureGates{
GatewayRoute: false,
Expand All @@ -139,15 +151,27 @@ func TestLokiStackController_RegisterOwnedResourcesForUpdateOrDeleteOnly(t *test
pred: updateOrDeleteOnlyPred,
},
{
obj: &routev1.Route{},
index: 9,
obj: &routev1.Route{},
index: 9,
ownCallsCount: 10,
featureGates: configv1.FeatureGates{
OpenShift: configv1.OpenShiftFeatureGates{
GatewayRoute: true,
},
},
pred: updateOrDeleteOnlyPred,
},
{
obj: &openshiftconfigv1.APIServer{},
index: 10,
ownCallsCount: 11,
featureGates: configv1.FeatureGates{
OpenShift: configv1.OpenShiftFeatureGates{
ClusterTLSPolicy: true,
},
},
pred: updateOrDeleteOnlyPred,
},
}
for _, tst := range table {
b := &k8sfakes.FakeBuilder{}
Expand All @@ -159,7 +183,7 @@ func TestLokiStackController_RegisterOwnedResourcesForUpdateOrDeleteOnly(t *test
require.NoError(t, err)

// Require Owns-Calls for all owned resources
require.Equal(t, 10, b.OwnsCallCount())
require.Equal(t, tst.ownCallsCount, b.OwnsCallCount())

// Require Owns-call options to have delete predicate only
obj, opts := b.OwnsArgsForCall(tst.index)
Expand Down
Loading

0 comments on commit a672dd5

Please sign in to comment.