mirror of
https://github.com/sablierapp/sablier.git
synced 2025-12-21 13:23:03 +01:00
@@ -15,16 +15,13 @@ import (
|
|||||||
func StopAllUnregisteredInstances(ctx context.Context, provider providers.Provider, registered []string) error {
|
func StopAllUnregisteredInstances(ctx context.Context, provider providers.Provider, registered []string) error {
|
||||||
log.Info("Stopping all unregistered running instances")
|
log.Info("Stopping all unregistered running instances")
|
||||||
|
|
||||||
log.Tracef("Retrieving all instances with label [%v=true]", LabelEnable)
|
log.Trace("Retrieving all registered instances")
|
||||||
instances, err := provider.InstanceList(ctx, providers.InstanceListOptions{
|
instances, err := provider.List(ctx)
|
||||||
All: false, // Only running containers
|
|
||||||
Labels: []string{LabelEnable},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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))
|
names := make([]string, 0, len(instances))
|
||||||
for _, instance := range instances {
|
for _, instance := range instances {
|
||||||
names = append(names, instance.Name)
|
names = append(names, instance.Name)
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/sablierapp/sablier/app/discovery"
|
"github.com/sablierapp/sablier/app/discovery"
|
||||||
"github.com/sablierapp/sablier/app/providers"
|
|
||||||
"github.com/sablierapp/sablier/app/providers/mock"
|
"github.com/sablierapp/sablier/app/providers/mock"
|
||||||
"github.com/sablierapp/sablier/app/types"
|
"github.com/sablierapp/sablier/app/types"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -22,11 +21,8 @@ func TestStopAllUnregisteredInstances(t *testing.T) {
|
|||||||
}
|
}
|
||||||
registered := []string{"instance1"}
|
registered := []string{"instance1"}
|
||||||
|
|
||||||
// Set up expectations for InstanceList
|
// Set up expectations for List
|
||||||
mockProvider.On("InstanceList", ctx, providers.InstanceListOptions{
|
mockProvider.On("List", ctx).Return(instances, nil)
|
||||||
All: false,
|
|
||||||
Labels: []string{discovery.LabelEnable},
|
|
||||||
}).Return(instances, nil)
|
|
||||||
|
|
||||||
// Set up expectations for Stop
|
// Set up expectations for Stop
|
||||||
mockProvider.On("Stop", ctx, "instance2").Return(nil)
|
mockProvider.On("Stop", ctx, "instance2").Return(nil)
|
||||||
@@ -54,11 +50,8 @@ func TestStopAllUnregisteredInstances_WithError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
registered := []string{"instance1"}
|
registered := []string{"instance1"}
|
||||||
|
|
||||||
// Set up expectations for InstanceList
|
// Set up expectations for List
|
||||||
mockProvider.On("InstanceList", ctx, providers.InstanceListOptions{
|
mockProvider.On("List", ctx).Return(instances, nil)
|
||||||
All: false,
|
|
||||||
Labels: []string{discovery.LabelEnable},
|
|
||||||
}).Return(instances, nil)
|
|
||||||
|
|
||||||
// Set up expectations for Stop with error
|
// Set up expectations for Stop with error
|
||||||
mockProvider.On("Stop", ctx, "instance2").Return(errors.New("stop error"))
|
mockProvider.On("Stop", ctx, "instance2").Return(errors.New("stop error"))
|
||||||
|
|||||||
@@ -7,20 +7,16 @@ import (
|
|||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/sablierapp/sablier/app/discovery"
|
"github.com/sablierapp/sablier/app/discovery"
|
||||||
"github.com/sablierapp/sablier/app/providers"
|
|
||||||
"github.com/sablierapp/sablier/app/types"
|
"github.com/sablierapp/sablier/app/types"
|
||||||
"strings"
|
"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()
|
args := filters.NewArgs()
|
||||||
for _, label := range options.Labels {
|
args.Add("label", fmt.Sprintf("%s=true", discovery.LabelEnable))
|
||||||
args.Add("label", label)
|
|
||||||
args.Add("label", fmt.Sprintf("%s=true", label))
|
|
||||||
}
|
|
||||||
|
|
||||||
containers, err := provider.Client.ContainerList(ctx, container.ListOptions{
|
containers, err := provider.Client.ContainerList(ctx, container.ListOptions{
|
||||||
All: options.All,
|
All: true,
|
||||||
Filters: args,
|
Filters: args,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,14 @@ import (
|
|||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/sablierapp/sablier/app/discovery"
|
"github.com/sablierapp/sablier/app/discovery"
|
||||||
"github.com/sablierapp/sablier/app/providers"
|
|
||||||
"github.com/sablierapp/sablier/app/types"
|
"github.com/sablierapp/sablier/app/types"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"strconv"
|
"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()
|
args := filters.NewArgs()
|
||||||
for _, label := range options.Labels {
|
args.Add("label", fmt.Sprintf("%s=true", discovery.LabelEnable))
|
||||||
args.Add("label", label)
|
|
||||||
args.Add("label", fmt.Sprintf("%s=true", label))
|
|
||||||
}
|
|
||||||
|
|
||||||
services, err := provider.Client.ServiceList(ctx, dockertypes.ServiceListOptions{
|
services, err := provider.Client.ServiceList(ctx, dockertypes.ServiceListOptions{
|
||||||
Filters: args,
|
Filters: args,
|
||||||
|
|||||||
@@ -3,23 +3,31 @@ package kubernetes
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/sablierapp/sablier/app/discovery"
|
"github.com/sablierapp/sablier/app/discovery"
|
||||||
"github.com/sablierapp/sablier/app/providers"
|
|
||||||
"github.com/sablierapp/sablier/app/types"
|
"github.com/sablierapp/sablier/app/types"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
v1 "k8s.io/api/apps/v1"
|
v1 "k8s.io/api/apps/v1"
|
||||||
core_v1 "k8s.io/api/core/v1"
|
core_v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/selection"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (provider *KubernetesProvider) InstanceList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) {
|
const (
|
||||||
deployments, err := provider.deploymentList(ctx, options)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
statefulSets, err := provider.statefulSetList(ctx, options)
|
statefulSets, err := provider.statefulSetList(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -27,9 +35,19 @@ func (provider *KubernetesProvider) InstanceList(ctx context.Context, options pr
|
|||||||
return append(deployments, statefulSets...), nil
|
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{
|
deployments, err := provider.Client.AppsV1().Deployments(core_v1.NamespaceAll).List(ctx, metav1.ListOptions{
|
||||||
LabelSelector: strings.Join(options.Labels, ","),
|
LabelSelector: selector.String(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -49,23 +67,23 @@ func (provider *KubernetesProvider) deploymentToInstance(d v1.Deployment) types.
|
|||||||
var group string
|
var group string
|
||||||
var replicas uint64
|
var replicas uint64
|
||||||
|
|
||||||
if _, ok := d.Labels[discovery.LabelEnable]; ok {
|
if _, ok := d.Labels[LabelEnable]; ok {
|
||||||
if g, ok := d.Labels[discovery.LabelGroup]; ok {
|
if g, ok := d.Labels[LabelGroup]; ok {
|
||||||
group = g
|
group = g
|
||||||
} else {
|
} 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)
|
atoi, err := strconv.Atoi(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Defaulting to default replicas value, could not convert value \"%v\" to int: %v", r, err)
|
log.Warnf("Defaulting to default replicas value, could not convert value \"%v\" to int: %v", r, err)
|
||||||
replicas = discovery.LabelReplicasDefaultValue
|
replicas = LabelReplicasDefaultValue
|
||||||
} else {
|
} else {
|
||||||
replicas = uint64(atoi)
|
replicas = uint64(atoi)
|
||||||
}
|
}
|
||||||
} else {
|
} 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{
|
statefulSets, err := provider.Client.AppsV1().StatefulSets(core_v1.NamespaceAll).List(ctx, metav1.ListOptions{
|
||||||
LabelSelector: strings.Join(options.Labels, ","),
|
LabelSelector: selector.String(),
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -104,23 +132,23 @@ func (provider *KubernetesProvider) statefulSetToInstance(ss v1.StatefulSet) typ
|
|||||||
var group string
|
var group string
|
||||||
var replicas uint64
|
var replicas uint64
|
||||||
|
|
||||||
if _, ok := ss.Labels[discovery.LabelEnable]; ok {
|
if _, ok := ss.Labels[LabelEnable]; ok {
|
||||||
if g, ok := ss.Labels[discovery.LabelGroup]; ok {
|
if g, ok := ss.Labels[LabelGroup]; ok {
|
||||||
group = g
|
group = g
|
||||||
} else {
|
} 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)
|
atoi, err := strconv.Atoi(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Defaulting to default replicas value, could not convert value \"%v\" to int: %v", r, err)
|
log.Warnf("Defaulting to default replicas value, could not convert value \"%v\" to int: %v", r, err)
|
||||||
replicas = discovery.LabelReplicasDefaultValue
|
replicas = LabelReplicasDefaultValue
|
||||||
} else {
|
} else {
|
||||||
replicas = uint64(atoi)
|
replicas = uint64(atoi)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
replicas = discovery.LabelReplicasDefaultValue
|
replicas = LabelReplicasDefaultValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ func (m *ProviderMock) GetGroups(ctx context.Context) (map[string][]string, erro
|
|||||||
args := m.Called(ctx)
|
args := m.Called(ctx)
|
||||||
return args.Get(0).(map[string][]string), args.Error(1)
|
return args.Get(0).(map[string][]string), args.Error(1)
|
||||||
}
|
}
|
||||||
func (m *ProviderMock) InstanceList(ctx context.Context, options providers.InstanceListOptions) ([]types.Instance, error) {
|
func (m *ProviderMock) List(ctx context.Context) ([]types.Instance, error) {
|
||||||
args := m.Called(ctx, options)
|
args := m.Called(ctx)
|
||||||
return args.Get(0).([]types.Instance), args.Error(1)
|
return args.Get(0).([]types.Instance), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ type Provider interface {
|
|||||||
Stop(ctx context.Context, name string) error
|
Stop(ctx context.Context, name string) error
|
||||||
GetState(ctx context.Context, name string) (instance.State, error)
|
GetState(ctx context.Context, name string) (instance.State, error)
|
||||||
GetGroups(ctx context.Context) (map[string][]string, 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)
|
NotifyInstanceStopped(ctx context.Context, instance chan<- string)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package providers
|
package providers
|
||||||
|
|
||||||
type InstanceListOptions struct {
|
type InstanceListOptions struct {
|
||||||
All bool
|
All bool
|
||||||
Labels []string
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,17 +74,17 @@ kind: Deployment
|
|||||||
metadata:
|
metadata:
|
||||||
name: whoami
|
name: whoami
|
||||||
labels:
|
labels:
|
||||||
app: whoami
|
app.kubernetes.io/name: whoami
|
||||||
sablier.enable: "true"
|
sablierapp.dev/enable: "true"
|
||||||
sablier.group: mygroup
|
sablierapp.dev/group: mygroup
|
||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: whoami
|
app.kubernetes.io/name: whoami
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: whoami
|
app.kubernetes.io/name: whoami
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: whoami
|
- name: whoami
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: whoami-deployment
|
name: whoami
|
||||||
labels:
|
labels:
|
||||||
app: whoami
|
app.kubernetes.io/name: whoami
|
||||||
sablier.enable: "true"
|
sablierapp.dev/enable: "true"
|
||||||
sablier.group: "E2E"
|
sablierapp.dev/group: "E2E"
|
||||||
spec:
|
spec:
|
||||||
replicas: 0
|
replicas: 0
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: whoami
|
app.kubernetes.io/name: whoami
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: whoami
|
app.kubernetes.io/name: whoami
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: whoami
|
- name: whoami
|
||||||
@@ -36,7 +36,7 @@ spec:
|
|||||||
targetPort: 80
|
targetPort: 80
|
||||||
port: 80
|
port: 80
|
||||||
selector:
|
selector:
|
||||||
app: whoami
|
app.kubernetes.io/name: whoami
|
||||||
---
|
---
|
||||||
apiVersion: traefik.io/v1alpha1
|
apiVersion: traefik.io/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
@@ -160,18 +160,18 @@ kind: Deployment
|
|||||||
metadata:
|
metadata:
|
||||||
name: nginx-deployment
|
name: nginx-deployment
|
||||||
labels:
|
labels:
|
||||||
app: nginx
|
app.kubernetes.io/name: nginx
|
||||||
sablier.enable: "true"
|
sablierapp.dev/enable: "true"
|
||||||
sablier.group: "E2E"
|
sablierapp.dev/group: "E2E"
|
||||||
spec:
|
spec:
|
||||||
replicas: 0
|
replicas: 0
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: nginx
|
app.kubernetes.io/name: nginx
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: nginx
|
app.kubernetes.io/name: nginx
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
@@ -195,7 +195,7 @@ spec:
|
|||||||
targetPort: 80
|
targetPort: 80
|
||||||
port: 80
|
port: 80
|
||||||
selector:
|
selector:
|
||||||
app: nginx
|
app.kubernetes.io/name: nginx
|
||||||
---
|
---
|
||||||
apiVersion: traefik.io/v1alpha1
|
apiVersion: traefik.io/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
|
|||||||
Reference in New Issue
Block a user