operator: Store gateway tenant information in secret instead of configmap (#8577)

pull/8578/head^2
Gerard Vanloo 2 years ago committed by GitHub
parent 2836c79537
commit 233997ef20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      operator/CHANGELOG.md
  2. 26
      operator/internal/handlers/internal/gateway/tenant_configsecret.go
  3. 12
      operator/internal/handlers/internal/gateway/tenant_configsecret_test.go
  4. 4
      operator/internal/handlers/lokistack_create_or_update.go
  5. 59
      operator/internal/manifests/gateway.go
  6. 26
      operator/internal/manifests/gateway_test.go
  7. 40
      operator/internal/manifests/internal/config/build_test.go

@ -1,5 +1,6 @@
## Main
- [8577](https://github.com/grafana/loki/pull/8577) **Red-GV**: Store gateway tenant information in secret instead of configmap
- [8397](https://github.com/grafana/loki/pull/8397) **periklis**: Update Loki operand to v2.7.3
- [8308](https://github.com/grafana/loki/pull/8308) **aminesnow**: operator: Cleanup ruler resources when disabled
- [8336](https://github.com/grafana/loki/pull/8336) **periklis**: Update Loki operand to v2.7.2

@ -35,22 +35,22 @@ type openShiftSpec struct {
CookieSecret string `json:"cookieSecret"`
}
// GetTenantConfigMapData returns the tenantName, tenantId, cookieSecret
// GetTenantConfigSecretData returns the tenantName, tenantId, cookieSecret
// clusters to auto-create redirect URLs for OpenShift Auth or an error.
func GetTenantConfigMapData(ctx context.Context, k k8s.Client, req ctrl.Request) (map[string]manifests.TenantConfig, error) {
var tenantConfigMap corev1.ConfigMap
func GetTenantConfigSecretData(ctx context.Context, k k8s.Client, req ctrl.Request) (map[string]manifests.TenantConfig, error) {
var tenantSecret corev1.Secret
key := client.ObjectKey{Name: manifests.GatewayName(req.Name), Namespace: req.Namespace}
if err := k.Get(ctx, key, &tenantConfigMap); err != nil {
return nil, kverrors.Wrap(err, "couldn't find tenant configMap.")
if err := k.Get(ctx, key, &tenantSecret); err != nil {
return nil, kverrors.Wrap(err, "couldn't find tenant secret.")
}
tcm, err := extractTenantConfigMap(&tenantConfigMap)
ts, err := extractTenantConfigMap(&tenantSecret)
if err != nil {
return nil, kverrors.Wrap(err, "error occurred in extracting tenants.yaml configMap.")
return nil, kverrors.Wrap(err, "error occurred in extracting tenants.yaml secret.")
}
tcmMap := make(map[string]manifests.TenantConfig)
for _, tenant := range tcm.Tenants {
tsMap := make(map[string]manifests.TenantConfig)
for _, tenant := range ts.Tenants {
tc := manifests.TenantConfig{}
if tenant.OpenShift != nil {
tc.OpenShift = &manifests.TenantOpenShiftSpec{
@ -58,17 +58,17 @@ func GetTenantConfigMapData(ctx context.Context, k k8s.Client, req ctrl.Request)
}
}
tcmMap[tenant.Name] = tc
tsMap[tenant.Name] = tc
}
return tcmMap, nil
return tsMap, nil
}
// extractTenantConfigMap extracts tenants.yaml data if valid.
// This is to be used to configure tenant's authentication spec when exists.
func extractTenantConfigMap(cm *corev1.ConfigMap) (*tenantsConfigJSON, error) {
func extractTenantConfigMap(s *corev1.Secret) (*tenantsConfigJSON, error) {
// Extract required fields from tenants.yaml
tenantConfigYAML, ok := cm.BinaryData[LokiGatewayTenantFileName]
tenantConfigYAML, ok := s.Data[LokiGatewayTenantFileName]
if !ok {
return nil, kverrors.New("missing tenants.yaml file in configMap.")
}

@ -36,7 +36,7 @@ tenants:
cookieSecret: test789
`)
func TestGetTenantConfigMapData_ConfigMapExist(t *testing.T) {
func TestGetTenantConfigSecretData_SecretExist(t *testing.T) {
k := &k8sfakes.FakeClient{}
r := ctrl.Request{
NamespacedName: types.NamespacedName{
@ -47,12 +47,12 @@ func TestGetTenantConfigMapData_ConfigMapExist(t *testing.T) {
k.GetStub = func(_ context.Context, name types.NamespacedName, object client.Object, _ ...client.GetOption) error {
if name.Name == "lokistack-dev-gateway" && name.Namespace == "some-ns" {
k.SetClientObject(object, &corev1.ConfigMap{
k.SetClientObject(object, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "lokistack-dev-gateway",
Namespace: "some-ns",
},
BinaryData: map[string][]byte{
Data: map[string][]byte{
"tenants.yaml": tenantConfigData,
},
})
@ -60,7 +60,7 @@ func TestGetTenantConfigMapData_ConfigMapExist(t *testing.T) {
return nil
}
ts, err := GetTenantConfigMapData(context.TODO(), k, r)
ts, err := GetTenantConfigSecretData(context.TODO(), k, r)
require.NotNil(t, ts)
require.NoError(t, err)
@ -84,7 +84,7 @@ func TestGetTenantConfigMapData_ConfigMapExist(t *testing.T) {
require.Equal(t, expected, ts)
}
func TestGetTenantConfigMapData_ConfigMapNotExist(t *testing.T) {
func TestGetTenantConfigSecretData_SecretNotExist(t *testing.T) {
k := &k8sfakes.FakeClient{}
r := ctrl.Request{
NamespacedName: types.NamespacedName{
@ -97,7 +97,7 @@ func TestGetTenantConfigMapData_ConfigMapNotExist(t *testing.T) {
return apierrors.NewNotFound(schema.GroupResource{}, "something wasn't found")
}
ts, err := GetTenantConfigMapData(context.TODO(), k, r)
ts, err := GetTenantConfigSecretData(context.TODO(), k, r)
require.Nil(t, ts)
require.Error(t, err)
}

@ -190,9 +190,9 @@ func CreateOrUpdateLokiStack(
}
// extract the existing tenant's id, cookieSecret if exists, otherwise create new.
tenantConfigs, err = gateway.GetTenantConfigMapData(ctx, k, req)
tenantConfigs, err = gateway.GetTenantConfigSecretData(ctx, k, req)
if err != nil {
ll.Error(err, "error in getting tenant config map data")
ll.Error(err, "error in getting tenant secret data")
}
}

@ -30,7 +30,7 @@ var logsEndpointRe = regexp.MustCompile(`^--logs\.(?:read|tail|write|rules)\.end
// BuildGateway returns a list of k8s objects for Loki Stack Gateway
func BuildGateway(opts Options) ([]client.Object, error) {
cm, sha1C, err := gatewayConfigMap(opts)
cm, tenantSecret, sha1C, err := gatewayConfigObjs(opts)
if err != nil {
return nil, err
}
@ -45,7 +45,7 @@ func BuildGateway(opts Options) ([]client.Object, error) {
return nil, err
}
objs := []client.Object{cm, dpl, sa, saToken, svc, ing}
objs := []client.Object{cm, tenantSecret, dpl, sa, saToken, svc, ing}
minTLSVersion := opts.TLSProfile.MinTLSVersion
ciphersList := opts.TLSProfile.Ciphers
@ -104,10 +104,8 @@ func NewGatewayDeployment(opts Options, sha1C string) *appsv1.Deployment {
{
Name: "tenants",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: GatewayName(opts.Name),
},
Secret: &corev1.SecretVolumeSource{
SecretName: GatewayName(opts.Name),
},
},
},
@ -349,36 +347,49 @@ func NewServiceAccountTokenSecret(opts Options) client.Object {
}
}
// gatewayConfigMap creates a configMap for rbac.yaml and tenants.yaml
func gatewayConfigMap(opt Options) (*corev1.ConfigMap, string, error) {
// gatewayConfigObjs creates a configMap for rbac.yaml and a secret for tenants.yaml
func gatewayConfigObjs(opt Options) (*corev1.ConfigMap, *corev1.Secret, string, error) {
cfg := gatewayConfigOptions(opt)
rbacConfig, tenantsConfig, regoConfig, err := gateway.Build(cfg)
if err != nil {
return nil, "", err
return nil, nil, "", err
}
s := sha1.New()
_, err = s.Write(tenantsConfig)
if err != nil {
return nil, "", err
return nil, nil, "", err
}
sha1C := fmt.Sprintf("%x", s.Sum(nil))
return &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: corev1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: GatewayName(opt.Name),
Labels: commonLabels(opt.Name),
},
BinaryData: map[string][]byte{
gateway.LokiGatewayRbacFileName: rbacConfig,
gateway.LokiGatewayTenantFileName: tenantsConfig,
gateway.LokiGatewayRegoFileName: regoConfig,
},
}, sha1C, nil
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: corev1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: GatewayName(opt.Name),
Labels: commonLabels(opt.Name),
},
BinaryData: map[string][]byte{
gateway.LokiGatewayRbacFileName: rbacConfig,
gateway.LokiGatewayRegoFileName: regoConfig,
},
}, &corev1.Secret{
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: corev1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: GatewayName(opt.Name),
Labels: ComponentLabels(LabelGatewayComponent, opt.Name),
Namespace: opt.Namespace,
},
Data: map[string][]byte{
gateway.LokiGatewayTenantFileName: tenantsConfig,
},
Type: corev1.SecretTypeOpaque,
}, sha1C, nil
}
// gatewayConfigOptions converts Options to gateway.Options

@ -152,7 +152,7 @@ func TestGatewayConfigMap_ReturnsSHA1OfBinaryContents(t *testing.T) {
},
}
_, sha1C, err := gatewayConfigMap(opts)
_, _, sha1C, err := gatewayConfigObjs(opts)
require.NoError(t, err)
require.NotEmpty(t, sha1C)
}
@ -178,7 +178,7 @@ func TestBuildGateway_HasConfigForTenantMode(t *testing.T) {
require.NoError(t, err)
d, ok := objs[1].(*appsv1.Deployment)
d, ok := objs[2].(*appsv1.Deployment)
require.True(t, ok)
require.Len(t, d.Spec.Template.Spec.Containers, 2)
}
@ -210,7 +210,7 @@ func TestBuildGateway_HasExtraObjectsForTenantMode(t *testing.T) {
})
require.NoError(t, err)
require.Len(t, objs, 11)
require.Len(t, objs, 12)
}
func TestBuildGateway_WithExtraObjectsForTenantMode_RouteSvcMatches(t *testing.T) {
@ -243,8 +243,8 @@ func TestBuildGateway_WithExtraObjectsForTenantMode_RouteSvcMatches(t *testing.T
require.NoError(t, err)
svc := objs[4].(*corev1.Service)
rt := objs[5].(*routev1.Route)
svc := objs[5].(*corev1.Service)
rt := objs[6].(*routev1.Route)
require.Equal(t, svc.Kind, rt.Spec.To.Kind)
require.Equal(t, svc.Name, rt.Spec.To.Name)
require.Equal(t, svc.Spec.Ports[0].Name, rt.Spec.Port.TargetPort.StrVal)
@ -280,8 +280,8 @@ func TestBuildGateway_WithExtraObjectsForTenantMode_ServiceAccountNameMatches(t
require.NoError(t, err)
dpl := objs[1].(*appsv1.Deployment)
sa := objs[2].(*corev1.ServiceAccount)
dpl := objs[2].(*appsv1.Deployment)
sa := objs[3].(*corev1.ServiceAccount)
require.Equal(t, dpl.Spec.Template.Spec.ServiceAccountName, sa.Name)
}
@ -450,7 +450,7 @@ func TestBuildGateway_WithTLSProfile(t *testing.T) {
objs, err := BuildGateway(tc.options)
require.NoError(t, err)
d, ok := objs[1].(*appsv1.Deployment)
d, ok := objs[2].(*appsv1.Deployment)
require.True(t, ok)
for _, arg := range tc.expectedArgs {
@ -659,7 +659,7 @@ func TestBuildGateway_WithRulesEnabled(t *testing.T) {
objs, err := BuildGateway(tc.opts)
require.NoError(t, err)
d, ok := objs[1].(*appsv1.Deployment)
d, ok := objs[2].(*appsv1.Deployment)
require.True(t, ok)
for _, arg := range tc.wantArgs {
@ -702,7 +702,7 @@ func TestBuildGateway_WithHTTPEncryption(t *testing.T) {
require.NoError(t, err)
dpl := objs[1].(*appsv1.Deployment)
dpl := objs[2].(*appsv1.Deployment)
require.NotNil(t, dpl)
require.Len(t, dpl.Spec.Template.Spec.Containers, 1)
@ -793,10 +793,8 @@ func TestBuildGateway_WithHTTPEncryption(t *testing.T) {
{
Name: "tenants",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "abcd-gateway",
},
Secret: &corev1.SecretVolumeSource{
SecretName: "abcd-gateway",
},
},
},

@ -193,8 +193,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -459,8 +459,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -533,8 +533,8 @@ func TestBuild_ConfigAndRuntimeConfig_CreateLokiConfigFailed(t *testing.T) {
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -821,8 +821,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -1157,8 +1157,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -1507,8 +1507,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -1898,8 +1898,8 @@ overrides:
Port: 9095,
},
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
StorageDirectory: "/tmp/loki",
MaxConcurrent: MaxConcurrent{
@ -2199,8 +2199,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -2605,8 +2605,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",
@ -2948,8 +2948,8 @@ overrides:
Namespace: "test-ns",
Name: "test",
Compactor: Address{
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
FQDN: "loki-compactor-grpc-lokistack-dev.default.svc.cluster.local",
Port: 9095,
},
FrontendWorker: Address{
FQDN: "loki-query-frontend-grpc-lokistack-dev.default.svc.cluster.local",

Loading…
Cancel
Save