WIP: recipe lint command

This commit is contained in:
decentral1se 2021-08-03 19:25:32 +02:00
parent 3a42288a59
commit 532bb8a336
No known key found for this signature in database
GPG Key ID: 5E2EF5A63E3718CC
2 changed files with 86 additions and 0 deletions

View File

@ -5,14 +5,19 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"sort"
"strconv"
"text/template"
"coopcloud.tech/abra/catalogue"
"coopcloud.tech/abra/cli/formatter"
"coopcloud.tech/abra/cli/internal"
loader "coopcloud.tech/abra/client/stack"
"coopcloud.tech/abra/config"
"github.com/docker/cli/cli/command/stack/options"
"github.com/docker/distribution/reference"
"github.com/go-git/go-git/v5"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
@ -144,6 +149,85 @@ var recipeCreateCommand = &cli.Command{
},
}
var recipeLintCommand = &cli.Command{
Name: "lint",
Usage: "Recipe configuration linter",
ArgsUsage: "<recipe>",
Action: func(c *cli.Context) error {
recipe := c.Args().First()
if recipe == "" {
internal.ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
}
pattern := fmt.Sprintf("%s/%s/compose**yml", config.APPS_DIR, recipe)
composeFiles, err := filepath.Glob(pattern)
if err != nil {
logrus.Fatal(err)
}
opts := options.Deploy{Composefiles: composeFiles}
config, err := loader.LoadComposefile(opts)
if err != nil {
logrus.Fatal(err)
}
expectedVersion := false
if config.Version == "3.8" {
expectedVersion = true
}
serviceNamedApp := false
traefikEnabled := false
healthChecksForAllServices := true
allImagesTagged := true
noUnstableTags := true
for _, service := range config.Services {
if service.Name == "app" {
serviceNamedApp = true
}
for label := range service.Deploy.Labels {
if label == "traefik.enable" {
if service.Deploy.Labels[label] == "true" {
traefikEnabled = true
}
}
}
img, err := reference.ParseNormalizedNamed(service.Image)
if err != nil {
logrus.Fatal(err)
}
if reference.IsNameOnly(img) {
allImagesTagged = false
}
if img.(reference.NamedTagged).Tag() == "latest" {
noUnstableTags = false
}
if service.HealthCheck == nil {
healthChecksForAllServices = false
}
}
// TODO
// check for .env.sample
tableCol := []string{"Rule", "Satisfied"}
table := formatter.CreateTable(tableCol)
table.Append([]string{"Compose files have the expected version", strconv.FormatBool(expectedVersion)})
table.Append([]string{"Recipe contains a service named 'app'", strconv.FormatBool(serviceNamedApp)})
table.Append([]string{"Traefik routing enabled on at least one service", strconv.FormatBool(traefikEnabled)})
table.Append([]string{"All services have a healthcheck enabled", strconv.FormatBool(healthChecksForAllServices)})
table.Append([]string{"All images are using a tag", strconv.FormatBool(allImagesTagged)})
table.Append([]string{"No usage of unstable 'latest' tags", strconv.FormatBool(noUnstableTags)})
table.Render()
return nil
},
}
// RecipeCommand defines the `abra recipe` command and ets subcommands
var RecipeCommand = &cli.Command{
Name: "recipe",
@ -162,5 +246,6 @@ how reliable this app is to deploy and maintain in its current state.
recipeListCommand,
recipeVersionCommand,
recipeCreateCommand,
recipeLintCommand,
},
}

1
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4
github.com/containerd/containerd v1.5.5 // indirect
github.com/docker/cli v20.10.7+incompatible
github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker v20.10.7+incompatible
github.com/docker/docker-credential-helpers v0.6.4 // indirect
github.com/docker/go-units v0.4.0