0
0
Fork 0
mirror of https://github.com/crazy-max/diun.git synced 2025-04-10 22:00:13 +00:00

Remove support of multi Docker and Swarm providers

This commit is contained in:
CrazyMax 2020-05-25 23:20:30 +02:00
parent 6da156cd07
commit a6a231ac06
No known key found for this signature in database
GPG key ID: 3248E46B6BB8C7F7
14 changed files with 204 additions and 208 deletions

View file

@ -10,8 +10,6 @@
## Overview
Here is a YAML structure example:
```yml
db:
path: diun.db
@ -83,21 +81,10 @@ regopts:
providers:
docker:
# Watch only labeled containers on local Docker engine
local:
watch_stopped: true
# Watch all containers on 10.0.0.1:2375
remote:
endpoint: tcp://10.0.0.1:2375
watch_by_default: true
watch_stopped: true
swarm:
# Watch all services on local Swarm cluster
myswarm:
watch_by_default: true
watch_by_default: true
file:
# Watch images from filename ./myimages.yml
filename: ./myimages.yml
# Watch images from directory ./imagesdir
directory: ./imagesdir
```

View file

@ -7,7 +7,7 @@
## About
The Docker provider allows you to analyze the containers of your standalone Docker instance to extract the images found and check for updates on the registry.
The Docker provider allows you to analyze the containers of your Docker instance to extract images found and check for updates on the registry.
## Quick start
@ -22,8 +22,7 @@ watch:
providers:
docker:
mydocker:
watch_stopped: true
watch_stopped: true
```
Here we use a single Docker provider with a minimum configuration to analyze labeled containers (watch by default disabled), even stopped ones, of your local Docker instance.
@ -64,7 +63,7 @@ services:
restart: always
```
As an example we use [crazymax/cloudflared:latest](https://github.com/crazy-max/docker-cloudflared) Docker image. A few [labels](#configuration) are added to configure the image analysis of this container for Diun. Now start this composition with `docker-composes up -d` and take a look at the logs:
As an example we use [crazymax/cloudflared:latest](https://github.com/crazy-max/docker-cloudflared) Docker image. A few [labels](#docker-labels) are added to configure the image analysis of this container for Diun. Now start this composition with `docker-composes up -d` and take a look at the logs:
```
$ docker-compose logs -f
@ -74,7 +73,7 @@ cloudflared | time="2019-12-14T15:30:07+01:00" level=info msg="Adding DNS ups
cloudflared | time="2019-12-14T15:30:07+01:00" level=info msg="Starting metrics server" addr="[::]:49312"
cloudflared | time="2019-12-14T15:30:07+01:00" level=info msg="Starting DNS over HTTPS proxy server" addr="dns://0.0.0.0:5053"
diun_1 | Sat, 14 Dec 2019 15:30:07 CET INF Starting Diun v2.0.0
diun_1 | Sat, 14 Dec 2019 15:30:07 CET INF Found 1 docker provider(s) to analyze...
diun_1 | Sat, 14 Dec 2019 15:30:07 CET INF Found 1 image(s) to analyze provider=docker
diun_1 | Sat, 14 Dec 2019 15:30:10 CET INF New image found id=mydocker image=docker.io/crazymax/cloudflared:latest provider=docker
diun_1 | Sat, 14 Dec 2019 15:30:12 CET INF New image found id=mydocker image=docker.io/crazymax/cloudflared:2019.9.0 provider=docker
diun_1 | Sat, 14 Dec 2019 15:30:12 CET INF New image found id=mydocker image=docker.io/crazymax/cloudflared:2019.9.1 provider=docker
@ -91,8 +90,6 @@ diun_1 | Sat, 14 Dec 2019 15:30:13 CET INF Next run in 29 minutes (2019-
## Provider configuration
The Docker provider configuration is map of Docker standalone engines to watch with the following options available:
* `endpoint`: Server address to connect to. Local if empty.
* `api_version`: Overrides the client version with the specified one.
* `tls_certs_path`: Path to load the TLS certificates from.

View file

@ -7,7 +7,7 @@
## About
The Swarm provider is closely linked to the [Docker provider](docker.md) except that it allows you to analyze the services of your Swarm cluster to extract the images found and check for updates on the registry.
The Swarm provider allows you to analyze the services of your Swarm cluster to extract images found and check for updates on the registry.
## Quick start
@ -22,10 +22,9 @@ watch:
providers:
swarm:
myswarm:
```
Here we use a single Swarm provider with a minimum configuration to analyze labeled containers (watch by default disabled), of your local Swarm cluster.
Here we use our local Swarm provider with a minimum configuration to analyze labeled containers (watch by default disabled).
Now let's create a simple stack for Diun:
@ -69,7 +68,7 @@ services:
- "diun.watch_repo=true"
```
As an example we use [nginx](https://hub.docker.com/_/nginx/) Docker image. A few [labels](#configuration) are added to configure the image analysis of this service for Diun. We can now start these 2 stacks:
As an example we use [nginx](https://hub.docker.com/_/nginx/) Docker image. A few [labels](#docker-labels) are added to configure the image analysis of this service for Diun. We can now start these 2 stacks:
```
docker stack deploy -c diun.yml diun
@ -82,7 +81,7 @@ And watch logs of Diun service:
$ docker service logs -f diun_diun
diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:19:57 CET INF Starting Diun dev
diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:19:57 CET INF Starting Diun...
diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:19:57 CET INF Found 1 swarm provider(s) to analyze...
diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:19:57 CET INF Found 1 image(s) to analyze provider=swarm
diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:19:59 CET INF New image found id=myswarm image=docker.io/library/nginx:latest provider=swarm
diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:20:01 CET INF New image found id=myswarm image=docker.io/library/nginx:1.9 provider=swarm
diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:20:01 CET INF New image found id=myswarm image=docker.io/library/nginx:1.9.4 provider=swarm
@ -106,8 +105,6 @@ diun_diun.1.i1l4yuiafq6y@docker-desktop | Sat, 14 Dec 2019 16:20:02 CET INF N
## Provider configuration
The Swarm provider configuration is a map of Docker Swarm clusters to watch with the following options available:
* `endpoint`: Server address to connect to. Local if empty.
* `api_version`: Overrides the client version with the specified one.
* `tls_certs_path`: Path to load the TLS certificates from.

View file

@ -23,7 +23,7 @@ type Config struct {
Watch model.Watch `yaml:"watch,omitempty"`
Notif model.Notif `yaml:"notif,omitempty"`
RegOpts map[string]model.RegOpts `yaml:"regopts,omitempty"`
Providers model.Providers `yaml:"providers,omitempty"`
Providers *model.Providers `yaml:"providers,omitempty"`
}
// Load returns Configuration struct
@ -116,16 +116,12 @@ func (cfg *Config) validate() error {
}
}
for id, prdDocker := range cfg.Providers.Docker {
if err := cfg.validateDockerProvider(id, prdDocker); err != nil {
return err
}
if err := cfg.validateDockerProvider(); err != nil {
return err
}
for id, prdSwarm := range cfg.Providers.Swarm {
if err := cfg.validateSwarmProvider(id, prdSwarm); err != nil {
return err
}
if err := cfg.validateSwarmProvider(); err != nil {
return err
}
if err := cfg.validateFileProvider(); err != nil {
@ -161,32 +157,42 @@ func (cfg *Config) validateRegOpts(id string, regopts model.RegOpts) error {
return nil
}
func (cfg *Config) validateDockerProvider(id string, prdDocker model.PrdDocker) error {
if err := mergo.Merge(&prdDocker, model.PrdDocker{
TLSVerify: true,
WatchByDefault: false,
WatchStopped: false,
}); err != nil {
return fmt.Errorf("cannot set default values for docker %s provider: %v", id, err)
func (cfg *Config) validateDockerProvider() error {
if cfg.Providers.Docker == nil {
return nil
}
if err := mergo.Merge(cfg.Providers.Docker, model.PrdDocker{
TLSVerify: utl.NewTrue(),
WatchByDefault: utl.NewFalse(),
WatchStopped: utl.NewFalse(),
}); err != nil {
return errors.Wrap(err, "cannot set default values for docker provider")
}
cfg.Providers.Docker[id] = prdDocker
return nil
}
func (cfg *Config) validateSwarmProvider(id string, prdSwarm model.PrdSwarm) error {
if err := mergo.Merge(&prdSwarm, model.PrdSwarm{
TLSVerify: true,
WatchByDefault: false,
}); err != nil {
return fmt.Errorf("cannot set default values for swarm %s provider: %v", id, err)
func (cfg *Config) validateSwarmProvider() error {
if cfg.Providers.Swarm == nil {
return nil
}
if err := mergo.Merge(cfg.Providers.Swarm, model.PrdSwarm{
TLSVerify: utl.NewTrue(),
WatchByDefault: utl.NewFalse(),
}); err != nil {
return errors.Wrap(err, "cannot set default values for docker provider")
}
cfg.Providers.Swarm[id] = prdSwarm
return nil
}
func (cfg *Config) validateFileProvider() error {
if cfg.Providers.File == nil {
return nil
}
switch {
case len(cfg.Providers.File.Directory) > 0:
if _, err := os.Stat(cfg.Providers.File.Directory); os.IsNotExist(err) {
@ -196,7 +202,10 @@ func (cfg *Config) validateFileProvider() error {
if _, err := os.Stat(cfg.Providers.File.Filename); os.IsNotExist(err) {
return errors.Wrap(err, "filename not found for file provider")
}
default:
return errors.New("error using file provider, neither filename or directory defined")
}
return nil
}

View file

@ -69,11 +69,9 @@ regopts:
providers:
docker:
standalone:
watch_by_default: true
watch_stopped: true
watch_by_default: true
watch_stopped: true
swarm:
local_swarm:
watch_by_default: true
watch_by_default: true
file:
filename: ./dummy.yml

View file

@ -5,6 +5,7 @@ import (
"github.com/crazy-max/diun/internal/config"
"github.com/crazy-max/diun/internal/model"
"github.com/crazy-max/diun/pkg/utl"
"github.com/stretchr/testify/assert"
)
@ -115,21 +116,17 @@ func TestLoad(t *testing.T) {
PasswordFile: "/run/secrets/password",
},
},
Providers: model.Providers{
Docker: map[string]model.PrdDocker{
"standalone": {
TLSVerify: true,
WatchByDefault: true,
WatchStopped: true,
},
Providers: &model.Providers{
Docker: &model.PrdDocker{
TLSVerify: utl.NewTrue(),
WatchByDefault: utl.NewTrue(),
WatchStopped: utl.NewTrue(),
},
Swarm: map[string]model.PrdSwarm{
"local_swarm": {
TLSVerify: true,
WatchByDefault: true,
},
Swarm: &model.PrdSwarm{
TLSVerify: utl.NewTrue(),
WatchByDefault: utl.NewTrue(),
},
File: model.PrdFile{
File: &model.PrdFile{
Filename: "./dummy.yml",
},
},

View file

@ -2,9 +2,9 @@ package model
// Providers represents a provider configuration
type Providers struct {
Docker map[string]PrdDocker `yaml:"docker,omitempty" json:",omitempty"`
Swarm map[string]PrdSwarm `yaml:"swarm,omitempty" json:",omitempty"`
File PrdFile `yaml:"file,omitempty" json:",omitempty"`
Docker *PrdDocker `yaml:"docker,omitempty" json:",omitempty"`
Swarm *PrdSwarm `yaml:"swarm,omitempty" json:",omitempty"`
File *PrdFile `yaml:"file,omitempty" json:",omitempty"`
}
// PrdDocker holds docker provider configuration
@ -12,9 +12,9 @@ type PrdDocker struct {
Endpoint string `yaml:"endpoint,omitempty" json:",omitempty"`
APIVersion string `yaml:"api_version,omitempty" json:",omitempty"`
TLSCertsPath string `yaml:"tls_certs_path,omitempty" json:",omitempty"`
TLSVerify bool `yaml:"tls_verify,omitempty" json:",omitempty"`
WatchByDefault bool `yaml:"watch_by_default,omitempty" json:",omitempty"`
WatchStopped bool `yaml:"watch_stopped,omitempty" json:",omitempty"`
TLSVerify *bool `yaml:"tls_verify,omitempty" json:",omitempty"`
WatchByDefault *bool `yaml:"watch_by_default,omitempty" json:",omitempty"`
WatchStopped *bool `yaml:"watch_stopped,omitempty" json:",omitempty"`
}
// PrdSwarm holds swarm provider configuration
@ -22,8 +22,8 @@ type PrdSwarm struct {
Endpoint string `yaml:"endpoint,omitempty" json:",omitempty"`
APIVersion string `yaml:"api_version,omitempty" json:",omitempty"`
TLSCertsPath string `yaml:"tls_certs_path,omitempty" json:",omitempty"`
TLSVerify bool `yaml:"tls_verify,omitempty" json:",omitempty"`
WatchByDefault bool `yaml:"watch_by_default,omitempty" json:",omitempty"`
TLSVerify *bool `yaml:"tls_verify,omitempty" json:",omitempty"`
WatchByDefault *bool `yaml:"watch_by_default,omitempty" json:",omitempty"`
}
// PrdFile holds file provider configuration

View file

@ -1,42 +1,36 @@
package docker
import (
"fmt"
"reflect"
"github.com/crazy-max/diun/internal/model"
"github.com/crazy-max/diun/internal/provider"
"github.com/crazy-max/diun/pkg/docker"
"github.com/docker/docker/api/types/filters"
"github.com/rs/zerolog/log"
)
func (c *Client) listContainerImage(id string, elt model.PrdDocker) []model.Image {
sublog := log.With().
Str("provider", fmt.Sprintf("docker-%s", id)).
Logger()
func (c *Client) listContainerImage() []model.Image {
cli, err := docker.New(docker.Options{
Endpoint: elt.Endpoint,
APIVersion: elt.APIVersion,
TLSCertPath: elt.TLSCertsPath,
TLSVerify: elt.TLSVerify,
Endpoint: c.config.Endpoint,
APIVersion: c.config.APIVersion,
TLSCertPath: c.config.TLSCertsPath,
TLSVerify: *c.config.TLSVerify,
})
if err != nil {
sublog.Error().Err(err).Msg("Cannot create Docker client")
c.logger.Error().Err(err).Msg("Cannot create Docker client")
return []model.Image{}
}
ctnFilter := filters.NewArgs()
ctnFilter.Add("status", "running")
if elt.WatchStopped {
if *c.config.WatchStopped {
ctnFilter.Add("status", "created")
ctnFilter.Add("status", "exited")
}
ctns, err := cli.ContainerList(ctnFilter)
if err != nil {
sublog.Error().Err(err).Msg("Cannot list Docker containers")
c.logger.Error().Err(err).Msg("Cannot list Docker containers")
return []model.Image{}
}
@ -44,18 +38,18 @@ func (c *Client) listContainerImage(id string, elt model.PrdDocker) []model.Imag
for _, ctn := range ctns {
local, err := cli.IsLocalImage(ctn.Image)
if err != nil {
sublog.Error().Err(err).Msgf("Cannot inspect image from container %s", ctn.ID)
c.logger.Error().Err(err).Msgf("Cannot inspect image from container %s", ctn.ID)
continue
} else if local {
sublog.Debug().Msgf("Skip locally built image for container %s", ctn.ID)
c.logger.Debug().Msgf("Skip locally built image for container %s", ctn.ID)
continue
}
image, err := provider.ValidateContainerImage(ctn.Image, ctn.Labels, elt.WatchByDefault)
image, err := provider.ValidateContainerImage(ctn.Image, ctn.Labels, *c.config.WatchByDefault)
if err != nil {
sublog.Error().Err(err).Msgf("Cannot get image from container %s", ctn.ID)
c.logger.Error().Err(err).Msgf("Cannot get image from container %s", ctn.ID)
continue
} else if reflect.DeepEqual(image, model.Image{}) {
sublog.Debug().Msgf("Watch disabled for container %s", ctn.ID)
c.logger.Debug().Msgf("Watch disabled for container %s", ctn.ID)
continue
}
list = append(list, image)

View file

@ -1,8 +1,6 @@
package docker
import (
"fmt"
"github.com/crazy-max/diun/internal/model"
"github.com/crazy-max/diun/internal/provider"
"github.com/rs/zerolog"
@ -12,15 +10,15 @@ import (
// Client represents an active docker provider object
type Client struct {
*provider.Client
elts map[string]model.PrdDocker
config *model.PrdDocker
logger zerolog.Logger
}
// New creates new docker provider instance
func New(elts map[string]model.PrdDocker) *provider.Client {
func New(config *model.PrdDocker) *provider.Client {
return &provider.Client{
Handler: &Client{
elts: elts,
config: config,
logger: log.With().Str("provider", "docker").Logger(),
},
}
@ -28,19 +26,22 @@ func New(elts map[string]model.PrdDocker) *provider.Client {
// ListJob returns job list to process
func (c *Client) ListJob() []model.Job {
if len(c.elts) == 0 {
if c.config == nil {
return []model.Job{}
}
c.logger.Info().Msgf("Found %d image(s) to analyze", len(c.elts))
images := c.listContainerImage()
if len(images) == 0 {
return []model.Job{}
}
c.logger.Info().Msgf("Found %d image(s) to analyze", len(images))
var list []model.Job
for id, elt := range c.elts {
for _, img := range c.listContainerImage(id, elt) {
list = append(list, model.Job{
Provider: fmt.Sprintf("docker-%s", id),
Image: img,
})
}
for _, image := range images {
list = append(list, model.Job{
Provider: "docker",
Image: image,
})
}
return list

View file

@ -1,29 +1,24 @@
package file
import (
"io/ioutil"
"path/filepath"
"strings"
"github.com/crazy-max/diun/internal/model"
"github.com/crazy-max/diun/internal/provider"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"gopkg.in/yaml.v2"
)
// Client represents an active file provider object
type Client struct {
*provider.Client
item model.PrdFile
config *model.PrdFile
logger zerolog.Logger
}
// New creates new file provider instance
func New(item model.PrdFile) *provider.Client {
func New(config *model.PrdFile) *provider.Client {
return &provider.Client{
Handler: &Client{
item: item,
config: config,
logger: log.With().Str("provider", "file").Logger(),
},
}
@ -31,73 +26,23 @@ func New(item model.PrdFile) *provider.Client {
// ListJob returns job list to process
func (c *Client) ListJob() []model.Job {
images := c.loadImages()
if c.config == nil {
return []model.Job{}
}
images := c.listFileImage()
if len(images) == 0 {
return []model.Job{}
}
c.logger.Info().Msgf("Found %d image(s) to analyze", len(images))
var list []model.Job
for _, elt := range images {
for _, image := range images {
list = append(list, model.Job{
Provider: "file",
Image: elt,
Image: image,
})
}
return list
}
func (c *Client) loadImages() []model.Image {
var images []model.Image
files := c.getFiles()
if len(files) == 0 {
return []model.Image{}
}
for _, file := range files {
var items []model.Image
bytes, err := ioutil.ReadFile(file)
if err != nil {
c.logger.Error().Err(err).Msgf("Unable to read config file %s", file)
continue
}
if err := yaml.UnmarshalStrict(bytes, &items); err != nil {
c.logger.Error().Err(err).Msgf("Unable to decode into struct %s", file)
continue
}
images = append(images, items...)
}
return images
}
func (c *Client) getFiles() []string {
var files []string
switch {
case len(c.item.Directory) > 0:
fileList, err := ioutil.ReadDir(c.item.Directory)
if err != nil {
c.logger.Error().Err(err).Msgf("Unable to read directory %s", c.item.Directory)
return files
}
for _, file := range fileList {
if file.IsDir() {
continue
}
switch strings.ToLower(filepath.Ext(file.Name())) {
case ".yaml", ".yml":
// noop
default:
continue
}
files = append(files, filepath.Join(c.item.Directory, file.Name()))
}
case len(c.item.Filename) > 0:
files = append(files, c.item.Filename)
}
return files
}

View file

@ -0,0 +1,64 @@
package file
import (
"io/ioutil"
"path/filepath"
"strings"
"github.com/crazy-max/diun/internal/model"
"gopkg.in/yaml.v2"
)
func (c *Client) listFileImage() []model.Image {
var images []model.Image
files := c.getFiles()
if len(files) == 0 {
return []model.Image{}
}
for _, file := range files {
var items []model.Image
bytes, err := ioutil.ReadFile(file)
if err != nil {
c.logger.Error().Err(err).Msgf("Unable to read config file %s", file)
continue
}
if err := yaml.UnmarshalStrict(bytes, &items); err != nil {
c.logger.Error().Err(err).Msgf("Unable to decode into struct %s", file)
continue
}
images = append(images, items...)
}
return images
}
func (c *Client) getFiles() []string {
var files []string
switch {
case len(c.config.Directory) > 0:
fileList, err := ioutil.ReadDir(c.config.Directory)
if err != nil {
c.logger.Error().Err(err).Msgf("Unable to read directory %s", c.config.Directory)
return files
}
for _, file := range fileList {
if file.IsDir() {
continue
}
switch strings.ToLower(filepath.Ext(file.Name())) {
case ".yaml", ".yml":
// noop
default:
continue
}
files = append(files, filepath.Join(c.config.Directory, file.Name()))
}
case len(c.config.Filename) > 0:
files = append(files, c.config.Filename)
}
return files
}

View file

@ -1,35 +1,29 @@
package swarm
import (
"fmt"
"reflect"
"github.com/crazy-max/diun/internal/model"
"github.com/crazy-max/diun/internal/provider"
"github.com/crazy-max/diun/pkg/docker"
"github.com/docker/docker/api/types/filters"
"github.com/rs/zerolog/log"
)
func (c *Client) listServiceImage(id string, elt model.PrdSwarm) []model.Image {
sublog := log.With().
Str("provider", fmt.Sprintf("swarm-%s", id)).
Logger()
func (c *Client) listServiceImage() []model.Image {
cli, err := docker.New(docker.Options{
Endpoint: elt.Endpoint,
APIVersion: elt.APIVersion,
TLSCertPath: elt.TLSCertsPath,
TLSVerify: elt.TLSVerify,
Endpoint: c.config.Endpoint,
APIVersion: c.config.APIVersion,
TLSCertPath: c.config.TLSCertsPath,
TLSVerify: *c.config.TLSVerify,
})
if err != nil {
sublog.Error().Err(err).Msg("Cannot create Docker client")
c.logger.Error().Err(err).Msg("Cannot create Docker client")
return []model.Image{}
}
svcs, err := cli.ServiceList(filters.NewArgs())
if err != nil {
sublog.Error().Err(err).Msg("Cannot list Swarm services")
c.logger.Error().Err(err).Msg("Cannot list Swarm services")
return []model.Image{}
}
@ -37,15 +31,15 @@ func (c *Client) listServiceImage(id string, elt model.PrdSwarm) []model.Image {
for _, svc := range svcs {
local, _ := cli.IsLocalImage(svc.Spec.TaskTemplate.ContainerSpec.Image)
if local {
sublog.Debug().Msgf("Skip locally built image for service %s", svc.Spec.Name)
c.logger.Debug().Msgf("Skip locally built image for service %s", svc.Spec.Name)
continue
}
image, err := provider.ValidateContainerImage(svc.Spec.TaskTemplate.ContainerSpec.Image, svc.Spec.Labels, elt.WatchByDefault)
image, err := provider.ValidateContainerImage(svc.Spec.TaskTemplate.ContainerSpec.Image, svc.Spec.Labels, *c.config.WatchByDefault)
if err != nil {
sublog.Error().Err(err).Msgf("Cannot get image from service %s", svc.Spec.Name)
c.logger.Error().Err(err).Msgf("Cannot get image from service %s", svc.Spec.Name)
continue
} else if reflect.DeepEqual(image, model.Image{}) {
sublog.Debug().Msgf("Watch disabled for service %s", svc.Spec.Name)
c.logger.Debug().Msgf("Watch disabled for service %s", svc.Spec.Name)
continue
}
list = append(list, image)

View file

@ -1,8 +1,6 @@
package swarm
import (
"fmt"
"github.com/crazy-max/diun/internal/model"
"github.com/crazy-max/diun/internal/provider"
"github.com/rs/zerolog"
@ -12,15 +10,15 @@ import (
// Client represents an active swarm provider object
type Client struct {
*provider.Client
elts map[string]model.PrdSwarm
config *model.PrdSwarm
logger zerolog.Logger
}
// New creates new swarm provider instance
func New(elts map[string]model.PrdSwarm) *provider.Client {
func New(config *model.PrdSwarm) *provider.Client {
return &provider.Client{
Handler: &Client{
elts: elts,
config: config,
logger: log.With().Str("provider", "swarm").Logger(),
},
}
@ -28,19 +26,22 @@ func New(elts map[string]model.PrdSwarm) *provider.Client {
// ListJob returns job list to process
func (c *Client) ListJob() []model.Job {
if len(c.elts) == 0 {
if c.config == nil {
return []model.Job{}
}
c.logger.Info().Msgf("Found %d image(s) to analyze", len(c.elts))
images := c.listServiceImage()
if len(images) == 0 {
return []model.Job{}
}
c.logger.Info().Msgf("Found %d image(s) to analyze", len(images))
var list []model.Job
for id, elt := range c.elts {
for _, img := range c.listServiceImage(id, elt) {
list = append(list, model.Job{
Provider: fmt.Sprintf("swarm-%s", id),
Image: img,
})
}
for _, image := range images {
list = append(list, model.Job{
Provider: "swarm",
Image: image,
})
}
return list

View file

@ -66,3 +66,15 @@ func GetSecret(plaintext, filename string) (string, error) {
}
return "", nil
}
// NewFalse returns a false bool pointer
func NewFalse() *bool {
b := false
return &b
}
// NewTrue returns a true bool pointer
func NewTrue() *bool {
b := true
return &b
}