forked from toolshed/abra
		
	
		
			
				
	
	
		
			107 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package recipe
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"strconv"
 | 
						|
 | 
						|
	"coopcloud.tech/abra/cli/formatter"
 | 
						|
	"coopcloud.tech/abra/cli/internal"
 | 
						|
	"coopcloud.tech/abra/pkg/catalogue"
 | 
						|
	"coopcloud.tech/abra/pkg/config"
 | 
						|
	"coopcloud.tech/tagcmp"
 | 
						|
	"github.com/docker/distribution/reference"
 | 
						|
	"github.com/sirupsen/logrus"
 | 
						|
	"github.com/urfave/cli/v2"
 | 
						|
)
 | 
						|
 | 
						|
var recipeLintCommand = &cli.Command{
 | 
						|
	Name:      "lint",
 | 
						|
	Usage:     "Lint a recipe",
 | 
						|
	Aliases:   []string{"l"},
 | 
						|
	ArgsUsage: "<recipe>",
 | 
						|
	Action: func(c *cli.Context) error {
 | 
						|
		recipe := internal.ValidateRecipe(c)
 | 
						|
 | 
						|
		expectedVersion := false
 | 
						|
		if recipe.Config.Version == "3.8" {
 | 
						|
			expectedVersion = true
 | 
						|
		}
 | 
						|
 | 
						|
		envSampleProvided := false
 | 
						|
		envSample := fmt.Sprintf("%s/%s/.env.sample", config.APPS_DIR, recipe.Name)
 | 
						|
		if _, err := os.Stat(envSample); !os.IsNotExist(err) {
 | 
						|
			envSampleProvided = true
 | 
						|
		} else if err != nil {
 | 
						|
			logrus.Fatal(err)
 | 
						|
		}
 | 
						|
 | 
						|
		serviceNamedApp := false
 | 
						|
		traefikEnabled := false
 | 
						|
		healthChecksForAllServices := true
 | 
						|
		allImagesTagged := true
 | 
						|
		noUnstableTags := true
 | 
						|
		semverLikeTags := true
 | 
						|
		for _, service := range recipe.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
 | 
						|
			}
 | 
						|
 | 
						|
			tag := img.(reference.NamedTagged).Tag()
 | 
						|
			if tag == "latest" {
 | 
						|
				noUnstableTags = false
 | 
						|
			}
 | 
						|
 | 
						|
			if !tagcmp.IsParsable(tag) {
 | 
						|
				semverLikeTags = false
 | 
						|
			}
 | 
						|
 | 
						|
			if service.HealthCheck == nil {
 | 
						|
				healthChecksForAllServices = false
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		tableCol := []string{"rule", "satisfied"}
 | 
						|
		table := formatter.CreateTable(tableCol)
 | 
						|
		table.Append([]string{"compose files have the expected version", strconv.FormatBool(expectedVersion)})
 | 
						|
		table.Append([]string{"environment configuration is provided", strconv.FormatBool(envSampleProvided)})
 | 
						|
		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.Append([]string{"all tags are using a semver-like format", strconv.FormatBool(semverLikeTags)})
 | 
						|
		table.Render()
 | 
						|
 | 
						|
		return nil
 | 
						|
	},
 | 
						|
	BashComplete: func(c *cli.Context) {
 | 
						|
		catl, err := catalogue.ReadRecipeCatalogue()
 | 
						|
		if err != nil {
 | 
						|
			logrus.Warn(err)
 | 
						|
		}
 | 
						|
		if c.NArg() > 0 {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		for name := range catl {
 | 
						|
			fmt.Println(name)
 | 
						|
		}
 | 
						|
	},
 | 
						|
}
 |