operator: Add a PodDisruptionBudget to lokistack-gateway (#9162)

pull/9182/head
Mohamed-Amine Bouqsimi 3 years ago committed by GitHub
parent 4c4f3adbf1
commit 3d017a4b25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      operator/CHANGELOG.md
  2. 12
      operator/bundle/community-openshift/manifests/loki-operator.clusterserviceversion.yaml
  3. 12
      operator/bundle/community/manifests/loki-operator.clusterserviceversion.yaml
  4. 12
      operator/bundle/openshift/manifests/loki-operator.clusterserviceversion.yaml
  5. 10
      operator/config/rbac/role.yaml
  6. 1
      operator/controllers/loki/lokistack_controller.go
  7. 28
      operator/internal/manifests/gateway.go
  8. 36
      operator/internal/manifests/gateway_test.go
  9. 11
      operator/internal/manifests/mutate.go
  10. 38
      operator/internal/manifests/mutate_test.go

@ -1,4 +1,5 @@
## Main
- [9162](https://github.com/grafana/loki/pull/9162) **aminesnow**: Add a PodDisruptionBudget to lokistack-gateway
- [9049](https://github.com/grafana/loki/pull/9049) **alanconway**: Revert 1x.extra-small changes, add 1x.demo
- [8661](https://github.com/grafana/loki/pull/8661) **xuanyunhui**: Add a new Object Storage Type for AlibabaCloud OSS
- [9036](https://github.com/grafana/loki/pull/9036) **periklis**: Update Loki operand to v2.8.0

@ -150,7 +150,7 @@ metadata:
categories: OpenShift Optional, Logging & Tracing
certified: "false"
containerImage: docker.io/grafana/loki-operator:main-99acb9b
createdAt: "2023-04-06T11:19:03Z"
createdAt: "2023-04-18T07:59:30Z"
description: The Community Loki Operator provides Kubernetes native deployment
and management of Loki and related logging components.
operators.operatorframework.io/builder: operator-sdk-unknown
@ -1424,6 +1424,16 @@ spec:
- list
- update
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:

@ -150,7 +150,7 @@ metadata:
categories: OpenShift Optional, Logging & Tracing
certified: "false"
containerImage: docker.io/grafana/loki-operator:main-99acb9b
createdAt: "2023-04-06T11:19:01Z"
createdAt: "2023-04-18T07:59:27Z"
description: The Community Loki Operator provides Kubernetes native deployment
and management of Loki and related logging components.
operators.operatorframework.io/builder: operator-sdk-unknown
@ -1410,6 +1410,16 @@ spec:
- list
- update
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:

@ -150,7 +150,7 @@ metadata:
categories: OpenShift Optional, Logging & Tracing
certified: "false"
containerImage: quay.io/openshift-logging/loki-operator:v0.1.0
createdAt: "2023-04-06T11:19:04Z"
createdAt: "2023-04-18T07:59:33Z"
description: |
The Loki Operator for OCP provides a means for configuring and managing a Loki stack for cluster logging.
## Prerequisites and Requirements
@ -1408,6 +1408,16 @@ spec:
- list
- update
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:

@ -206,6 +206,16 @@ rules:
- list
- update
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:

@ -129,6 +129,7 @@ type LokiStackReconciler struct {
// +kubebuilder:rbac:urls=/api/v2/alerts,verbs=create
// +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;create;update
// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list;watch;create;update
// +kubebuilder:rbac:groups=policy,resources=poddisruptionbudgets,verbs=get;list;watch;create;update
// +kubebuilder:rbac:groups=config.openshift.io,resources=dnses;apiservers;proxies,verbs=get;list;watch
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;delete

@ -16,6 +16,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
policyv1 "k8s.io/api/policy/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/pointer"
@ -39,13 +40,14 @@ func BuildGateway(opts Options) ([]client.Object, error) {
sa := NewServiceAccount(opts)
saToken := NewServiceAccountTokenSecret(opts)
svc := NewGatewayHTTPService(opts)
pdb := NewGatewayPodDisruptionBudget(opts)
ing, err := NewGatewayIngress(opts)
if err != nil {
return nil, err
}
objs := []client.Object{cm, tenantSecret, dpl, sa, saToken, svc, ing}
objs := []client.Object{cm, tenantSecret, dpl, sa, saToken, svc, ing, pdb}
minTLSVersion := opts.TLSProfile.MinTLSVersion
ciphersList := opts.TLSProfile.Ciphers
@ -352,6 +354,30 @@ func NewServiceAccountTokenSecret(opts Options) client.Object {
}
}
// NewGatewayPodDisruptionBudget returns a PodDisruptionBudget for the LokiStack
// Gateway pods.
func NewGatewayPodDisruptionBudget(opts Options) *policyv1.PodDisruptionBudget {
l := ComponentLabels(LabelGatewayComponent, opts.Name)
mu := intstr.FromInt(1)
return &policyv1.PodDisruptionBudget{
TypeMeta: metav1.TypeMeta{
Kind: "PodDisruptionBudget",
APIVersion: policyv1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Labels: l,
Name: GatewayName(opts.Name),
Namespace: opts.Namespace,
},
Spec: policyv1.PodDisruptionBudgetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: l,
},
MinAvailable: &mu,
},
}
}
// 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)

@ -17,6 +17,7 @@ import (
routev1 "github.com/openshift/api/route/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
)
func TestNewGatewayDeployment_HasTemplateConfigHashAnnotation(t *testing.T) {
@ -255,7 +256,7 @@ func TestBuildGateway_HasExtraObjectsForTenantMode(t *testing.T) {
})
require.NoError(t, err)
require.Len(t, objs, 12)
require.Len(t, objs, 13)
}
func TestBuildGateway_WithExtraObjectsForTenantMode_RouteSvcMatches(t *testing.T) {
@ -289,7 +290,7 @@ func TestBuildGateway_WithExtraObjectsForTenantMode_RouteSvcMatches(t *testing.T
require.NoError(t, err)
svc := objs[5].(*corev1.Service)
rt := objs[6].(*routev1.Route)
rt := objs[7].(*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)
@ -894,3 +895,34 @@ func TestBuildGateway_WithHTTPEncryption(t *testing.T) {
}
require.Equal(t, expectedVolumes, dpl.Spec.Template.Spec.Volumes)
}
func TestBuildGateway_PodDisruptionBudget(t *testing.T) {
opts := Options{
Name: "abcd",
Namespace: "efgh",
Gates: configv1.FeatureGates{
LokiStackGateway: true,
},
Stack: lokiv1.LokiStackSpec{
Template: &lokiv1.LokiTemplateSpec{
Gateway: &lokiv1.LokiComponentSpec{
Replicas: rand.Int31(),
},
},
Tenants: &lokiv1.TenantsSpec{
Mode: lokiv1.OpenshiftLogging,
},
},
}
objs, err := BuildGateway(opts)
require.NoError(t, err)
require.Len(t, objs, 13)
pdb := objs[6].(*policyv1.PodDisruptionBudget)
require.NotNil(t, pdb)
require.Equal(t, "abcd-gateway", pdb.Name)
require.Equal(t, "efgh", pdb.Namespace)
require.NotNil(t, pdb.Spec.MinAvailable.IntVal)
require.Equal(t, int32(1), pdb.Spec.MinAvailable.IntVal)
require.EqualValues(t, ComponentLabels(LabelGatewayComponent, opts.Name), pdb.Spec.Selector.MatchLabels)
}

@ -10,6 +10,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
policyv1 "k8s.io/api/policy/v1"
rbacv1 "k8s.io/api/rbac/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@ -116,6 +117,10 @@ func MutateFuncFor(existing, desired client.Object, depAnnotations map[string]st
pr := existing.(*monitoringv1.PrometheusRule)
wantPr := desired.(*monitoringv1.PrometheusRule)
mutatePrometheusRule(pr, wantPr)
case *policyv1.PodDisruptionBudget:
pdb := existing.(*policyv1.PodDisruptionBudget)
wantPdb := desired.(*policyv1.PodDisruptionBudget)
mutatePodDisruptionBudget(pdb, wantPdb)
default:
t := reflect.TypeOf(existing).String()
@ -240,3 +245,9 @@ func mutateStatefulSet(existing, desired *appsv1.StatefulSet) error {
}
return nil
}
func mutatePodDisruptionBudget(existing, desired *policyv1.PodDisruptionBudget) {
existing.Annotations = desired.Annotations
existing.Labels = desired.Labels
existing.Spec = desired.Spec
}

@ -11,6 +11,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
policyv1 "k8s.io/api/policy/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
@ -1065,3 +1066,40 @@ func TestGetMutateFunc_MutateRoute(t *testing.T) {
require.Exactly(t, got.Annotations, want.Annotations)
require.Exactly(t, got.Spec, want.Spec)
}
func TestGetMutateFunc_MutatePodDisruptionBudget(t *testing.T) {
mu := intstr.FromInt(1)
got := &policyv1.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"test": "test",
"other": "label",
},
},
}
want := &policyv1.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"other": "label",
"new": "label",
},
},
Spec: policyv1.PodDisruptionBudgetSpec{
MinAvailable: &mu,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"label": "test",
"and": "another",
},
},
},
}
f := manifests.MutateFuncFor(got, want, nil)
err := f()
require.NoError(t, err)
require.Exactly(t, got.Labels, want.Labels)
require.Exactly(t, got.Spec, want.Spec)
}

Loading…
Cancel
Save