|
@@ -0,0 +1,153 @@
|
|
|
+package stack
|
|
|
+
|
|
|
+import (
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ "github.com/docker/docker/api/types"
|
|
|
+ "github.com/docker/docker/api/types/filters"
|
|
|
+ "github.com/docker/docker/api/types/swarm"
|
|
|
+ "github.com/docker/docker/cli/compose/convert"
|
|
|
+ "github.com/docker/docker/client"
|
|
|
+ "golang.org/x/net/context"
|
|
|
+)
|
|
|
+
|
|
|
+type fakeClient struct {
|
|
|
+ client.Client
|
|
|
+
|
|
|
+ services []string
|
|
|
+ networks []string
|
|
|
+ secrets []string
|
|
|
+
|
|
|
+ removedServices []string
|
|
|
+ removedNetworks []string
|
|
|
+ removedSecrets []string
|
|
|
+
|
|
|
+ serviceListFunc func(options types.ServiceListOptions) ([]swarm.Service, error)
|
|
|
+ networkListFunc func(options types.NetworkListOptions) ([]types.NetworkResource, error)
|
|
|
+ secretListFunc func(options types.SecretListOptions) ([]swarm.Secret, error)
|
|
|
+ serviceRemoveFunc func(serviceID string) error
|
|
|
+ networkRemoveFunc func(networkID string) error
|
|
|
+ secretRemoveFunc func(secretID string) error
|
|
|
+}
|
|
|
+
|
|
|
+func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
|
|
+ if cli.serviceListFunc != nil {
|
|
|
+ return cli.serviceListFunc(options)
|
|
|
+ }
|
|
|
+
|
|
|
+ namespace := namespaceFromFilters(options.Filters)
|
|
|
+ servicesList := []swarm.Service{}
|
|
|
+ for _, name := range cli.services {
|
|
|
+ if belongToNamespace(name, namespace) {
|
|
|
+ servicesList = append(servicesList, serviceFromName(name))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return servicesList, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (cli *fakeClient) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
|
|
|
+ if cli.networkListFunc != nil {
|
|
|
+ return cli.networkListFunc(options)
|
|
|
+ }
|
|
|
+
|
|
|
+ namespace := namespaceFromFilters(options.Filters)
|
|
|
+ networksList := []types.NetworkResource{}
|
|
|
+ for _, name := range cli.networks {
|
|
|
+ if belongToNamespace(name, namespace) {
|
|
|
+ networksList = append(networksList, networkFromName(name))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return networksList, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (cli *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
|
|
+ if cli.secretListFunc != nil {
|
|
|
+ return cli.secretListFunc(options)
|
|
|
+ }
|
|
|
+
|
|
|
+ namespace := namespaceFromFilters(options.Filters)
|
|
|
+ secretsList := []swarm.Secret{}
|
|
|
+ for _, name := range cli.secrets {
|
|
|
+ if belongToNamespace(name, namespace) {
|
|
|
+ secretsList = append(secretsList, secretFromName(name))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return secretsList, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (cli *fakeClient) ServiceRemove(ctx context.Context, serviceID string) error {
|
|
|
+ if cli.serviceRemoveFunc != nil {
|
|
|
+ return cli.serviceRemoveFunc(serviceID)
|
|
|
+ }
|
|
|
+
|
|
|
+ cli.removedServices = append(cli.removedServices, serviceID)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (cli *fakeClient) NetworkRemove(ctx context.Context, networkID string) error {
|
|
|
+ if cli.networkRemoveFunc != nil {
|
|
|
+ return cli.networkRemoveFunc(networkID)
|
|
|
+ }
|
|
|
+
|
|
|
+ cli.removedNetworks = append(cli.removedNetworks, networkID)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (cli *fakeClient) SecretRemove(ctx context.Context, secretID string) error {
|
|
|
+ if cli.secretRemoveFunc != nil {
|
|
|
+ return cli.secretRemoveFunc(secretID)
|
|
|
+ }
|
|
|
+
|
|
|
+ cli.removedSecrets = append(cli.removedSecrets, secretID)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func serviceFromName(name string) swarm.Service {
|
|
|
+ return swarm.Service{
|
|
|
+ ID: "ID-" + name,
|
|
|
+ Spec: swarm.ServiceSpec{
|
|
|
+ Annotations: swarm.Annotations{Name: name},
|
|
|
+ },
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func networkFromName(name string) types.NetworkResource {
|
|
|
+ return types.NetworkResource{
|
|
|
+ ID: "ID-" + name,
|
|
|
+ Name: name,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func secretFromName(name string) swarm.Secret {
|
|
|
+ return swarm.Secret{
|
|
|
+ ID: "ID-" + name,
|
|
|
+ Spec: swarm.SecretSpec{
|
|
|
+ Annotations: swarm.Annotations{Name: name},
|
|
|
+ },
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func namespaceFromFilters(filters filters.Args) string {
|
|
|
+ label := filters.Get("label")[0]
|
|
|
+ return strings.TrimPrefix(label, convert.LabelNamespace+"=")
|
|
|
+}
|
|
|
+
|
|
|
+func belongToNamespace(id, namespace string) bool {
|
|
|
+ return strings.HasPrefix(id, namespace+"_")
|
|
|
+}
|
|
|
+
|
|
|
+func objectName(namespace, name string) string {
|
|
|
+ return namespace + "_" + name
|
|
|
+}
|
|
|
+
|
|
|
+func objectID(name string) string {
|
|
|
+ return "ID-" + name
|
|
|
+}
|
|
|
+
|
|
|
+func buildObjectIDs(objectNames []string) []string {
|
|
|
+ IDs := make([]string, len(objectNames))
|
|
|
+ for i, name := range objectNames {
|
|
|
+ IDs[i] = objectID(name)
|
|
|
+ }
|
|
|
+ return IDs
|
|
|
+}
|