mirror of
https://github.com/crazy-max/diun.git
synced 2025-12-21 21:33:22 +01:00
Move registry client to a dedicated package
This commit is contained in:
@@ -6,8 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/crazy-max/diun/internal/model"
|
"github.com/crazy-max/diun/internal/model"
|
||||||
"github.com/crazy-max/diun/pkg/docker"
|
"github.com/crazy-max/diun/pkg/registry"
|
||||||
"github.com/crazy-max/diun/pkg/docker/registry"
|
|
||||||
"github.com/crazy-max/diun/pkg/utl"
|
"github.com/crazy-max/diun/pkg/utl"
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@@ -75,7 +74,7 @@ func (di *Diun) createJob(job model.Job) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
job.Registry, err = docker.NewRegistryClient(docker.RegistryOptions{
|
job.Registry, err = registry.New(registry.Options{
|
||||||
Os: job.Image.Os,
|
Os: job.Image.Os,
|
||||||
Arch: job.Image.Arch,
|
Arch: job.Image.Arch,
|
||||||
Username: regUser,
|
Username: regUser,
|
||||||
@@ -99,7 +98,7 @@ func (di *Diun) createJob(job model.Job) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tags, err := job.Registry.Tags(docker.TagsOptions{
|
tags, err := job.Registry.Tags(registry.TagsOptions{
|
||||||
Image: job.RegImage,
|
Image: job.RegImage,
|
||||||
Max: job.Image.MaxTags,
|
Max: job.Image.MaxTags,
|
||||||
Include: job.Image.IncludeTags,
|
Include: job.Image.IncludeTags,
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/crazy-max/diun/internal/model"
|
"github.com/crazy-max/diun/internal/model"
|
||||||
"github.com/crazy-max/diun/pkg/docker"
|
"github.com/crazy-max/diun/pkg/registry"
|
||||||
"github.com/crazy-max/diun/pkg/docker/registry"
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
@@ -72,8 +71,8 @@ func (c *Client) First(image registry.Image) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetManifest returns Docker image manifest
|
// GetManifest returns Docker image manifest
|
||||||
func (c *Client) GetManifest(image registry.Image) (docker.Manifest, error) {
|
func (c *Client) GetManifest(image registry.Image) (registry.Manifest, error) {
|
||||||
var manifest docker.Manifest
|
var manifest registry.Manifest
|
||||||
|
|
||||||
err := c.View(func(tx *bolt.Tx) error {
|
err := c.View(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket([]byte(bucket))
|
b := tx.Bucket([]byte(bucket))
|
||||||
@@ -87,7 +86,7 @@ func (c *Client) GetManifest(image registry.Image) (docker.Manifest, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PutManifest add Docker image manifest in db
|
// PutManifest add Docker image manifest in db
|
||||||
func (c *Client) PutManifest(image registry.Image, manifest docker.Manifest) error {
|
func (c *Client) PutManifest(image registry.Image, manifest registry.Manifest) error {
|
||||||
entryBytes, _ := json.Marshal(manifest)
|
entryBytes, _ := json.Marshal(manifest)
|
||||||
|
|
||||||
err := c.Update(func(tx *bolt.Tx) error {
|
err := c.Update(func(tx *bolt.Tx) error {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/crazy-max/diun/pkg/docker"
|
"github.com/crazy-max/diun/pkg/registry"
|
||||||
"github.com/crazy-max/diun/pkg/docker/registry"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Job holds job configuration
|
// Job holds job configuration
|
||||||
@@ -10,6 +9,6 @@ type Job struct {
|
|||||||
Provider string
|
Provider string
|
||||||
Image Image
|
Image Image
|
||||||
RegImage registry.Image
|
RegImage registry.Image
|
||||||
Registry *docker.RegistryClient
|
Registry *registry.Client
|
||||||
FirstCheck bool
|
FirstCheck bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/crazy-max/diun/pkg/docker"
|
"github.com/crazy-max/diun/pkg/registry"
|
||||||
"github.com/crazy-max/diun/pkg/docker/registry"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NotifEntry represents a notification entry
|
// NotifEntry represents a notification entry
|
||||||
type NotifEntry struct {
|
type NotifEntry struct {
|
||||||
Status ImageStatus `json:"status,omitempty"`
|
Status ImageStatus `json:"status,omitempty"`
|
||||||
Provider string `json:"provider,omitempty"`
|
Provider string `json:"provider,omitempty"`
|
||||||
Image registry.Image `json:"image,omitempty"`
|
Image registry.Image `json:"image,omitempty"`
|
||||||
Manifest docker.Manifest `json:"manifest,omitempty"`
|
Manifest registry.Manifest `json:"manifest,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notif holds data necessary for notification configuration
|
// Notif holds data necessary for notification configuration
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ func (c *Client) listContainerImage(id string, elt model.PrdDocker) []model.Imag
|
|||||||
Str("provider", fmt.Sprintf("docker-%s", id)).
|
Str("provider", fmt.Sprintf("docker-%s", id)).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
cli, err := docker.NewClient(elt.Endpoint, elt.APIVersion, elt.TLSCertsPath, elt.TLSVerify)
|
cli, err := docker.New(docker.Options{
|
||||||
|
Endpoint: elt.Endpoint,
|
||||||
|
APIVersion: elt.APIVersion,
|
||||||
|
TLSCertPath: elt.TLSCertsPath,
|
||||||
|
TLSVerify: elt.TLSVerify,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sublog.Error().Err(err).Msg("Cannot create Docker client")
|
sublog.Error().Err(err).Msg("Cannot create Docker client")
|
||||||
return []model.Image{}
|
return []model.Image{}
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ func (c *Client) listServiceImage(id string, elt model.PrdSwarm) []model.Image {
|
|||||||
Str("provider", fmt.Sprintf("swarm-%s", id)).
|
Str("provider", fmt.Sprintf("swarm-%s", id)).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
cli, err := docker.NewClient(elt.Endpoint, elt.APIVersion, elt.TLSCertsPath, elt.TLSVerify)
|
cli, err := docker.New(docker.Options{
|
||||||
|
Endpoint: elt.Endpoint,
|
||||||
|
APIVersion: elt.APIVersion,
|
||||||
|
TLSCertPath: elt.TLSCertsPath,
|
||||||
|
TLSVerify: elt.TLSVerify,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sublog.Error().Err(err).Msg("Cannot create Docker client")
|
sublog.Error().Err(err).Msg("Cannot create Docker client")
|
||||||
return []model.Image{}
|
return []model.Image{}
|
||||||
|
|||||||
@@ -16,21 +16,29 @@ type Client struct {
|
|||||||
API *client.Client
|
API *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient initializes a new Docker API client with default values
|
// Options holds docker client object options
|
||||||
func NewClient(endpoint, apiVersion, tlsCertsPath string, tlsVerify bool) (*Client, error) {
|
type Options struct {
|
||||||
var opts []client.Opt
|
Endpoint string
|
||||||
if endpoint != "" {
|
APIVersion string
|
||||||
opts = append(opts, client.WithHost(endpoint))
|
TLSCertPath string
|
||||||
|
TLSVerify bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// New initializes a new Docker API client with default values
|
||||||
|
func New(opts Options) (*Client, error) {
|
||||||
|
var dockerOpts []client.Opt
|
||||||
|
if opts.Endpoint != "" {
|
||||||
|
dockerOpts = append(dockerOpts, client.WithHost(opts.Endpoint))
|
||||||
}
|
}
|
||||||
if apiVersion != "" {
|
if opts.APIVersion != "" {
|
||||||
opts = append(opts, client.WithVersion(apiVersion))
|
dockerOpts = append(dockerOpts, client.WithVersion(opts.APIVersion))
|
||||||
}
|
}
|
||||||
if tlsCertsPath != "" {
|
if opts.TLSCertPath != "" {
|
||||||
options := tlsconfig.Options{
|
options := tlsconfig.Options{
|
||||||
CAFile: filepath.Join(tlsCertsPath, "ca.pem"),
|
CAFile: filepath.Join(opts.TLSCertPath, "ca.pem"),
|
||||||
CertFile: filepath.Join(tlsCertsPath, "cert.pem"),
|
CertFile: filepath.Join(opts.TLSCertPath, "cert.pem"),
|
||||||
KeyFile: filepath.Join(tlsCertsPath, "key.pem"),
|
KeyFile: filepath.Join(opts.TLSCertPath, "key.pem"),
|
||||||
InsecureSkipVerify: !tlsVerify,
|
InsecureSkipVerify: !opts.TLSVerify,
|
||||||
}
|
}
|
||||||
tlsc, err := tlsconfig.Client(options)
|
tlsc, err := tlsconfig.Client(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -40,10 +48,10 @@ func NewClient(endpoint, apiVersion, tlsCertsPath string, tlsVerify bool) (*Clie
|
|||||||
Transport: &http.Transport{TLSClientConfig: tlsc},
|
Transport: &http.Transport{TLSClientConfig: tlsc},
|
||||||
CheckRedirect: client.CheckRedirect,
|
CheckRedirect: client.CheckRedirect,
|
||||||
}
|
}
|
||||||
opts = append(opts, client.WithHTTPClient(httpCli))
|
dockerOpts = append(dockerOpts, client.WithHTTPClient(httpCli))
|
||||||
}
|
}
|
||||||
|
|
||||||
cli, err := client.NewClientWithOpts(opts...)
|
cli, err := client.NewClientWithOpts(dockerOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package registry
|
|
||||||
|
|
||||||
// Name returns the full name representation of an image.
|
|
||||||
func (i Image) Name() string {
|
|
||||||
return i.named.Name()
|
|
||||||
}
|
|
||||||
61
pkg/kubernetes/client.go
Normal file
61
pkg/kubernetes/client.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package kubernetes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client represents an active docker object
|
||||||
|
type Client struct {
|
||||||
|
ctx context.Context
|
||||||
|
API *client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient initializes a new Docker API client with default values
|
||||||
|
func NewClient(endpoint, apiVersion, tlsCertsPath string, tlsVerify bool) (*Client, error) {
|
||||||
|
var opts []client.Opt
|
||||||
|
if endpoint != "" {
|
||||||
|
opts = append(opts, client.WithHost(endpoint))
|
||||||
|
}
|
||||||
|
if apiVersion != "" {
|
||||||
|
opts = append(opts, client.WithVersion(apiVersion))
|
||||||
|
}
|
||||||
|
if tlsCertsPath != "" {
|
||||||
|
options := tlsconfig.Options{
|
||||||
|
CAFile: filepath.Join(tlsCertsPath, "ca.pem"),
|
||||||
|
CertFile: filepath.Join(tlsCertsPath, "cert.pem"),
|
||||||
|
KeyFile: filepath.Join(tlsCertsPath, "key.pem"),
|
||||||
|
InsecureSkipVerify: !tlsVerify,
|
||||||
|
}
|
||||||
|
tlsc, err := tlsconfig.Client(options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to create tls config")
|
||||||
|
}
|
||||||
|
httpCli := &http.Client{
|
||||||
|
Transport: &http.Transport{TLSClientConfig: tlsc},
|
||||||
|
CheckRedirect: client.CheckRedirect,
|
||||||
|
}
|
||||||
|
opts = append(opts, client.WithHTTPClient(httpCli))
|
||||||
|
}
|
||||||
|
|
||||||
|
cli, err := client.NewClientWithOpts(opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
_, err = cli.ServerVersion(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
ctx: ctx,
|
||||||
|
API: cli,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
@@ -17,6 +17,11 @@ type Image struct {
|
|||||||
named reference.Named
|
named reference.Named
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns the full name representation of an image.
|
||||||
|
func (i Image) Name() string {
|
||||||
|
return i.named.Name()
|
||||||
|
}
|
||||||
|
|
||||||
// String returns the string representation of an image.
|
// String returns the string representation of an image.
|
||||||
func (i Image) String() string {
|
func (i Image) String() string {
|
||||||
return i.named.String()
|
return i.named.String()
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
package docker
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/image/manifest"
|
"github.com/containers/image/manifest"
|
||||||
"github.com/crazy-max/diun/pkg/docker/registry"
|
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,7 +21,7 @@ type Manifest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Manifest returns the manifest for a specific image
|
// Manifest returns the manifest for a specific image
|
||||||
func (c *RegistryClient) Manifest(image registry.Image) (Manifest, error) {
|
func (c *Client) Manifest(image Image) (Manifest, error) {
|
||||||
ctx, cancel := c.timeoutContext()
|
ctx, cancel := c.timeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package docker
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -10,14 +10,14 @@ import (
|
|||||||
"github.com/containers/image/types"
|
"github.com/containers/image/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegistryClient represents an active docker registry object
|
// Client represents an active docker registry object
|
||||||
type RegistryClient struct {
|
type Client struct {
|
||||||
opts RegistryOptions
|
opts Options
|
||||||
sysCtx *types.SystemContext
|
sysCtx *types.SystemContext
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegistryOptions holds docker registry object options
|
// Options holds docker registry object options
|
||||||
type RegistryOptions struct {
|
type Options struct {
|
||||||
Os string
|
Os string
|
||||||
Arch string
|
Arch string
|
||||||
Username string
|
Username string
|
||||||
@@ -27,8 +27,8 @@ type RegistryOptions struct {
|
|||||||
UserAgent string
|
UserAgent string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRegistryClient creates new docker registry client instance
|
// New creates new docker registry client instance
|
||||||
func NewRegistryClient(opts RegistryOptions) (*RegistryClient, error) {
|
func New(opts Options) (*Client, error) {
|
||||||
// Auth
|
// Auth
|
||||||
auth := &types.DockerAuthConfig{}
|
auth := &types.DockerAuthConfig{}
|
||||||
if opts.Username != "" {
|
if opts.Username != "" {
|
||||||
@@ -48,12 +48,12 @@ func NewRegistryClient(opts RegistryOptions) (*RegistryClient, error) {
|
|||||||
DockerRegistryUserAgent: opts.UserAgent,
|
DockerRegistryUserAgent: opts.UserAgent,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RegistryClient{
|
return &Client{
|
||||||
sysCtx: sysCtx,
|
sysCtx: sysCtx,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RegistryClient) timeoutContext() (context.Context, context.CancelFunc) {
|
func (c *Client) timeoutContext() (context.Context, context.CancelFunc) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
var cancel context.CancelFunc = func() {}
|
var cancel context.CancelFunc = func() {}
|
||||||
if c.opts.Timeout > 0 {
|
if c.opts.Timeout > 0 {
|
||||||
@@ -62,7 +62,7 @@ func (c *RegistryClient) timeoutContext() (context.Context, context.CancelFunc)
|
|||||||
return ctx, cancel
|
return ctx, cancel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RegistryClient) newImage(ctx context.Context, imageStr string) (types.ImageCloser, error) {
|
func (c *Client) newImage(ctx context.Context, imageStr string) (types.ImageCloser, error) {
|
||||||
if !strings.HasPrefix(imageStr, "//") {
|
if !strings.HasPrefix(imageStr, "//") {
|
||||||
imageStr = fmt.Sprintf("//%s", imageStr)
|
imageStr = fmt.Sprintf("//%s", imageStr)
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
package docker
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containers/image/docker"
|
"github.com/containers/image/docker"
|
||||||
"github.com/crazy-max/diun/pkg/docker/registry"
|
|
||||||
"github.com/crazy-max/diun/pkg/utl"
|
"github.com/crazy-max/diun/pkg/utl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,14 +13,14 @@ type Tags struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TagsOptions struct {
|
type TagsOptions struct {
|
||||||
Image registry.Image
|
Image Image
|
||||||
Max int
|
Max int
|
||||||
Include []string
|
Include []string
|
||||||
Exclude []string
|
Exclude []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags returns tags of a Docker repository
|
// Tags returns tags of a Docker repository
|
||||||
func (c *RegistryClient) Tags(opts TagsOptions) (*Tags, error) {
|
func (c *Client) Tags(opts TagsOptions) (*Tags, error) {
|
||||||
ctx, cancel := c.timeoutContext()
|
ctx, cancel := c.timeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
Reference in New Issue
Block a user