Skip to content

Commit

Permalink
Merge pull request #32 from gerald1248/add_route_conflict
Browse files Browse the repository at this point in the history
identify route conflicts
  • Loading branch information
gerald1248 authored Feb 9, 2017
2 parents 40a055e + 7471ddf commit e2bf00c
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 15 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ $ ./openshift-linter list
|image pull policy |policy 'Always' or ':latest' image specified |
|limits |resource limits missing, incomplete or invalid |
|name invalid |namespace, name or container doesn't match predefined regex|
|route conflict |route has more than one name |
|security |privileged security context |
```

Expand Down
12 changes: 6 additions & 6 deletions bindata.go

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ gulp.task('clean-build', function() {
], { force: true });
});

gulp.task('clean-package', function() {
return del.sync(['./package/*'], { force: true });
});

gulp.task('build-bindata', function(callback) {
exec('go-bindata static/...', function(err, stdout, stderr) {
console.log(stdout);
Expand All @@ -172,6 +176,7 @@ gulp.task('build-win32', function(callback) {
'build-html',
'build-bindata',
'build-go-win32',
'clean-package',
'package-binary',
'package-snakeoil',
'dist',
Expand All @@ -190,6 +195,7 @@ gulp.task('build-linux', function(callback) {
'build-html',
'build-bindata',
'build-go-linux-x64',
'clean-package',
'package-binary',
'package-snakeoil',
'dist',
Expand Down
52 changes: 52 additions & 0 deletions item-route-conflict.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package main

import "fmt"

type ItemRouteConflict struct {
name, description, kind string
}

func (irc *ItemRouteConflict) Name() string {
return irc.name
}

func (irc *ItemRouteConflict) Description() string {
return irc.description
}

func (irc *ItemRouteConflict) Kind() string {
return irc.kind
}

func (irc *ItemRouteConflict) Lint(config *Config, params LinterParams) (ResultMap, error) {
resultRouteConflict := make(ResultMap)

//populate map with key spec.host and value metadata.name
//only one route (metadata.name) should resolve to a given FQDN stored in spec.host
routeMap := make(map[string]string)

var key, value string
for _, item := range config.Items {
if item.Kind != irc.Kind() {
continue
}

if item.Metadata != nil && item.Spec != nil {
//skip if host or targetPort field not present
if item.Spec.Host == "" || item.Spec.Port == nil || item.Spec.Port.TargetPort == 0 {
continue
}

key = fmt.Sprintf("%s:%d", item.Spec.Host, item.Spec.Port.TargetPort)
value = item.Metadata.Name

if len(routeMap[key]) > 0 && routeMap[key] != value {
problem := fmt.Sprintf("'%s' and '%s' both name route to '%s'", routeMap[key], value, key)
resultRouteConflict[problem] = append(resultRouteConflict[problem], ContainerSpec{"", "", ""})
} else {
routeMap[key] = value
}
}
}
return resultRouteConflict, nil
}
4 changes: 2 additions & 2 deletions items.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ func Items() []LinterItem {
&ItemHealth{"health", "health check missing or incomplete", "DeploymentConfig"},
&ItemImagePullPolicy{"image pull policy", "policy 'Always' or ':latest' image specified", "DeploymentConfig"},
&ItemLimits{"limits", "resource limits missing, incomplete or invalid", "DeploymentConfig"},
&ItemSecurity{"security", "privileged security context", "DeploymentConfig"}}

&ItemSecurity{"security", "privileged security context", "DeploymentConfig"},
&ItemRouteConflict{"route conflict", "route has more than one name", "Route"}}
return items
}

Expand Down
3 changes: 1 addition & 2 deletions makelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ func makeList(a *[]byte) error {
}

switch obj.Kind {
case "List":
case "List", "Template":
return nil
case "BuildConfig", "DeploymentConfig", "Pod", "Route":
slices := [][]byte{[]byte(`{"kind":"List","items":[`), *a, []byte(`]}`)}
b := bytes.Join(slices, []byte{})
*a = b
fmt.Printf("%s\n", string(*a))
return nil
}
return errors.New(fmt.Sprintf("can't parse JSON: no configuration object found"))
Expand Down
6 changes: 6 additions & 0 deletions markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ func table(s ContainerSet, b *bytes.Buffer) {
//header row
rows[0] = []string{"Namespace", "Name", "Container"}

//special case: one empty spec
if count == 1 && s[0].Namespace == "" && s[0].Name == "" && s[0].Container == "" {
//exit without writing to buffer
return
}

//content rows
for i := 0; i < count; i++ {
spec := s[i]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openshift-linter",
"version": "0.2.0",
"version": "0.2.1",
"description": "basic linter for OpenShift configuration objects",
"main": "openshift-linter.go",
"scripts": {
Expand Down
6 changes: 6 additions & 0 deletions process.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ func processBytes(bytes []byte, params LinterParams) (CombinedResultMap, error)
return nil, errors.New(fmt.Sprintf("can't unmarshal data: %v", err))
}

//objects of type "Template" have "objects" not "items"
//standardize on "items"
if len(config.Objects) > 0 && len(config.Items) == 0 {
config.Items = config.Objects //copy pointer
}

//try to guess namespace from configurable metadata field
preprocessConfig(&config, params)

Expand Down
7 changes: 6 additions & 1 deletion src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,12 @@ var App = function() {
continue;
}
plural = (len === 1) ? "" : "s"
buffer += "<h3>" + key + ": " + subkey + " (" + len + " item" + plural + ")</h3>";
buffer += "<h3>" + key + ": " + subkey + " (" + len + " item" + plural + ")</h3>";

//special case: skip table when only one blank container spec given
if (len === 1 && list[0].Namespace === "" && list[0].Name === "" && list[0].Container === "") {
continue;
}
buffer += "<table class='table table-striped'>";
buffer += "<thead class='thead-default'><tr><th>Namespace</th><th>Name</th><th>Container</th></tr></thead>";
for (var i = 0; i < len; i++) {
Expand Down
2 changes: 1 addition & 1 deletion static/js/bundle-min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions static/js/bundle.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type LinterItem interface {
type Config struct {
Kind string `json:"kind"`
Items []*Item `json:"items"`
Objects []*Item `json:"objects"`
CustomNamespaceLabel string `json:"customNamespaceLabel"`
CustomNamespacePattern string `json:"customNamespacePattern"`
CustomNamePattern string `json:"customNamePattern"`
Expand All @@ -35,9 +36,14 @@ type Metadata struct {
}

type Spec struct {
//DeploymentConfig
Volumes []interface{} `json:"volumes"`
Containers []*Container `json:"containers"`
Template *Item `json:"template"` //nested item with its own Metadata and Spec sections

//Route
Host string `json:"host"`
Port *Port `json:"port"`
}

type Container struct {
Expand Down Expand Up @@ -88,6 +94,10 @@ type ResourceConstraint struct {
Memory string `json:"memory"`
}

type Port struct {
TargetPort int `json:"targetPort"`
}

func (r *ResourceConstraint) Complete() bool {
return len(r.CPU) > 0 && len(r.Memory) > 0
}
Expand Down

0 comments on commit e2bf00c

Please sign in to comment.