Skip to content

Commit

Permalink
Merge pull request #2 from namely/add-validator
Browse files Browse the repository at this point in the history
Add validator
  • Loading branch information
shraykay authored Jan 24, 2018
2 parents 73a9ab6 + 42a1857 commit 35b7f50
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 8 deletions.
44 changes: 39 additions & 5 deletions cmd/k8s-pipeliner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ package main
import (
"encoding/json"
"errors"
"fmt"
"os"

"github.com/namely/k8s-pipeliner/pipeline"
"github.com/namely/k8s-pipeliner/pipeline/builder"
"github.com/namely/k8s-pipeliner/pipeline/config"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)

const (
// Version defines the current version of k8s-pipeliner
Version = "0.0.1"
Version = "0.0.2"
)

func main() {
Expand All @@ -29,10 +30,15 @@ func main() {
Usage: "creates a spinnaker pipeline for a given application on multiple k8s clusters",
Action: createAction,
},
{
Name: "validate",
Usage: "performs simple validation on a pipeline to ensure it will work with Spinnaker + Kubernetes",
Action: validateAction,
},
}

if err := app.Run(os.Args); err != nil {
logrus.WithError(err).Error()
fmt.Println(err.Error())
os.Exit(1)
}
}
Expand All @@ -48,10 +54,38 @@ func createAction(ctx *cli.Context) error {
return err
}

pipeline, err := config.NewPipeline(f)
p, err := config.NewPipeline(f)
if err != nil {
return err
}

return json.NewEncoder(os.Stdout).Encode(builder.New(pipeline))
return json.NewEncoder(os.Stdout).Encode(builder.New(p))
}

func validateAction(ctx *cli.Context) error {
p, err := pipelineConfigHelper(ctx)
if err != nil {
return err
}

return pipeline.NewValidator(p).Validate()
}

func pipelineConfigHelper(ctx *cli.Context) (*config.Pipeline, error) {
pipelineFile := ctx.Args().First()
if pipelineFile == "" {
return nil, errors.New("missing parameter: file")
}

f, err := os.Open(pipelineFile)
if err != nil {
return nil, err
}

p, err := config.NewPipeline(f)
if err != nil {
return nil, err
}

return p, nil
}
15 changes: 13 additions & 2 deletions pipeline/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ func New(p *config.Pipeline) *Builder {
return &Builder{p}
}

// MarshalJSON implements json.Marshaller
func (b *Builder) MarshalJSON() ([]byte, error) {
// Pipeline returns a filled out spinnaker pipeline from the given
// config
func (b *Builder) Pipeline() (*types.SpinnakerPipeline, error) {
sp := &types.SpinnakerPipeline{}

for _, trigger := range b.pipeline.Triggers {
Expand Down Expand Up @@ -64,6 +65,16 @@ func (b *Builder) MarshalJSON() ([]byte, error) {
sp.Stages = append(sp.Stages, s)
}

return sp, nil
}

// MarshalJSON implements json.Marshaller
func (b *Builder) MarshalJSON() ([]byte, error) {
sp, err := b.Pipeline()
if err != nil {
return nil, err
}

return json.Marshal(sp)
}

Expand Down
70 changes: 70 additions & 0 deletions pipeline/validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package pipeline

import (
"fmt"

multierror "github.com/hashicorp/go-multierror"
"github.com/namely/k8s-pipeliner/pipeline/builder"
"github.com/namely/k8s-pipeliner/pipeline/builder/types"
"github.com/namely/k8s-pipeliner/pipeline/config"
)

// Validator validates that a pipeline is valid
type Validator struct {
pipeline *config.Pipeline
}

// NewValidator initializes a validator object
func NewValidator(p *config.Pipeline) *Validator {
return &Validator{pipeline: p}
}

// Validate performs some validations on the pipeline configuration
// to see if it passes some simple standards such as "do deploys have resources allocated"
func (v *Validator) Validate() error {
b := builder.New(v.pipeline)
sp, err := b.Pipeline()
if err != nil {
return err
}

var errs *multierror.Error
for _, stage := range sp.Stages {
switch s := stage.(type) {
case *types.DeployStage:
errs = multierror.Append(validateDeployStage(s))
}
}

return errs
}

func validateDeployStage(s *types.DeployStage) error {
var errs *multierror.Error

for _, cluster := range s.Clusters {
for _, container := range cluster.Containers {
if container.Requests.CPU == "0" {
err := fmt.Errorf("Stage: %s, Container: %s - Missing CPU on Resource Requests", s.Name, container.Name)
errs = multierror.Append(err)
}

if container.Requests.Memory == "0" {
err := fmt.Errorf("Stage: %s, Container: %s - Missing Memory on Resource Requests", s.Name, container.Name)
errs = multierror.Append(err)
}

if container.Limits.CPU == "0" {
err := fmt.Errorf("Stage: %s, Container: %s - Missing CPU on Resource Limits", s.Name, container.Name)
errs = multierror.Append(err)
}

if container.Limits.Memory == "0" {
err := fmt.Errorf("Stage: %s, Container: %s - Missing Memory on Resource Limits", s.Name, container.Name)
errs = multierror.Append(err)
}
}
}

return errs
}
2 changes: 1 addition & 1 deletion test-deployment.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: extensions/v1beta2
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: example
Expand Down

0 comments on commit 35b7f50

Please sign in to comment.