-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from kumaya/patch
create atlas_patch go utility
- Loading branch information
Showing
13 changed files
with
2,557 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
PROJECT_ROOT ?= $(PWD) | ||
GO_PACKAGES ?= $(shell go list ./... | grep -v vendor) | ||
GO_TEST_FLAGS ?= -v -cover | ||
|
||
.PHONY: fmt | ||
fmt: | ||
@go fmt $(GO_PACKAGES) | ||
|
||
.PHONY: test | ||
test: fmt | ||
@go test $(GO_TEST_FLAGS) $(GO_PACKAGES) | ||
|
||
.PHONY: vendor | ||
vendor: | ||
@go mod tidy | ||
@go mod vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package main | ||
|
||
import "github.com/spf13/pflag" | ||
|
||
var ( | ||
swaggerFiles = pflag.StringSlice("files", []string{}, "input swagger file location") | ||
withPrivate = pflag.Bool("with_private", false, "if unset, generate swagger schema without operations 0 as 'private' work only if atlas_patch set") | ||
withCustomAnnotations = pflag.Bool("with_custom_annotations", false, "if set, you became available to use custom annotations") | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"strings" | ||
|
||
"github.com/golang/glog" | ||
"github.com/infobloxopen/atlas-openapiv2-patch/internal/descriptor" | ||
genopenapi "github.com/infobloxopen/atlas-openapiv2-patch/pkg/svc" | ||
"github.com/spf13/pflag" | ||
) | ||
|
||
func run(reg *descriptor.Registry, swaggerFiles []string) error { | ||
for _, file := range swaggerFiles { | ||
fileName := file | ||
var f []byte | ||
var err error | ||
f, err = ioutil.ReadFile(file) | ||
if err != nil { | ||
return err | ||
} | ||
resp := genopenapi.AtlasSwagger(f, reg.IsWithPrivateOperations(), reg.IsWithCustomAnnotations()) | ||
|
||
if reg.IsWithPrivateOperations() { | ||
err = os.Remove(file) | ||
if err != nil { | ||
return err | ||
} | ||
fileName = strings.Replace(file, ".swagger.json", ".private.swagger.json", -1) | ||
} | ||
err = ioutil.WriteFile(fileName, []byte(resp), os.FileMode(0644)) | ||
if err != nil { | ||
return fmt.Errorf("unable to generate swagger definition") | ||
} | ||
glog.V(1).Infof("New OpenAPI file will emit") | ||
} | ||
return nil | ||
} | ||
|
||
func main() { | ||
pflag.Parse() | ||
reg := descriptor.NewRegistry() | ||
|
||
reg.SetPrivateOperations(*withPrivate) | ||
reg.SetCustomAnnotations(*withCustomAnnotations) | ||
glog.V(1).Info("Processing code generator request") | ||
|
||
if len(*swaggerFiles) == 0 { | ||
glog.Fatal("invalid swagger input files provided") | ||
} | ||
err := run(reg, *swaggerFiles) | ||
if err != nil { | ||
glog.Fatal(err) | ||
} | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"testing" | ||
|
||
"github.com/infobloxopen/atlas-openapiv2-patch/internal/descriptor" | ||
) | ||
|
||
const ( | ||
succeed = "\u2713" | ||
failed = "\u2717" | ||
red = "\033[31m" | ||
green = "\033[32m" | ||
yellow = "\033[33m" | ||
reset = "\033[0m" | ||
sampleSwaggerFile = "../../internal/testdata/atlaspatch.swagger.json" | ||
) | ||
|
||
func deepCompare(file1, file2 string) (bool, error) { | ||
const chunkSize = 64000 | ||
|
||
f1, err := os.Open(file1) | ||
if err != nil { | ||
return false, fmt.Errorf("cannot open %q file, error: %v", file1, err) | ||
} | ||
defer f1.Close() | ||
|
||
f2, err := os.Open(file2) | ||
if err != nil { | ||
return false, fmt.Errorf("cannot open %q file, error: %v", file2, err) | ||
} | ||
defer f2.Close() | ||
|
||
for { | ||
b1 := make([]byte, chunkSize) | ||
_, err1 := f1.Read(b1) | ||
|
||
b2 := make([]byte, chunkSize) | ||
_, err2 := f2.Read(b2) | ||
|
||
if err1 != nil || err2 != nil { | ||
if err1 == io.EOF && err2 == io.EOF { | ||
return true, nil | ||
} else if err1 == io.EOF || err2 == io.EOF { | ||
return false, nil | ||
} else { | ||
return false, fmt.Errorf("unexpected (not EOF) error "+ | ||
"when reading files (1, 2): %v, %v", err1, err2) | ||
} | ||
} | ||
|
||
if !bytes.Equal(b1, b2) { | ||
return false, nil | ||
} | ||
} | ||
} | ||
|
||
func createFiles(fileNames []string) error { | ||
for _, file := range fileNames { | ||
var f []byte | ||
f, err := ioutil.ReadFile(sampleSwaggerFile) | ||
if err != nil { | ||
return err | ||
} | ||
err = ioutil.WriteFile(file, f, os.FileMode(0666)) | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func deleteFiles(fileNames []string) error { | ||
for _, file := range fileNames { | ||
err := os.Remove(file) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func Test_run(t *testing.T) { | ||
type args struct { | ||
withPrivate bool | ||
withCustomAnnotations bool | ||
files []string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
wantErr bool | ||
wantFile string | ||
generatedFiles []string | ||
}{ | ||
{ | ||
name: "without custom flags", | ||
wantErr: false, | ||
args: args{ | ||
withPrivate: false, | ||
withCustomAnnotations: false, | ||
files: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"}, | ||
}, | ||
wantFile: "../../internal/testdata/atlaspatch.wanted.swagger.json", | ||
generatedFiles: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"}, | ||
}, | ||
{ | ||
name: "with custom annotation flag", | ||
wantErr: false, | ||
args: args{ | ||
withPrivate: false, | ||
withCustomAnnotations: true, | ||
files: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"}, | ||
}, | ||
wantFile: "../../internal/testdata/atlaspatch.wanted.swagger.json", | ||
generatedFiles: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"}, | ||
}, | ||
{ | ||
name: "with private flags", | ||
wantErr: false, | ||
args: args{ | ||
withPrivate: true, | ||
withCustomAnnotations: false, | ||
files: []string{"../../internal/testdata/atlaspatch.emitted.swagger.json"}, | ||
}, | ||
wantFile: "../../internal/testdata/atlaspatch.wanted.private.swagger.json", | ||
generatedFiles: []string{"../../internal/testdata/atlaspatch.emitted.private.swagger.json"}, | ||
}, | ||
} | ||
reg := descriptor.NewRegistry() | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
reg.SetPrivateOperations(tt.args.withPrivate) | ||
reg.SetCustomAnnotations(tt.args.withCustomAnnotations) | ||
err := createFiles(tt.args.files) | ||
defer deleteFiles(tt.generatedFiles) | ||
defer deleteFiles(tt.args.files) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
err = run(reg, tt.args.files) | ||
if err != nil { | ||
t.Errorf("unable to apply atlas patch, %v", err) | ||
return | ||
} | ||
|
||
isEqual, err := deepCompare(tt.generatedFiles[0], tt.wantFile) | ||
if err != nil { | ||
t.Errorf("Emitted vs wanted files content comparison error: %v", err) | ||
return | ||
} | ||
|
||
if !isEqual { | ||
t.Errorf("\t%s Emitted swagger JSON file is not equal to wanted one, compare with: "+ | ||
"\n"+yellow+" \n\ndiff %s %s\n\n "+reset, failed, tt.args.files, tt.wantFile) | ||
return | ||
} | ||
t.Logf("\t%s %s test is passed", succeed, tt.name) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module github.com/infobloxopen/atlas-openapiv2-patch | ||
|
||
go 1.16 | ||
|
||
require ( | ||
github.com/go-openapi/spec v0.20.4 | ||
github.com/golang/glog v1.0.0 | ||
github.com/spf13/pflag v1.0.5 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= | ||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= | ||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= | ||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= | ||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= | ||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= | ||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= | ||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= | ||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= | ||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= | ||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= | ||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= | ||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= | ||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= | ||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= | ||
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= | ||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= | ||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= | ||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= | ||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= | ||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= | ||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= | ||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= | ||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | ||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY= | ||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= | ||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= | ||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= | ||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= | ||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package descriptor | ||
|
||
import "fmt" | ||
|
||
type Registry struct { | ||
// privateOperations if true, respect private annotations and generate separate openapi files for private ops | ||
privateOperations bool | ||
|
||
// customAnnotations if true, allow custom annotations in the openapi spec | ||
customAnnotations bool | ||
} | ||
|
||
func NewRegistry() *Registry { | ||
return &Registry{ | ||
privateOperations: false, | ||
customAnnotations: false, | ||
} | ||
} | ||
|
||
// IsWithPrivateOperations whether private operations are enabled | ||
func (r *Registry) IsWithPrivateOperations() bool { | ||
return r.privateOperations | ||
} | ||
|
||
// SetPrivateOperations if true, respect private operation annotation | ||
func (r *Registry) SetPrivateOperations(private bool) { | ||
r.privateOperations = private | ||
} | ||
|
||
// IsWithCustomAnnotations whether custom annotations are used | ||
func (r *Registry) IsWithCustomAnnotations() bool { | ||
return r.customAnnotations | ||
} | ||
|
||
// SetCustomAnnotations if true, use atlas custom annotations | ||
func (r *Registry) SetCustomAnnotations(custom bool) { | ||
r.customAnnotations = custom | ||
} | ||
|
||
func (r *Registry) String() string { | ||
return ` | ||
privateOperations ` + fmt.Sprintf("%t", r.privateOperations) + ` | ||
customAnnotations ` + fmt.Sprintf("%t", r.customAnnotations) + ` | ||
` | ||
} |
Oops, something went wrong.