diff --git a/app/discovery/autostop.go b/app/discovery/autostop.go index 01d0a11a..41221688 100644 --- a/app/discovery/autostop.go +++ b/app/discovery/autostop.go @@ -15,16 +15,13 @@ import ( func StopAllUnregisteredInstances(ctx context.Context, provider providers.Provider, registered []string) error { log.Info("Stopping all unregistered running instances") - log.Tracef("Retrieving all instances with label [%v=true]", LabelEnable) - instances, err := provider.InstanceList(ctx, providers.InstanceListOptions{ - All: false, // Only running containers - Labels: []string{LabelEnable}, - }) + log.Trace("Retrieving all registered instances") + instances, err := provider.List(ctx) if err != nil { return err } - log.Tracef("Found %v instances with label [%v=true]", len(instances), LabelEnable) + log.Tracef("Found %v instances", len(instances)) names := make([]string, 0, len(instances)) for _, instance := range instances { names = append(names, instance.Name) diff --git a/app/discovery/autostop_test.go b/app/discovery/autostop_test.go index ca2f1a2d..3be48ff2 100644 --- a/app/discovery/autostop_test.go +++ b/app/discovery/autostop_test.go @@ -4,7 +4,6 @@ import ( "context" "errors" "github.com/sablierapp/sablier/app/discovery" - "github.com/sablierapp/sablier/app/providers" "github.com/sablierapp/sablier/app/providers/mock" "github.com/sablierapp/sablier/app/types" "testing" @@ -22,11 +21,8 @@ func TestStopAllUnregisteredInstances(t *testing.T) { } registered := []string{"instance1"} - // Set up expectations for InstanceList - mockProvider.On("InstanceList", ctx, providers.InstanceListOptions{ - All: false, - Labels: []string{discovery.LabelEnable}, - }).Return(instances, nil) + // Set up expectations for List + mockProvider.On("List", ctx).Return(instances, nil) // Set up expectations for Stop mockProvider.On("Stop", ctx, "instance2").Return(nil) @@ -54,11 +50,8 @@ func TestStopAllUnregisteredInstances_WithError(t *testing.T) { } registered := []string{"instance1"} - // Set up expectations for InstanceList - mockProvider.On("InstanceList", ctx, providers.InstanceListOptions{ - All: false, - Labels: []string{discovery.LabelEnable}, - }).Return(instances, nil) + // Set up expectations for List + mockProvider.On("List", ctx).Return(instances, nil) // Set up expectations for Stop with error mockProvider.On("Stop", ctx, "instance2").Return(errors.New("stop error")) diff --git a/app/providers/docker/list.go b/app/providers/docker/list.go index 5523f9be..3d058aaa 100644 --- a/app/providers/docker/list.go +++ b/app/providers/docker/list.go @@ -7,20 +7,16 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/sablierapp/sablier/app/discovery" - "github.com/sablierapp/sablier/app/providers" "github.com/sablierapp/sablier/app/types" "strings" ) -func (provider *DockerClassicProvider) InstanceList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) { +func (provider *DockerClassicProvider) List(ctx context.Context) ([]types.Instance, error) { args := filters.NewArgs() - for _, label := range options.Labels { - args.Add("label", label) - args.Add("label", fmt.Sprintf("%s=true", label)) - } + args.Add("label", fmt.Sprintf("%s=true", discovery.LabelEnable)) containers, err := provider.Client.ContainerList(ctx, container.ListOptions{ - All: options.All, + All: true, Filters: args, }) diff --git a/app/providers/dockerswarm/list.go b/app/providers/dockerswarm/list.go index dad6f47e..db3d5c78 100644 --- a/app/providers/dockerswarm/list.go +++ b/app/providers/dockerswarm/list.go @@ -7,18 +7,14 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/sablierapp/sablier/app/discovery" - "github.com/sablierapp/sablier/app/providers" "github.com/sablierapp/sablier/app/types" log "github.com/sirupsen/logrus" "strconv" ) -func (provider *DockerSwarmProvider) InstanceList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) { +func (provider *DockerSwarmProvider) List(ctx context.Context) ([]types.Instance, error) { args := filters.NewArgs() - for _, label := range options.Labels { - args.Add("label", label) - args.Add("label", fmt.Sprintf("%s=true", label)) - } + args.Add("label", fmt.Sprintf("%s=true", discovery.LabelEnable)) services, err := provider.Client.ServiceList(ctx, dockertypes.ServiceListOptions{ Filters: args, diff --git a/app/providers/kubernetes/list.go b/app/providers/kubernetes/list.go index 6fda3647..4a6b0304 100644 --- a/app/providers/kubernetes/list.go +++ b/app/providers/kubernetes/list.go @@ -3,23 +3,31 @@ package kubernetes import ( "context" "github.com/sablierapp/sablier/app/discovery" - "github.com/sablierapp/sablier/app/providers" "github.com/sablierapp/sablier/app/types" log "github.com/sirupsen/logrus" v1 "k8s.io/api/apps/v1" core_v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" "strconv" - "strings" ) -func (provider *KubernetesProvider) InstanceList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) { - deployments, err := provider.deploymentList(ctx, options) +const ( + LabelEnable = "sablierapp.dev/enable" + LabelGroup = "sablierapp.dev/group" + LabelGroupDefaultValue = "default" + LabelReplicas = "sablierapp.dev/replicas" + LabelReplicasDefaultValue uint64 = 1 +) + +func (provider *KubernetesProvider) List(ctx context.Context) ([]types.Instance, error) { + deployments, err := provider.deploymentList(ctx) if err != nil { return nil, err } - statefulSets, err := provider.statefulSetList(ctx, options) + statefulSets, err := provider.statefulSetList(ctx) if err != nil { return nil, err } @@ -27,9 +35,19 @@ func (provider *KubernetesProvider) InstanceList(ctx context.Context, options pr return append(deployments, statefulSets...), nil } -func (provider *KubernetesProvider) deploymentList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) { +func (provider *KubernetesProvider) deploymentList(ctx context.Context) ([]types.Instance, error) { + requirement, err := labels.NewRequirement(LabelEnable, selection.Equals, []string{"true"}) + if err != nil { + return nil, err + } + requirementDeprecated, err := labels.NewRequirement(discovery.LabelEnable, selection.Equals, []string{"true"}) + if err != nil { + return nil, err + } + selector := labels.NewSelector() + selector = selector.Add(*requirement, *requirementDeprecated) deployments, err := provider.Client.AppsV1().Deployments(core_v1.NamespaceAll).List(ctx, metav1.ListOptions{ - LabelSelector: strings.Join(options.Labels, ","), + LabelSelector: selector.String(), }) if err != nil { @@ -49,23 +67,23 @@ func (provider *KubernetesProvider) deploymentToInstance(d v1.Deployment) types. var group string var replicas uint64 - if _, ok := d.Labels[discovery.LabelEnable]; ok { - if g, ok := d.Labels[discovery.LabelGroup]; ok { + if _, ok := d.Labels[LabelEnable]; ok { + if g, ok := d.Labels[LabelGroup]; ok { group = g } else { - group = discovery.LabelGroupDefaultValue + group = LabelGroupDefaultValue } - if r, ok := d.Labels[discovery.LabelReplicas]; ok { + if r, ok := d.Labels[LabelReplicas]; ok { atoi, err := strconv.Atoi(r) if err != nil { log.Warnf("Defaulting to default replicas value, could not convert value \"%v\" to int: %v", r, err) - replicas = discovery.LabelReplicasDefaultValue + replicas = LabelReplicasDefaultValue } else { replicas = uint64(atoi) } } else { - replicas = discovery.LabelReplicasDefaultValue + replicas = LabelReplicasDefaultValue } } @@ -82,9 +100,19 @@ func (provider *KubernetesProvider) deploymentToInstance(d v1.Deployment) types. } } -func (provider *KubernetesProvider) statefulSetList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) { +func (provider *KubernetesProvider) statefulSetList(ctx context.Context) ([]types.Instance, error) { + requirement, err := labels.NewRequirement(LabelEnable, selection.Equals, []string{"true"}) + if err != nil { + return nil, err + } + requirementDeprecated, err := labels.NewRequirement(discovery.LabelEnable, selection.Equals, []string{"true"}) + if err != nil { + return nil, err + } + selector := labels.NewSelector() + selector = selector.Add(*requirement, *requirementDeprecated) statefulSets, err := provider.Client.AppsV1().StatefulSets(core_v1.NamespaceAll).List(ctx, metav1.ListOptions{ - LabelSelector: strings.Join(options.Labels, ","), + LabelSelector: selector.String(), }) if err != nil { @@ -104,23 +132,23 @@ func (provider *KubernetesProvider) statefulSetToInstance(ss v1.StatefulSet) typ var group string var replicas uint64 - if _, ok := ss.Labels[discovery.LabelEnable]; ok { - if g, ok := ss.Labels[discovery.LabelGroup]; ok { + if _, ok := ss.Labels[LabelEnable]; ok { + if g, ok := ss.Labels[LabelGroup]; ok { group = g } else { - group = discovery.LabelGroupDefaultValue + group = LabelGroupDefaultValue } - if r, ok := ss.Labels[discovery.LabelReplicas]; ok { + if r, ok := ss.Labels[LabelReplicas]; ok { atoi, err := strconv.Atoi(r) if err != nil { log.Warnf("Defaulting to default replicas value, could not convert value \"%v\" to int: %v", r, err) - replicas = discovery.LabelReplicasDefaultValue + replicas = LabelReplicasDefaultValue } else { replicas = uint64(atoi) } } else { - replicas = discovery.LabelReplicasDefaultValue + replicas = LabelReplicasDefaultValue } } diff --git a/app/providers/mock/mock.go b/app/providers/mock/mock.go index f177658b..9cb7d6db 100644 --- a/app/providers/mock/mock.go +++ b/app/providers/mock/mock.go @@ -32,8 +32,8 @@ func (m *ProviderMock) GetGroups(ctx context.Context) (map[string][]string, erro args := m.Called(ctx) return args.Get(0).(map[string][]string), args.Error(1) } -func (m *ProviderMock) InstanceList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) { - args := m.Called(ctx, options) +func (m *ProviderMock) List(ctx context.Context) ([]types.Instance, error) { + args := m.Called(ctx) return args.Get(0).([]types.Instance), args.Error(1) } diff --git a/app/providers/provider.go b/app/providers/provider.go index 5768cad5..88df14f6 100644 --- a/app/providers/provider.go +++ b/app/providers/provider.go @@ -12,7 +12,7 @@ type Provider interface { Stop(ctx context.Context, name string) error GetState(ctx context.Context, name string) (instance.State, error) GetGroups(ctx context.Context) (map[string][]string, error) - InstanceList(ctx context.Context, options InstanceListOptions) ([]types.Instance, error) + List(ctx context.Context) ([]types.Instance, error) NotifyInstanceStopped(ctx context.Context, instance chan<- string) } diff --git a/app/providers/types.go b/app/providers/types.go index 975faa46..2274d635 100644 --- a/app/providers/types.go +++ b/app/providers/types.go @@ -1,6 +1,5 @@ package providers type InstanceListOptions struct { - All bool - Labels []string + All bool } diff --git a/docs/providers/kubernetes.md b/docs/providers/kubernetes.md index 86a366f5..c2897d2e 100644 --- a/docs/providers/kubernetes.md +++ b/docs/providers/kubernetes.md @@ -74,17 +74,17 @@ kind: Deployment metadata: name: whoami labels: - app: whoami - sablier.enable: "true" - sablier.group: mygroup + app.kubernetes.io/name: whoami + sablierapp.dev/enable: "true" + sablierapp.dev/group: mygroup spec: selector: matchLabels: - app: whoami + app.kubernetes.io/name: whoami template: metadata: labels: - app: whoami + app.kubernetes.io/name: whoami spec: containers: - name: whoami diff --git a/plugins/traefik/e2e/kubernetes/manifests/deployment.yml b/plugins/traefik/e2e/kubernetes/manifests/deployment.yml index 00cfc692..e5357622 100644 --- a/plugins/traefik/e2e/kubernetes/manifests/deployment.yml +++ b/plugins/traefik/e2e/kubernetes/manifests/deployment.yml @@ -1,20 +1,20 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: whoami-deployment + name: whoami labels: - app: whoami - sablier.enable: "true" - sablier.group: "E2E" + app.kubernetes.io/name: whoami + sablierapp.dev/enable: "true" + sablierapp.dev/group: "E2E" spec: replicas: 0 selector: matchLabels: - app: whoami + app.kubernetes.io/name: whoami template: metadata: labels: - app: whoami + app.kubernetes.io/name: whoami spec: containers: - name: whoami @@ -36,7 +36,7 @@ spec: targetPort: 80 port: 80 selector: - app: whoami + app.kubernetes.io/name: whoami --- apiVersion: traefik.io/v1alpha1 kind: Middleware @@ -160,18 +160,18 @@ kind: Deployment metadata: name: nginx-deployment labels: - app: nginx - sablier.enable: "true" - sablier.group: "E2E" + app.kubernetes.io/name: nginx + sablierapp.dev/enable: "true" + sablierapp.dev/group: "E2E" spec: replicas: 0 selector: matchLabels: - app: nginx + app.kubernetes.io/name: nginx template: metadata: labels: - app: nginx + app.kubernetes.io/name: nginx spec: containers: - name: nginx @@ -195,7 +195,7 @@ spec: targetPort: 80 port: 80 selector: - app: nginx + app.kubernetes.io/name: nginx --- apiVersion: traefik.io/v1alpha1 kind: Middleware