Skip to content

Commit

Permalink
feat: Starting to add docker support
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Boutour <[email protected]>
  • Loading branch information
ViBiOh committed May 21, 2021
1 parent 75d7799 commit b5e576a
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 22 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ Usage of ketchup:
[db] SSL Mode {KETCHUP_DB_SSLMODE} (default "disable")
-dbUser string
[db] User {KETCHUP_DB_USER}
-dockerOAuth URL string
[docker] Registry API URL {KETCHUP_DOCKER_OAUTH _URL} (default "https://auth.docker.io/token")
-dockerPassword string
[docker] Registry Password {KETCHUP_DOCKER_PASSWORD}
-dockerRegistry string
[docker] Registry API URL {KETCHUP_DOCKER_REGISTRY} (default "https://index.docker.io/v2/")
-dockerUsername string
[docker] Registry Username {KETCHUP_DOCKER_USERNAME}
-frameOptions string
[owasp] X-Frame-Options {KETCHUP_FRAME_OPTIONS} (default "deny")
-githubToken string
Expand Down
5 changes: 4 additions & 1 deletion cmd/ketchup/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/ViBiOh/httputils/v4/pkg/redis"
"github.com/ViBiOh/httputils/v4/pkg/renderer"
"github.com/ViBiOh/httputils/v4/pkg/server"
"github.com/ViBiOh/ketchup/pkg/docker"
"github.com/ViBiOh/ketchup/pkg/github"
"github.com/ViBiOh/ketchup/pkg/helm"
"github.com/ViBiOh/ketchup/pkg/ketchup"
Expand Down Expand Up @@ -73,6 +74,7 @@ func main() {
redisConfig := redis.Flags(fs, "redis")
mailerConfig := mailer.Flags(fs, "mailer")
githubConfig := github.Flags(fs, "github")
dockerConfig := docker.Flags(fs, "docker")
notifierConfig := notifier.Flags(fs, "notifier")
schedulerConfig := scheduler.Flags(fs, "scheduler")

Expand Down Expand Up @@ -102,8 +104,9 @@ func main() {

userServiceApp := userService.New(userStore.New(ketchupDb), authServiceApp)
githubApp := github.New(githubConfig, redisApp)
dockerApp := docker.New(dockerConfig)
helmApp := helm.New()
repositoryServiceApp := repositoryService.New(repositoryStore.New(ketchupDb), githubApp, helmApp)
repositoryServiceApp := repositoryService.New(repositoryStore.New(ketchupDb), githubApp, helmApp, dockerApp)
ketchupServiceApp := ketchupService.New(ketchupStore.New(ketchupDb), repositoryServiceApp)

mailerApp, err := mailer.New(mailerConfig)
Expand Down
4 changes: 3 additions & 1 deletion cmd/notifier/notifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/ViBiOh/httputils/v4/pkg/db"
"github.com/ViBiOh/httputils/v4/pkg/logger"
"github.com/ViBiOh/ketchup/pkg/docker"
"github.com/ViBiOh/ketchup/pkg/github"
"github.com/ViBiOh/ketchup/pkg/helm"
"github.com/ViBiOh/ketchup/pkg/notifier"
Expand All @@ -25,6 +26,7 @@ func main() {
dbConfig := db.Flags(fs, "db")
mailerConfig := mailer.Flags(fs, "mailer")
githubConfig := github.Flags(fs, "github")
dockerConfig := docker.Flags(fs, "docker")
notifierConfig := notifier.Flags(fs, "notifier")

logger.Fatal(fs.Parse(os.Args[1:]))
Expand All @@ -45,7 +47,7 @@ func main() {
defer mailerApp.Close()

helmApp := helm.New()
repositoryServiceApp := repositoryService.New(repositoryStore.New(ketchupDb), github.New(githubConfig, nil), helmApp)
repositoryServiceApp := repositoryService.New(repositoryStore.New(ketchupDb), github.New(githubConfig, nil), helmApp, docker.New(dockerConfig))
ketchupServiceApp := ketchupService.New(ketchupStore.New(ketchupDb), repositoryServiceApp)

notifierApp := notifier.New(notifierConfig, repositoryServiceApp, ketchupServiceApp, mailerApp, helmApp)
Expand Down
120 changes: 120 additions & 0 deletions pkg/docker/docker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package docker

import (
"context"
"flag"
"fmt"
"net/url"
"strings"

"github.com/ViBiOh/httputils/v4/pkg/flags"
"github.com/ViBiOh/httputils/v4/pkg/httpjson"
"github.com/ViBiOh/httputils/v4/pkg/request"
"github.com/ViBiOh/ketchup/pkg/model"
"github.com/ViBiOh/ketchup/pkg/semver"
)

type authResponse struct {
AccessToken string `json:"access_token"`
}

type tagsResponse struct {
Tags []string `json:"tags"`
}

// App of package
type App interface {
LatestVersions(string, []string) (map[string]semver.Version, error)
}

// Config of package
type Config struct {
registryURL *string
authURL *string
username *string
password *string
}

type app struct {
registryURL string
authURL string
username string
password string
}

// Flags adds flags for configuring package
func Flags(fs *flag.FlagSet, prefix string, overrides ...flags.Override) Config {
return Config{
registryURL: flags.New(prefix, "FlagPrefix").Name("Registry").Default(flags.Default("Registry", "https://index.docker.io/v2/", overrides)).Label("Registry API URL").ToString(fs),
authURL: flags.New(prefix, "FlagPrefix").Name("OAuth URL").Default(flags.Default("Registry", "https://auth.docker.io/token", overrides)).Label("Registry API URL").ToString(fs),
username: flags.New(prefix, "FlagPrefix").Name("Username").Default(flags.Default("Username", "", overrides)).Label("Registry Username").ToString(fs),
password: flags.New(prefix, "FlagPrefix").Name("Password").Default(flags.Default("Password", "", overrides)).Label("Registry Password").ToString(fs),
}
}

// New creates new App from Config
func New(config Config) App {
return app{
registryURL: strings.TrimSpace(*config.registryURL),
authURL: strings.TrimSpace(*config.authURL),
username: strings.TrimSpace(*config.username),
password: strings.TrimSpace(*config.password),
}
}

func (a app) LatestVersions(repository string, patterns []string) (map[string]semver.Version, error) {
ctx := context.Background()

versions, compiledPatterns, err := model.PreparePatternMatching(patterns)
if err != nil {
return nil, fmt.Errorf("unable to prepare pattern matching: %s", err)
}

bearerToken, err := a.login(ctx, repository)
if err != nil {
return nil, fmt.Errorf("unable to login to registry: %s", err)
}

resp, err := request.New().Get(fmt.Sprintf("%s%s/tags/list", a.registryURL, repository)).Header("Authorization", fmt.Sprintf("Bearer %s", bearerToken)).Send(ctx, nil)
if err != nil {
return nil, fmt.Errorf("unable to fetch tags: %s", err)
}

var tagsContent tagsResponse
if err := httpjson.Read(resp, &tagsContent, "docker-tags"); err != nil {
return nil, err
}

for _, tag := range tagsContent.Tags {
tagVersion, err := semver.Parse(tag)
if err != nil {
continue
}

model.CheckPatternsMatching(versions, compiledPatterns, tagVersion)
}

return versions, nil
}

func (a app) login(ctx context.Context, repository string) (string, error) {
values := url.Values{}
values.Set("grant_type", "password")
values.Set("service", "registry.docker.io")
values.Set("client_id", "ketchup")
values.Set("scope", fmt.Sprintf("repository:%s:pull", repository))
values.Set("username", a.username)
values.Set("password", a.password)

resp, err := request.New().Post(a.authURL).Form(ctx, values)
if err != nil {
return "", fmt.Errorf("unable to authenticate to `%s`: %s", a.authURL, err)
}

var authContent authResponse
if err := httpjson.Read(resp, &authContent, "docker-login"); err != nil {
return "", err
}

return authContent.AccessToken, nil
}
2 changes: 2 additions & 0 deletions pkg/model/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const (
Github RepositoryKind = iota
// Helm repository kind
Helm
// Docker repository kind
Docker
)

var (
Expand Down
7 changes: 6 additions & 1 deletion pkg/service/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

httpModel "github.com/ViBiOh/httputils/v4/pkg/model"
"github.com/ViBiOh/ketchup/pkg/docker"
"github.com/ViBiOh/ketchup/pkg/github"
"github.com/ViBiOh/ketchup/pkg/helm"
"github.com/ViBiOh/ketchup/pkg/model"
Expand All @@ -34,14 +35,16 @@ type app struct {
repositoryStore repository.App
githubApp github.App
helmApp helm.App
dockerApp docker.App
}

// New creates new App from Config
func New(repositoryStore repository.App, githubApp github.App, helmApp helm.App) App {
func New(repositoryStore repository.App, githubApp github.App, helmApp helm.App, dockerApp docker.App) App {
return app{
repositoryStore: repositoryStore,
githubApp: githubApp,
helmApp: helmApp,
dockerApp: dockerApp,
}
}

Expand Down Expand Up @@ -223,6 +226,8 @@ func (a app) LatestVersions(repo model.Repository) (map[string]semver.Version, e
return a.githubApp.LatestVersions(repo.Name, patterns)
case model.Helm:
return a.helmApp.LatestVersions(repo.Name, repo.Part, patterns)
case model.Docker:
return a.dockerApp.LatestVersions(repo.Name, patterns)
default:
return nil, fmt.Errorf("unknown repository kind %d", repo.Kind)
}
Expand Down
Loading

0 comments on commit b5e576a

Please sign in to comment.