diff --git a/doc/configuration.md b/doc/configuration.md index 25a27b27..a32f5f71 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -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 ``` diff --git a/doc/providers/docker.md b/doc/providers/docker.md index 9334f2e4..7610f5ee 100644 --- a/doc/providers/docker.md +++ b/doc/providers/docker.md @@ -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. diff --git a/doc/providers/swarm.md b/doc/providers/swarm.md index 4bce1c24..ccc841f7 100644 --- a/doc/providers/swarm.md +++ b/doc/providers/swarm.md @@ -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. diff --git a/internal/config/config.go b/internal/config/config.go index 10a9d310..7528d2ce 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -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 } diff --git a/internal/config/config.test.yml b/internal/config/config.test.yml index b687d57e..3010b841 100644 --- a/internal/config/config.test.yml +++ b/internal/config/config.test.yml @@ -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 diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 168cef26..495e04f9 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -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", }, }, diff --git a/internal/model/providers.go b/internal/model/providers.go index b2fbe5bd..48a19353 100644 --- a/internal/model/providers.go +++ b/internal/model/providers.go @@ -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 diff --git a/internal/provider/docker/container.go b/internal/provider/docker/container.go index 6bd9f746..060fb9dc 100644 --- a/internal/provider/docker/container.go +++ b/internal/provider/docker/container.go @@ -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) diff --git a/internal/provider/docker/docker.go b/internal/provider/docker/docker.go index 481c5db0..2eb0559f 100644 --- a/internal/provider/docker/docker.go +++ b/internal/provider/docker/docker.go @@ -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 diff --git a/internal/provider/file/file.go b/internal/provider/file/file.go index 1afdb48a..38003801 100644 --- a/internal/provider/file/file.go +++ b/internal/provider/file/file.go @@ -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 -} diff --git a/internal/provider/file/image.go b/internal/provider/file/image.go new file mode 100644 index 00000000..997c5101 --- /dev/null +++ b/internal/provider/file/image.go @@ -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 +} diff --git a/internal/provider/swarm/service.go b/internal/provider/swarm/service.go index 505cb50b..23f7bcb5 100644 --- a/internal/provider/swarm/service.go +++ b/internal/provider/swarm/service.go @@ -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) diff --git a/internal/provider/swarm/swarm.go b/internal/provider/swarm/swarm.go index e18d5761..a6eef385 100644 --- a/internal/provider/swarm/swarm.go +++ b/internal/provider/swarm/swarm.go @@ -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 diff --git a/pkg/utl/utl.go b/pkg/utl/utl.go index 3f2b6081..06967243 100644 --- a/pkg/utl/utl.go +++ b/pkg/utl/utl.go @@ -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 +}