From a4ac0d7044a02a991bbbad986a5349cfaa1c0945 Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Thu, 2 Apr 2020 11:59:26 +0200 Subject: [PATCH] #1492 refactoring of go-utils (#148) * started cleanup and restructuring * moved sli handler functions * #1492 added api models * #1492 restructured packages * #1492 updated golang version in travis file * #1492 cleanup * #1492 fixed unit tests * #1492 added CreateProject and CreateService models * #1492 added CreateProject and CreateService models * #1492 added CreateServiceInStage function * #1492 added CreateConfigurationServiceProject function * #1492 fixed extraction of Keptn Context * #1492 set default protocol of helpers to http --- .travis.yml | 2 +- README.md | 9 + go.mod | 38 +- go.sum | 115 +---- pkg/api/models/contenttype.go | 19 - pkg/api/models/create_project.go | 89 ++++ pkg/api/models/create_service.go | 69 +++ pkg/api/models/data.go | 10 - pkg/api/models/error.go | 12 +- pkg/api/models/event.go | 179 -------- pkg/api/models/event_context.go | 5 +- pkg/api/models/events.go | 88 ++++ pkg/api/models/extensions.go | 10 - pkg/api/models/id.go | 19 - pkg/api/models/keptn_context_extended_c_e.go | 113 +++-- pkg/api/models/project.go | 53 +-- .../models/projects.go | 3 +- pkg/api/models/resource.go | 21 +- .../models/resources.go | 3 +- pkg/api/models/service.go | 34 +- .../models/services.go | 3 +- pkg/api/models/source.go | 19 - pkg/api/models/specversion.go | 19 - .../models/stage.go | 41 +- .../models/stages.go | 3 +- pkg/api/models/time.go | 60 --- pkg/api/models/type.go | 19 - .../models/version.go | 1 - pkg/api/utils/apiServiceUtils.go | 2 +- pkg/api/utils/authUtils.go | 13 +- pkg/api/utils/eventUtils.go | 15 +- pkg/api/utils/projectUtils.go | 27 +- pkg/api/utils/resourceUtils.go | 311 +++++++++++++- pkg/api/utils/serviceUtils.go | 87 +++- .../utils/stageUtils.go | 19 +- pkg/api/utils/xipIoResolver.go | 2 +- pkg/configuration-service/models/error.go | 67 --- pkg/configuration-service/models/project.go | 52 --- pkg/configuration-service/models/resource.go | 67 --- pkg/configuration-service/models/service.go | 43 -- .../utils/configServiceUtils.go | 92 ---- .../utils/projectUtils.go | 126 ------ .../utils/resourceUtils.go | 362 ---------------- .../utils/serviceUtils.go | 135 ------ pkg/configuration-service/utils/sliUtils.go | 84 ---- .../utils/sliUtils_test.go | 60 --- pkg/events/deployment_strategy_test.go | 14 - .../canaryAction.go => lib/canary_action.go} | 2 +- pkg/{utils => lib}/cmdUtils.go | 2 +- pkg/{utils => lib}/combined_logger.go | 2 +- .../utils/eventUtils.go => lib/datastore.go} | 24 +- .../datastore_test.go} | 13 +- .../deployment_strategy.go} | 2 +- pkg/{events/keptnEvents.go => lib/events.go} | 234 ++++++++++- pkg/lib/keptn.go | 288 +++++++++++++ pkg/lib/keptn_test.go | 392 ++++++++++++++++++ pkg/{utils => lib}/logger.go | 2 +- pkg/{models => lib}/remediations.go | 2 +- .../v2 => lib}/service_level_objectives.go | 2 +- pkg/{models => lib}/shipyard.go | 2 +- pkg/{utils => lib}/websocketutil.go | 2 +- pkg/models/service_indicators.go | 19 - pkg/models/service_objectives.go | 16 - pkg/mongodb-datastore/models/contenttype.go | 19 - pkg/mongodb-datastore/models/data.go | 10 - pkg/mongodb-datastore/models/error.go | 70 ---- pkg/mongodb-datastore/models/event.go | 179 -------- pkg/mongodb-datastore/models/events.go | 86 ---- pkg/mongodb-datastore/models/extensions.go | 10 - pkg/mongodb-datastore/models/id.go | 19 - .../models/keptn_context_extended_c_e.go | 102 ----- pkg/mongodb-datastore/models/log_entry.go | 83 ---- pkg/mongodb-datastore/models/source.go | 19 - pkg/mongodb-datastore/models/specversion.go | 19 - pkg/mongodb-datastore/models/time.go | 60 --- pkg/mongodb-datastore/models/type.go | 19 - pkg/mongodb-datastore/utils/datastoreUtils.go | 26 -- pkg/utils/fileUtils.go | 64 --- pkg/utils/gitHubUtils.go | 98 ----- pkg/utils/helmUtils.go | 187 --------- pkg/utils/keptnUtils.go | 66 --- pkg/utils/keptnUtils_test.go | 56 --- pkg/utils/kubeUtils.go | 243 ----------- swagger.yaml | 240 +++++++++++ 84 files changed, 2052 insertions(+), 3261 deletions(-) delete mode 100644 pkg/api/models/contenttype.go create mode 100644 pkg/api/models/create_project.go create mode 100644 pkg/api/models/create_service.go delete mode 100644 pkg/api/models/data.go delete mode 100644 pkg/api/models/event.go create mode 100644 pkg/api/models/events.go delete mode 100644 pkg/api/models/extensions.go delete mode 100644 pkg/api/models/id.go rename pkg/{configuration-service => api}/models/projects.go (99%) rename pkg/{configuration-service => api}/models/resources.go (99%) rename pkg/{configuration-service => api}/models/services.go (99%) delete mode 100644 pkg/api/models/source.go delete mode 100644 pkg/api/models/specversion.go rename pkg/{configuration-service => api}/models/stage.go (53%) rename pkg/{configuration-service => api}/models/stages.go (99%) delete mode 100644 pkg/api/models/time.go delete mode 100644 pkg/api/models/type.go rename pkg/{configuration-service => api}/models/version.go (99%) rename pkg/{configuration-service => api}/utils/stageUtils.go (88%) delete mode 100644 pkg/configuration-service/models/error.go delete mode 100644 pkg/configuration-service/models/project.go delete mode 100644 pkg/configuration-service/models/resource.go delete mode 100644 pkg/configuration-service/models/service.go delete mode 100644 pkg/configuration-service/utils/configServiceUtils.go delete mode 100644 pkg/configuration-service/utils/projectUtils.go delete mode 100644 pkg/configuration-service/utils/resourceUtils.go delete mode 100644 pkg/configuration-service/utils/serviceUtils.go delete mode 100644 pkg/configuration-service/utils/sliUtils.go delete mode 100644 pkg/configuration-service/utils/sliUtils_test.go delete mode 100644 pkg/events/deployment_strategy_test.go rename pkg/{events/canaryAction.go => lib/canary_action.go} (98%) rename pkg/{utils => lib}/cmdUtils.go (98%) rename pkg/{utils => lib}/combined_logger.go (99%) rename pkg/{mongodb-datastore/utils/eventUtils.go => lib/datastore.go} (82%) rename pkg/{mongodb-datastore/utils/eventUtils_test.go => lib/datastore_test.go} (94%) rename pkg/{events/deploymentStrategy.go => lib/deployment_strategy.go} (99%) rename pkg/{events/keptnEvents.go => lib/events.go} (65%) create mode 100644 pkg/lib/keptn.go create mode 100644 pkg/lib/keptn_test.go rename pkg/{utils => lib}/logger.go (99%) rename pkg/{models => lib}/remediations.go (97%) rename pkg/{models/v2 => lib}/service_level_objectives.go (99%) rename pkg/{models => lib}/shipyard.go (96%) rename pkg/{utils => lib}/websocketutil.go (99%) delete mode 100644 pkg/models/service_indicators.go delete mode 100644 pkg/models/service_objectives.go delete mode 100644 pkg/mongodb-datastore/models/contenttype.go delete mode 100644 pkg/mongodb-datastore/models/data.go delete mode 100644 pkg/mongodb-datastore/models/error.go delete mode 100644 pkg/mongodb-datastore/models/event.go delete mode 100644 pkg/mongodb-datastore/models/events.go delete mode 100644 pkg/mongodb-datastore/models/extensions.go delete mode 100644 pkg/mongodb-datastore/models/id.go delete mode 100644 pkg/mongodb-datastore/models/keptn_context_extended_c_e.go delete mode 100644 pkg/mongodb-datastore/models/log_entry.go delete mode 100644 pkg/mongodb-datastore/models/source.go delete mode 100644 pkg/mongodb-datastore/models/specversion.go delete mode 100644 pkg/mongodb-datastore/models/time.go delete mode 100644 pkg/mongodb-datastore/models/type.go delete mode 100644 pkg/mongodb-datastore/utils/datastoreUtils.go delete mode 100644 pkg/utils/fileUtils.go delete mode 100644 pkg/utils/gitHubUtils.go delete mode 100644 pkg/utils/helmUtils.go delete mode 100644 pkg/utils/keptnUtils.go delete mode 100644 pkg/utils/keptnUtils_test.go delete mode 100644 pkg/utils/kubeUtils.go create mode 100644 swagger.yaml diff --git a/.travis.yml b/.travis.yml index 6e6b498b..c285de78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: xenial language: go go: - - 1.12.x + - 1.13.x # Don't email me the results of the test runs. notifications: diff --git a/README.md b/README.md index f4660793..8e8e1bba 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,15 @@ import { ) ``` +## Updating model definitions +After updating the model definitions in the `swagger.yaml` file, execute the command + +``` +swagger generate model --spec=swagger.yaml -t=./pkg/api/ +``` + +to update the models located in `./pkg/api/models` + ## Automation Within [.travis.yml](.travis.yml) we have included an automation that creates a Pull Request to diff --git a/go.mod b/go.mod index 840bea6b..1dea67e1 100644 --- a/go.mod +++ b/go.mod @@ -1,50 +1,18 @@ module github.com/keptn/go-utils -go 1.12 +go 1.13 require ( - github.com/Azure/go-autorest/autorest v0.2.0 - github.com/Masterminds/goutils v1.1.0 // indirect - github.com/Masterminds/semver v1.5.0 // indirect - github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/cloudevents/sdk-go v0.10.0 - github.com/cyphar/filepath-securejoin v0.2.2 // indirect github.com/go-openapi/errors v0.19.2 github.com/go-openapi/strfmt v0.19.3 github.com/go-openapi/swag v0.19.5 github.com/go-openapi/validate v0.19.4 - github.com/gobwas/glob v0.2.3 // indirect - github.com/gogo/protobuf v1.3.1 // indirect + github.com/go-test/deep v1.0.5 + github.com/gogo/protobuf v1.2.0 // indirect github.com/google/uuid v1.1.1 - github.com/googleapis/gnostic v0.3.1 // indirect - github.com/gophercloud/gophercloud v0.6.0 // indirect github.com/gorilla/websocket v1.4.1 - github.com/huandu/xstrings v1.2.0 // indirect - github.com/imdario/mergo v0.3.8 // indirect - github.com/json-iterator/go v1.1.7 // indirect - github.com/magiconair/properties v1.8.1 - github.com/mitchellh/copystructure v1.0.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.4.0 - golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect golang.org/x/net v0.0.0-20191021144547-ec77196f6094 // indirect - golang.org/x/time v0.0.0-20191023065245-6d3f0bb11be5 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/src-d/go-git.v4 v4.13.1 gopkg.in/yaml.v2 v2.2.4 - k8s.io/api v0.0.0-20190313235455-40a48860b5ab - k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1 - k8s.io/client-go v11.0.0+incompatible - k8s.io/helm v2.14.3+incompatible - k8s.io/klog v1.0.0 // indirect - k8s.io/utils v0.0.0-20191010214722-8d271d903fe4 // indirect - sigs.k8s.io/yaml v1.1.0 // indirect -) - -// using kubernetes-1.15.0 for api/apimachinery - -replace ( - k8s.io/api => k8s.io/api v0.0.0-20190313235455-40a48860b5ab - k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1 - k8s.io/client-go => k8s.io/client-go v11.0.0+incompatible ) diff --git a/go.sum b/go.sum index 8518522f..c11889ac 100644 --- a/go.sum +++ b/go.sum @@ -22,12 +22,6 @@ github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0Sub github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -35,14 +29,9 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/jsonschema v0.0.0-20191017121752-4bb6e3fae4f2 h1:swGeCLPiUQ647AIRnFxnAHdzlg6IPpmU6QdkOPZINt8= -github.com/alecthomas/jsonschema v0.0.0-20191017121752-4bb6e3fae4f2/go.mod h1:Juc2PrI3wtNfUwptSvAIeNx+HrETwHQs6nf+TkOJlOA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -52,9 +41,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudevents/sdk-go v0.10.0 h1:j/0Gwiyc0aamxaPx2aLsRhbGUcwIcE/lb5s00OOExfw= github.com/cloudevents/sdk-go v0.10.0/go.mod h1:PW8UwWI6tD2Ry5kFpZfV1qlrADFkfaDCZXLiJ1dC1Ks= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= 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= @@ -62,23 +48,17 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -129,35 +109,26 @@ github.com/go-openapi/validate v0.19.4 h1:LGjO87VyXY3bIKjlYpXSFuLRG2mTeuYlZyeNwF github.com/go-openapi/validate v0.19.4/go.mod h1:BkJ0ZmXui7yB0bJXWSXgLPNTmbLVeX/3D1xn/N9mMUM= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/go-test/deep v1.0.5 h1:AKODKU3pDH1RzZzm6YZu77YWtEAq6uh1rLIAQlay2qc= +github.com/go-test/deep v1.0.5/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= -github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/gophercloud/gophercloud v0.6.0 h1:Xb2lcqZtml1XjgYZxbeayEemq7ASbeTp09m36gQFpEU= -github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= @@ -168,49 +139,26 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= -github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 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/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.2.6/go.mod h1:mQxQ0uHQ9FhEVPIcTSKwx2lqZEpXWWcCgA7R6NrWvvY= github.com/nats-io/nats-server/v2 v2.0.0/go.mod h1:RyVdsHHvY4B6c9pWG+uRLpZ0h0XsqiuKp2XCTurP5LI= @@ -222,7 +170,6 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -241,25 +188,16 @@ github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -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/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= -github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1 h1:Sq1fR+0c58RME5EoqKdjkiQAmPjmfHlZOoRI6fTUOcs= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -268,20 +206,19 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -304,8 +241,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8= golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -326,24 +261,18 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e h1:D5TXcfTk7xF7hvieo4QErS3qqCB4teTffacDWr7CI+0= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191023065245-6d3f0bb11be5 h1:KvJW0HDFZT3ZQ2kTXZ0xHbHm2BMbdJV4ff3petXiuxI= -golang.org/x/time v0.0.0-20191023065245-6d3f0bb11be5/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -351,7 +280,6 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.6.0 h1:2tJEkRfnZL5g1GeBUlITh/rqT5HG3sFcoVCUUxmgJ2g= @@ -373,19 +301,11 @@ google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= -gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= -gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= -gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= -gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -395,20 +315,5 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.0.0-20190313235455-40a48860b5ab h1:DG9A67baNpoeweOy2spF1OWHhnVY5KR7/Ek/+U1lVZc= -k8s.io/api v0.0.0-20190313235455-40a48860b5ab/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1 h1:IS7K02iBkQXpCeieSiyJjGoLSdVOv2DbPaWHJ+ZtgKg= -k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= -k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= -k8s.io/helm v2.14.3+incompatible h1:uzotTcZXa/b2SWVoUzM1xiCXVjI38TuxMujS/1s+3Gw= -k8s.io/helm v2.14.3+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/utils v0.0.0-20191010214722-8d271d903fe4 h1:Gi+/O1saihwDqnlmC8Vhv1M5Sp4+rbOmK9TbsLn8ZEA= -k8s.io/utils v0.0.0-20191010214722-8d271d903fe4/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= pack.ag/amqp v0.11.0/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/pkg/api/models/contenttype.go b/pkg/api/models/contenttype.go deleted file mode 100644 index 1ab19ad2..00000000 --- a/pkg/api/models/contenttype.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Contenttype contenttype -// swagger:model contenttype -type Contenttype string - -// Validate validates this contenttype -func (m Contenttype) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/api/models/create_project.go b/pkg/api/models/create_project.go new file mode 100644 index 00000000..4f3a5ff3 --- /dev/null +++ b/pkg/api/models/create_project.go @@ -0,0 +1,89 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// CreateProject create project +// swagger:model CreateProject +type CreateProject struct { + + // git remote URL + GitRemoteURL string `json:"gitRemoteURL,omitempty"` + + // git token + GitToken string `json:"gitToken,omitempty"` + + // git user + GitUser string `json:"gitUser,omitempty"` + + // name + // Required: true + Name *string `json:"name"` + + // shipyard + // Required: true + Shipyard *string `json:"shipyard"` +} + +// Validate validates this create project +func (m *CreateProject) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateName(formats); err != nil { + res = append(res, err) + } + + if err := m.validateShipyard(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CreateProject) validateName(formats strfmt.Registry) error { + + if err := validate.Required("name", "body", m.Name); err != nil { + return err + } + + return nil +} + +func (m *CreateProject) validateShipyard(formats strfmt.Registry) error { + + if err := validate.Required("shipyard", "body", m.Shipyard); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *CreateProject) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *CreateProject) UnmarshalBinary(b []byte) error { + var res CreateProject + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/api/models/create_service.go b/pkg/api/models/create_service.go new file mode 100644 index 00000000..52300381 --- /dev/null +++ b/pkg/api/models/create_service.go @@ -0,0 +1,69 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// CreateService create service +// swagger:model CreateService +type CreateService struct { + + // deployment strategies + DeploymentStrategies map[string]string `json:"deploymentStrategies,omitempty"` + + // helm chart + HelmChart string `json:"helmChart,omitempty"` + + // service name + // Required: true + ServiceName *string `json:"serviceName"` +} + +// Validate validates this create service +func (m *CreateService) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateServiceName(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CreateService) validateServiceName(formats strfmt.Registry) error { + + if err := validate.Required("serviceName", "body", m.ServiceName); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *CreateService) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *CreateService) UnmarshalBinary(b []byte) error { + var res CreateService + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/api/models/data.go b/pkg/api/models/data.go deleted file mode 100644 index 3c7d4098..00000000 --- a/pkg/api/models/data.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -// Data data -// swagger:model data -type Data interface{} diff --git a/pkg/api/models/error.go b/pkg/api/models/error.go index 9a60acf0..6fc2afad 100644 --- a/pkg/api/models/error.go +++ b/pkg/api/models/error.go @@ -6,24 +6,20 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Error error -// swagger:model error +// swagger:model Error type Error struct { - // code + // Error code Code int64 `json:"code,omitempty"` - // fields - Fields string `json:"fields,omitempty"` - - // message + // Error message // Required: true Message *string `json:"message"` } diff --git a/pkg/api/models/event.go b/pkg/api/models/event.go deleted file mode 100644 index 85d36c48..00000000 --- a/pkg/api/models/event.go +++ /dev/null @@ -1,179 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" -) - -// Event event -// swagger:model event -type Event struct { - - // contenttype - Contenttype Contenttype `json:"contenttype,omitempty"` - - // data - Data Data `json:"data,omitempty"` - - // extensions - Extensions Extensions `json:"extensions,omitempty"` - - // id - // Required: true - ID ID `json:"id"` - - // source - // Required: true - Source Source `json:"source"` - - // specversion - // Required: true - Specversion Specversion `json:"specversion"` - - // time - // Format: date-time - Time Time `json:"time,omitempty"` - - // type - // Required: true - Type Type `json:"type"` -} - -// Validate validates this event -func (m *Event) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateContenttype(formats); err != nil { - res = append(res, err) - } - - if err := m.validateID(formats); err != nil { - res = append(res, err) - } - - if err := m.validateSource(formats); err != nil { - res = append(res, err) - } - - if err := m.validateSpecversion(formats); err != nil { - res = append(res, err) - } - - if err := m.validateTime(formats); err != nil { - res = append(res, err) - } - - if err := m.validateType(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *Event) validateContenttype(formats strfmt.Registry) error { - - if swag.IsZero(m.Contenttype) { // not required - return nil - } - - if err := m.Contenttype.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("contenttype") - } - return err - } - - return nil -} - -func (m *Event) validateID(formats strfmt.Registry) error { - - if err := m.ID.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("id") - } - return err - } - - return nil -} - -func (m *Event) validateSource(formats strfmt.Registry) error { - - if err := m.Source.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("source") - } - return err - } - - return nil -} - -func (m *Event) validateSpecversion(formats strfmt.Registry) error { - - if err := m.Specversion.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("specversion") - } - return err - } - - return nil -} - -func (m *Event) validateTime(formats strfmt.Registry) error { - - if swag.IsZero(m.Time) { // not required - return nil - } - - if err := m.Time.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("time") - } - return err - } - - return nil -} - -func (m *Event) validateType(formats strfmt.Registry) error { - - if err := m.Type.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("type") - } - return err - } - - return nil -} - -// MarshalBinary interface implementation -func (m *Event) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Event) UnmarshalBinary(b []byte) error { - var res Event - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/api/models/event_context.go b/pkg/api/models/event_context.go index aa89af1a..95aea18f 100644 --- a/pkg/api/models/event_context.go +++ b/pkg/api/models/event_context.go @@ -6,15 +6,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // EventContext event context -// swagger:model eventContext +// swagger:model EventContext type EventContext struct { // keptn context diff --git a/pkg/api/models/events.go b/pkg/api/models/events.go new file mode 100644 index 00000000..842ed919 --- /dev/null +++ b/pkg/api/models/events.go @@ -0,0 +1,88 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "strconv" + + "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// Events events +// swagger:model Events +type Events struct { + + // events + Events []*KeptnContextExtendedCE `json:"events"` + + // Pointer to next page, base64 encoded + NextPageKey string `json:"nextPageKey,omitempty"` + + // Size of returned page + PageSize float64 `json:"pageSize,omitempty"` + + // Total number of resources + TotalCount float64 `json:"totalCount,omitempty"` +} + +// Validate validates this events +func (m *Events) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateEvents(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Events) validateEvents(formats strfmt.Registry) error { + + if swag.IsZero(m.Events) { // not required + return nil + } + + for i := 0; i < len(m.Events); i++ { + if swag.IsZero(m.Events[i]) { // not required + continue + } + + if m.Events[i] != nil { + if err := m.Events[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("events" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *Events) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Events) UnmarshalBinary(b []byte) error { + var res Events + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/api/models/extensions.go b/pkg/api/models/extensions.go deleted file mode 100644 index d098318b..00000000 --- a/pkg/api/models/extensions.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -// Extensions extensions -// swagger:model extensions -type Extensions interface{} diff --git a/pkg/api/models/id.go b/pkg/api/models/id.go deleted file mode 100644 index 7ff8ceed..00000000 --- a/pkg/api/models/id.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// ID id -// swagger:model id -type ID string - -// Validate validates this id -func (m ID) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/api/models/keptn_context_extended_c_e.go b/pkg/api/models/keptn_context_extended_c_e.go index cc8a9662..784449ec 100644 --- a/pkg/api/models/keptn_context_extended_c_e.go +++ b/pkg/api/models/keptn_context_extended_c_e.go @@ -6,80 +6,111 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" + "github.com/go-openapi/validate" ) // KeptnContextExtendedCE keptn context extended c e -// swagger:model keptnContextExtendedCE +// swagger:model KeptnContextExtendedCE type KeptnContextExtendedCE struct { - Event + + // contenttype + Contenttype string `json:"contenttype,omitempty"` + + // data + // Required: true + Data interface{} `json:"data"` + + // extensions + Extensions interface{} `json:"extensions,omitempty"` + + // id + ID string `json:"id,omitempty"` // shkeptncontext Shkeptncontext string `json:"shkeptncontext,omitempty"` + + // source + // Required: true + Source *string `json:"source"` + + // specversion + Specversion string `json:"specversion,omitempty"` + + // time + // Format: date-time + Time strfmt.DateTime `json:"time,omitempty"` + + // type + // Required: true + Type *string `json:"type"` } -// UnmarshalJSON unmarshals this object from a JSON structure -func (m *KeptnContextExtendedCE) UnmarshalJSON(raw []byte) error { - // AO0 - var aO0 Event - if err := swag.ReadJSON(raw, &aO0); err != nil { - return err +// Validate validates this keptn context extended c e +func (m *KeptnContextExtendedCE) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateData(formats); err != nil { + res = append(res, err) } - m.Event = aO0 - // AO1 - var dataAO1 struct { - Shkeptncontext string `json:"shkeptncontext,omitempty"` + if err := m.validateSource(formats); err != nil { + res = append(res, err) } - if err := swag.ReadJSON(raw, &dataAO1); err != nil { - return err + + if err := m.validateTime(formats); err != nil { + res = append(res, err) } - m.Shkeptncontext = dataAO1.Shkeptncontext + if err := m.validateType(formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } return nil } -// MarshalJSON marshals this object to a JSON structure -func (m KeptnContextExtendedCE) MarshalJSON() ([]byte, error) { - _parts := make([][]byte, 0, 2) +func (m *KeptnContextExtendedCE) validateData(formats strfmt.Registry) error { - aO0, err := swag.WriteJSON(m.Event) - if err != nil { - return nil, err + if err := validate.Required("data", "body", m.Data); err != nil { + return err } - _parts = append(_parts, aO0) - var dataAO1 struct { - Shkeptncontext string `json:"shkeptncontext,omitempty"` - } + return nil +} - dataAO1.Shkeptncontext = m.Shkeptncontext +func (m *KeptnContextExtendedCE) validateSource(formats strfmt.Registry) error { - jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1) - if errAO1 != nil { - return nil, errAO1 + if err := validate.Required("source", "body", m.Source); err != nil { + return err } - _parts = append(_parts, jsonDataAO1) - return swag.ConcatJSON(_parts...), nil + return nil } -// Validate validates this keptn context extended c e -func (m *KeptnContextExtendedCE) Validate(formats strfmt.Registry) error { - var res []error +func (m *KeptnContextExtendedCE) validateTime(formats strfmt.Registry) error { - // validation for a type composition with Event - if err := m.Event.Validate(formats); err != nil { - res = append(res, err) + if swag.IsZero(m.Time) { // not required + return nil } - if len(res) > 0 { - return errors.CompositeValidationError(res...) + if err := validate.FormatOf("time", "body", "date-time", m.Time.String(), formats); err != nil { + return err } + + return nil +} + +func (m *KeptnContextExtendedCE) validateType(formats strfmt.Registry) error { + + if err := validate.Required("type", "body", m.Type); err != nil { + return err + } + return nil } diff --git a/pkg/api/models/project.go b/pkg/api/models/project.go index b9ff2b39..78b040db 100644 --- a/pkg/api/models/project.go +++ b/pkg/api/models/project.go @@ -6,44 +6,38 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" + "strconv" "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "github.com/go-openapi/validate" ) // Project project -// swagger:model project +// swagger:model Project type Project struct { - // git remote URL - GitRemoteURL string `json:"gitRemoteURL,omitempty"` + // Git remote URI + GitRemoteURI string `json:"gitRemoteURI,omitempty"` - // git token + // Git token GitToken string `json:"gitToken,omitempty"` - // git user + // Git User GitUser string `json:"gitUser,omitempty"` - // name - // Required: true - Name *string `json:"name"` + // Project name + ProjectName string `json:"projectName,omitempty"` - // shipyard - // Required: true - Shipyard *string `json:"shipyard"` + // stages + Stages []*Stage `json:"stages"` } // Validate validates this project func (m *Project) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateName(formats); err != nil { - res = append(res, err) - } - - if err := m.validateShipyard(formats); err != nil { + if err := m.validateStages(formats); err != nil { res = append(res, err) } @@ -53,19 +47,26 @@ func (m *Project) Validate(formats strfmt.Registry) error { return nil } -func (m *Project) validateName(formats strfmt.Registry) error { +func (m *Project) validateStages(formats strfmt.Registry) error { - if err := validate.Required("name", "body", m.Name); err != nil { - return err + if swag.IsZero(m.Stages) { // not required + return nil } - return nil -} + for i := 0; i < len(m.Stages); i++ { + if swag.IsZero(m.Stages[i]) { // not required + continue + } -func (m *Project) validateShipyard(formats strfmt.Registry) error { + if m.Stages[i] != nil { + if err := m.Stages[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("stages" + "." + strconv.Itoa(i)) + } + return err + } + } - if err := validate.Required("shipyard", "body", m.Shipyard); err != nil { - return err } return nil diff --git a/pkg/configuration-service/models/projects.go b/pkg/api/models/projects.go similarity index 99% rename from pkg/configuration-service/models/projects.go rename to pkg/api/models/projects.go index 53187d89..2fd7f960 100644 --- a/pkg/configuration-service/models/projects.go +++ b/pkg/api/models/projects.go @@ -8,9 +8,8 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) diff --git a/pkg/api/models/resource.go b/pkg/api/models/resource.go index 0402c339..7f3a1f2d 100644 --- a/pkg/api/models/resource.go +++ b/pkg/api/models/resource.go @@ -6,20 +6,18 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Resource resource -// swagger:model resource +// swagger:model Resource type Resource struct { // Resource content - // Required: true - ResourceContent *string `json:"resourceContent"` + ResourceContent string `json:"resourceContent,omitempty"` // Resource URI // Required: true @@ -30,10 +28,6 @@ type Resource struct { func (m *Resource) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateResourceContent(formats); err != nil { - res = append(res, err) - } - if err := m.validateResourceURI(formats); err != nil { res = append(res, err) } @@ -44,15 +38,6 @@ func (m *Resource) Validate(formats strfmt.Registry) error { return nil } -func (m *Resource) validateResourceContent(formats strfmt.Registry) error { - - if err := validate.Required("resourceContent", "body", m.ResourceContent); err != nil { - return err - } - - return nil -} - func (m *Resource) validateResourceURI(formats strfmt.Registry) error { if err := validate.Required("resourceURI", "body", m.ResourceURI); err != nil { diff --git a/pkg/configuration-service/models/resources.go b/pkg/api/models/resources.go similarity index 99% rename from pkg/configuration-service/models/resources.go rename to pkg/api/models/resources.go index a9f6768b..b8605bc6 100644 --- a/pkg/configuration-service/models/resources.go +++ b/pkg/api/models/resources.go @@ -8,9 +8,8 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) diff --git a/pkg/api/models/service.go b/pkg/api/models/service.go index a795c3f4..ad475327 100644 --- a/pkg/api/models/service.go +++ b/pkg/api/models/service.go @@ -7,47 +7,19 @@ package models import ( strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" "github.com/go-openapi/swag" - "github.com/go-openapi/validate" ) // Service service -// swagger:model service +// swagger:model Service type Service struct { - // deployment strategies - DeploymentStrategies map[string]string `json:"deploymentStrategies,omitempty"` - - // helm chart - HelmChart string `json:"helmChart,omitempty"` - - // service name - // Required: true - ServiceName *string `json:"serviceName"` + // Service name + ServiceName string `json:"serviceName,omitempty"` } // Validate validates this service func (m *Service) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateServiceName(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *Service) validateServiceName(formats strfmt.Registry) error { - - if err := validate.Required("serviceName", "body", m.ServiceName); err != nil { - return err - } - return nil } diff --git a/pkg/configuration-service/models/services.go b/pkg/api/models/services.go similarity index 99% rename from pkg/configuration-service/models/services.go rename to pkg/api/models/services.go index 8c2862f4..09c2b52c 100644 --- a/pkg/configuration-service/models/services.go +++ b/pkg/api/models/services.go @@ -8,9 +8,8 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) diff --git a/pkg/api/models/source.go b/pkg/api/models/source.go deleted file mode 100644 index 9ef1769a..00000000 --- a/pkg/api/models/source.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Source source -// swagger:model source -type Source string - -// Validate validates this source -func (m Source) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/api/models/specversion.go b/pkg/api/models/specversion.go deleted file mode 100644 index 5dea0caf..00000000 --- a/pkg/api/models/specversion.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Specversion specversion -// swagger:model specversion -type Specversion string - -// Validate validates this specversion -func (m Specversion) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/configuration-service/models/stage.go b/pkg/api/models/stage.go similarity index 53% rename from pkg/configuration-service/models/stage.go rename to pkg/api/models/stage.go index 2f2869f0..d7872aa9 100644 --- a/pkg/configuration-service/models/stage.go +++ b/pkg/api/models/stage.go @@ -6,8 +6,10 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" + "strconv" + "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) @@ -15,12 +17,49 @@ import ( // swagger:model Stage type Stage struct { + // services + Services []*Service `json:"services"` + // Stage name StageName string `json:"stageName,omitempty"` } // Validate validates this stage func (m *Stage) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateServices(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Stage) validateServices(formats strfmt.Registry) error { + + if swag.IsZero(m.Services) { // not required + return nil + } + + for i := 0; i < len(m.Services); i++ { + if swag.IsZero(m.Services[i]) { // not required + continue + } + + if m.Services[i] != nil { + if err := m.Services[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("services" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + return nil } diff --git a/pkg/configuration-service/models/stages.go b/pkg/api/models/stages.go similarity index 99% rename from pkg/configuration-service/models/stages.go rename to pkg/api/models/stages.go index 88e451ab..dbaf2db4 100644 --- a/pkg/configuration-service/models/stages.go +++ b/pkg/api/models/stages.go @@ -8,9 +8,8 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + strfmt "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) diff --git a/pkg/api/models/time.go b/pkg/api/models/time.go deleted file mode 100644 index fbc3e48d..00000000 --- a/pkg/api/models/time.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// Time time -// swagger:model time -type Time strfmt.DateTime - -// UnmarshalJSON sets a Time value from JSON input -func (m *Time) UnmarshalJSON(b []byte) error { - return ((*strfmt.DateTime)(m)).UnmarshalJSON(b) -} - -// MarshalJSON retrieves a Time value as JSON output -func (m Time) MarshalJSON() ([]byte, error) { - return (strfmt.DateTime(m)).MarshalJSON() -} - -// Validate validates this time -func (m Time) Validate(formats strfmt.Registry) error { - var res []error - - if err := validate.FormatOf("", "body", "date-time", strfmt.DateTime(m).String(), formats); err != nil { - return err - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -// MarshalBinary interface implementation -func (m *Time) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Time) UnmarshalBinary(b []byte) error { - var res Time - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/api/models/type.go b/pkg/api/models/type.go deleted file mode 100644 index 80ec79f8..00000000 --- a/pkg/api/models/type.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Type type -// swagger:model type -type Type string - -// Validate validates this type -func (m Type) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/configuration-service/models/version.go b/pkg/api/models/version.go similarity index 99% rename from pkg/configuration-service/models/version.go rename to pkg/api/models/version.go index 9a3e0e61..48bb434f 100644 --- a/pkg/configuration-service/models/version.go +++ b/pkg/api/models/version.go @@ -7,7 +7,6 @@ package models import ( strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" ) diff --git a/pkg/api/utils/apiServiceUtils.go b/pkg/api/utils/apiServiceUtils.go index 4acb2311..483571cf 100644 --- a/pkg/api/utils/apiServiceUtils.go +++ b/pkg/api/utils/apiServiceUtils.go @@ -1,4 +1,4 @@ -package utils +package api import ( "bytes" diff --git a/pkg/api/utils/authUtils.go b/pkg/api/utils/authUtils.go index cc05f9b8..52b25605 100644 --- a/pkg/api/utils/authUtils.go +++ b/pkg/api/utils/authUtils.go @@ -1,4 +1,4 @@ -package utils +package api import ( "net/http" @@ -18,14 +18,19 @@ type AuthHandler struct { // NewAuthHandler returns a new AuthHandler func NewAuthHandler(baseURL string) *AuthHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") + scheme := "http" + if strings.Contains(baseURL, "https://") { + baseURL = strings.TrimPrefix(baseURL, "https://") + } else if strings.Contains(baseURL, "http://") { + baseURL = strings.TrimPrefix(baseURL, "http://") + scheme = "http" + } return &AuthHandler{ BaseURL: baseURL, AuthHeader: "", AuthToken: "", HTTPClient: &http.Client{Transport: getClientTransport()}, - Scheme: "https", + Scheme: scheme, } } diff --git a/pkg/api/utils/eventUtils.go b/pkg/api/utils/eventUtils.go index 1315f0d7..516f85d8 100644 --- a/pkg/api/utils/eventUtils.go +++ b/pkg/api/utils/eventUtils.go @@ -1,4 +1,4 @@ -package utils +package api import ( "encoding/json" @@ -20,14 +20,19 @@ type EventHandler struct { // NewEventHandler returns a new EventHandler func NewEventHandler(baseURL string) *EventHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") + scheme := "http" + if strings.Contains(baseURL, "https://") { + baseURL = strings.TrimPrefix(baseURL, "https://") + } else if strings.Contains(baseURL, "http://") { + baseURL = strings.TrimPrefix(baseURL, "http://") + scheme = "http" + } return &EventHandler{ BaseURL: baseURL, AuthHeader: "", AuthToken: "", HTTPClient: &http.Client{Transport: getClientTransport()}, - Scheme: "https", + Scheme: scheme, } } @@ -66,7 +71,7 @@ func (e *EventHandler) getHTTPClient() *http.Client { } // SendEvent sends an event to Keptn -func (e *EventHandler) SendEvent(event models.Event) (*models.EventContext, *models.Error) { +func (e *EventHandler) SendEvent(event models.KeptnContextExtendedCE) (*models.EventContext, *models.Error) { bodyStr, err := json.Marshal(event) if err != nil { return nil, buildErrorResponse(err.Error()) diff --git a/pkg/api/utils/projectUtils.go b/pkg/api/utils/projectUtils.go index dbcf6f67..3a78df08 100644 --- a/pkg/api/utils/projectUtils.go +++ b/pkg/api/utils/projectUtils.go @@ -1,4 +1,4 @@ -package utils +package api import ( "encoding/json" @@ -20,14 +20,19 @@ type ProjectHandler struct { // NewProjectHandler returns a new ProjectHandler func NewProjectHandler(baseURL string) *ProjectHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") + scheme := "http" + if strings.Contains(baseURL, "https://") { + baseURL = strings.TrimPrefix(baseURL, "https://") + } else if strings.Contains(baseURL, "http://") { + baseURL = strings.TrimPrefix(baseURL, "http://") + scheme = "http" + } return &ProjectHandler{ BaseURL: baseURL, AuthHeader: "", AuthToken: "", HTTPClient: &http.Client{Transport: getClientTransport()}, - Scheme: "https", + Scheme: scheme, } } @@ -66,7 +71,15 @@ func (p *ProjectHandler) getHTTPClient() *http.Client { } // CreateProject creates a new project -func (p *ProjectHandler) CreateProject(project models.Project) (*models.EventContext, *models.Error) { +func (p *ProjectHandler) CreateProject(project models.CreateProject) (*models.EventContext, *models.Error) { + bodyStr, err := json.Marshal(project) + if err != nil { + return nil, buildErrorResponse(err.Error()) + } + return post(p.Scheme+"://"+p.getBaseURL()+"/v1/project", bodyStr, p) +} + +func (p *ProjectHandler) CreateConfigurationServiceProject(project models.Project) (*models.EventContext, *models.Error) { bodyStr, err := json.Marshal(project) if err != nil { return nil, buildErrorResponse(err.Error()) @@ -76,12 +89,12 @@ func (p *ProjectHandler) CreateProject(project models.Project) (*models.EventCon // DeleteProject deletes a project func (p *ProjectHandler) DeleteProject(project models.Project) (*models.EventContext, *models.Error) { - return delete(p.Scheme+"://"+p.getBaseURL()+"/v1/project/"+*project.Name, p) + return delete(p.Scheme+"://"+p.getBaseURL()+"/v1/project/"+project.ProjectName, p) } // GetProject returns a project func (p *ProjectHandler) GetProject(project models.Project) (*models.Project, *models.Error) { - return getProject(p.Scheme+"://"+p.getBaseURL()+"/v1/project/"+*project.Name, p) + return getProject(p.Scheme+"://"+p.getBaseURL()+"/v1/project/"+project.ProjectName, p) } func getProject(uri string, api APIService) (*models.Project, *models.Error) { diff --git a/pkg/api/utils/resourceUtils.go b/pkg/api/utils/resourceUtils.go index 9bd3129e..150d05bb 100644 --- a/pkg/api/utils/resourceUtils.go +++ b/pkg/api/utils/resourceUtils.go @@ -1,9 +1,14 @@ -package utils +package api import ( + "bytes" + "crypto/tls" b64 "encoding/base64" "encoding/json" + "errors" + "io/ioutil" "net/http" + "net/url" "strings" "github.com/keptn/go-utils/pkg/api/models" @@ -24,14 +29,19 @@ type resourceRequest struct { // NewResourceHandler returns a new ResourceHandler func NewResourceHandler(baseURL string) *ResourceHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") + scheme := "http" + if strings.Contains(baseURL, "https://") { + baseURL = strings.TrimPrefix(baseURL, "https://") + } else if strings.Contains(baseURL, "http://") { + baseURL = strings.TrimPrefix(baseURL, "http://") + scheme = "http" + } return &ResourceHandler{ BaseURL: baseURL, AuthHeader: "", AuthToken: "", HTTPClient: &http.Client{Transport: getClientTransport()}, - Scheme: "https", + Scheme: scheme, } } @@ -74,8 +84,8 @@ func (r *ResourceHandler) CreateResources(project string, stage string, service copiedResources := make([]*models.Resource, len(resources), len(resources)) for i, val := range resources { - resourceContent := b64.StdEncoding.EncodeToString([]byte(*val.ResourceContent)) - copiedResources[i] = &models.Resource{ResourceURI: val.ResourceURI, ResourceContent: &resourceContent} + resourceContent := b64.StdEncoding.EncodeToString([]byte(val.ResourceContent)) + copiedResources[i] = &models.Resource{ResourceURI: val.ResourceURI, ResourceContent: resourceContent} } resReq := &resourceRequest{ @@ -94,3 +104,292 @@ func (r *ResourceHandler) CreateResources(project string, stage string, service return post(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource", requestStr, r) } } + +// CreateProjectResources creates multiple project resources +func (r *ResourceHandler) CreateProjectResources(project string, resources []*models.Resource) (string, error) { + return r.createResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource", resources) +} + +// GetProjectResource retrieves a project resource from the configuration service +func (r *ResourceHandler) GetProjectResource(project string, resourceURI string) (*models.Resource, error) { + return r.getResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/resource/" + url.QueryEscape(resourceURI)) +} + +// UpdateProjectResource updates a project resource +func (r *ResourceHandler) UpdateProjectResource(project string, resource *models.Resource) (string, error) { + return r.updateResource(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource/"+url.QueryEscape(*resource.ResourceURI), resource) +} + +// DeleteProjectResource deletes a project resource +func (r *ResourceHandler) DeleteProjectResource(project string, resourceURI string) error { + return r.deleteResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/resource/" + url.QueryEscape(resourceURI)) +} + +// UpdateProjectResources updates multiple project resources +func (r *ResourceHandler) UpdateProjectResources(project string, resources []*models.Resource) (string, error) { + return r.updateResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource", resources) +} + +// CreateStageResources creates a stage resource +func (r *ResourceHandler) CreateStageResources(project string, stage string, resources []*models.Resource) (string, error) { + return r.createResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/resource", resources) +} + +// GetStageResource retrieves a stage resource from the configuration service +func (r *ResourceHandler) GetStageResource(project string, stage string, resourceURI string) (*models.Resource, error) { + return r.getResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/resource/" + url.QueryEscape(resourceURI)) +} + +// UpdateStageResource updates a stage resource +func (r *ResourceHandler) UpdateStageResource(project string, stage string, resource *models.Resource) (string, error) { + return r.updateResource(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/resource/"+url.QueryEscape(*resource.ResourceURI), resource) +} + +// UpdateStageResources updates multiple stage resources +func (r *ResourceHandler) UpdateStageResources(project string, stage string, resources []*models.Resource) (string, error) { + return r.updateResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/resource", resources) +} + +// DeleteStageResource deletes a stage resource +func (r *ResourceHandler) DeleteStageResource(project string, stage string, resourceURI string) error { + return r.deleteResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/resource/" + url.QueryEscape(resourceURI)) +} + +// CreateServiceResources creates a service resource +func (r *ResourceHandler) CreateServiceResources(project string, stage string, service string, resources []*models.Resource) (string, error) { + return r.createResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+service+"/resource", resources) +} + +// GetServiceResource retrieves a service resource from the configuration service +func (r *ResourceHandler) GetServiceResource(project string, stage string, service string, resourceURI string) (*models.Resource, error) { + return r.getResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/service/" + url.QueryEscape(service) + "/resource/" + url.QueryEscape(resourceURI)) +} + +// UpdateServiceResource updates a service resource +func (r *ResourceHandler) UpdateServiceResource(project string, stage string, service string, resource *models.Resource) (string, error) { + return r.updateResource(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+url.QueryEscape(service)+"/resource/"+url.QueryEscape(*resource.ResourceURI), resource) +} + +// UpdateServiceResources updates multiple service resources +func (r *ResourceHandler) UpdateServiceResources(project string, stage string, service string, resources []*models.Resource) (string, error) { + return r.updateResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+url.QueryEscape(service)+"/resource", resources) +} + +// DeleteServiceResource deletes a service resource +func (r *ResourceHandler) DeleteServiceResource(project string, stage string, service string, resourceURI string) error { + return r.deleteResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/service/" + url.QueryEscape(service) + "/resource/" + url.QueryEscape(resourceURI)) +} + +func (r *ResourceHandler) createResources(uri string, resources []*models.Resource) (string, error) { + return r.writeResources(uri, "POST", resources) +} + +func (r *ResourceHandler) updateResources(uri string, resources []*models.Resource) (string, error) { + return r.writeResources(uri, "PUT", resources) +} + +func (r *ResourceHandler) writeResources(uri string, method string, resources []*models.Resource) (string, error) { + + copiedResources := make([]*models.Resource, len(resources), len(resources)) + for i, val := range resources { + copiedResources[i] = &models.Resource{ResourceURI: val.ResourceURI, ResourceContent: b64.StdEncoding.EncodeToString([]byte(val.ResourceContent))} + } + resReq := &resourceRequest{ + Resources: copiedResources, + } + + resourceStr, err := json.Marshal(resReq) + if err != nil { + return "", err + } + req, err := http.NewRequest(method, uri, bytes.NewBuffer(resourceStr)) + req.Header.Set("Content-Type", "application/json") + addAuthHeader(req, r) + + resp, err := r.HTTPClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + var version models.Version + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { + return "", errors.New(string(body)) + } + + err = json.Unmarshal(body, &version) + if err != nil { + return "", err + } + + return version.Version, nil +} + +func (r *ResourceHandler) updateResource(uri string, resource *models.Resource) (string, error) { + return r.writeResource(uri, "PUT", resource) +} + +func (r *ResourceHandler) writeResource(uri string, method string, resource *models.Resource) (string, error) { + + copiedResource := &models.Resource{ResourceURI: resource.ResourceURI, ResourceContent: b64.StdEncoding.EncodeToString([]byte(resource.ResourceContent))} + + resourceStr, err := json.Marshal(copiedResource) + if err != nil { + return "", err + } + req, err := http.NewRequest(method, uri, bytes.NewBuffer(resourceStr)) + req.Header.Set("Content-Type", "application/json") + addAuthHeader(req, r) + + resp, err := r.HTTPClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { + return "", errors.New(string(body)) + } + + var version models.Version + err = json.Unmarshal(body, &version) + if err != nil { + return "", err + } + + return version.Version, nil +} + +func (r *ResourceHandler) getResource(uri string) (*models.Resource, error) { + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + req, err := http.NewRequest("GET", uri, nil) + req.Header.Set("Content-Type", "application/json") + addAuthHeader(req, r) + + resp, err := r.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { + return nil, errors.New(string(body)) + } + + var resource models.Resource + err = json.Unmarshal(body, &resource) + if err != nil { + return nil, err + } + + // decode resource content + decodedStr, err := b64.StdEncoding.DecodeString(resource.ResourceContent) + if err != nil { + return nil, err + } + resource.ResourceContent = string(decodedStr) + + return &resource, nil +} + +func (r *ResourceHandler) deleteResource(uri string) error { + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + req, err := http.NewRequest("DELETE", uri, nil) + req.Header.Set("Content-Type", "application/json") + addAuthHeader(req, r) + + resp, err := r.HTTPClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +// GetAllStageResources returns a list of all resources. +func (r *ResourceHandler) GetAllStageResources(project string, stage string) ([]*models.Resource, error) { + url, err := url.Parse(r.Scheme + "://" + r.getBaseURL() + "/v1/project/" + project + "/stage/" + stage + "/resource") + if err != nil { + return nil, err + } + return r.getAllResources(url) +} + +// GetAllServiceResources returns a list of all resources. +func (r *ResourceHandler) GetAllServiceResources(project string, stage string, service string) ([]*models.Resource, error) { + url, err := url.Parse(r.Scheme + "://" + r.getBaseURL() + "/v1/project/" + project + "/stage/" + stage + + "/service/" + service + "/resource/") + if err != nil { + return nil, err + } + return r.getAllResources(url) +} + +func (r *ResourceHandler) getAllResources(u *url.URL) ([]*models.Resource, error) { + + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + resources := []*models.Resource{} + + nextPageKey := "" + + for { + if nextPageKey != "" { + q := u.Query() + q.Set("nextPageKey", nextPageKey) + u.RawQuery = q.Encode() + } + req, err := http.NewRequest("GET", u.String(), nil) + req.Header.Set("Content-Type", "application/json") + addAuthHeader(req, r) + + resp, err := r.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode == 200 { + var received models.Resources + err = json.Unmarshal(body, &received) + if err != nil { + return nil, err + } + resources = append(resources, received.Resources...) + + if received.NextPageKey == "" || received.NextPageKey == "0" { + break + } + nextPageKey = received.NextPageKey + + } else { + var respErr models.Error + err = json.Unmarshal(body, &respErr) + if err != nil { + return nil, err + } + return nil, errors.New("Response Error Code: " + string(respErr.Code) + " Message: " + *respErr.Message) + } + } + + return resources, nil +} diff --git a/pkg/api/utils/serviceUtils.go b/pkg/api/utils/serviceUtils.go index eebafb30..4e084920 100644 --- a/pkg/api/utils/serviceUtils.go +++ b/pkg/api/utils/serviceUtils.go @@ -1,8 +1,12 @@ -package utils +package api import ( + "crypto/tls" "encoding/json" + "errors" + "io/ioutil" "net/http" + "net/url" "strings" "github.com/keptn/go-utils/pkg/api/models" @@ -19,14 +23,19 @@ type ServiceHandler struct { // NewServiceHandler returns a new ServiceHandler func NewServiceHandler(baseURL string) *ServiceHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") + scheme := "http" + if strings.Contains(baseURL, "https://") { + baseURL = strings.TrimPrefix(baseURL, "https://") + } else if strings.Contains(baseURL, "http://") { + baseURL = strings.TrimPrefix(baseURL, "http://") + scheme = "http" + } return &ServiceHandler{ BaseURL: baseURL, AuthHeader: "", AuthToken: "", HTTPClient: &http.Client{Transport: getClientTransport()}, - Scheme: "https", + Scheme: scheme, } } @@ -65,10 +74,78 @@ func (s *ServiceHandler) getHTTPClient() *http.Client { } // CreateService creates a new service -func (s *ServiceHandler) CreateService(project string, service models.Service) (*models.EventContext, *models.Error) { +func (s *ServiceHandler) CreateService(project string, service models.CreateService) (*models.EventContext, *models.Error) { bodyStr, err := json.Marshal(service) if err != nil { return nil, buildErrorResponse(err.Error()) } return post(s.Scheme+"://"+s.getBaseURL()+"/v1/project/"+project+"/service", bodyStr, s) } + +// CreateService creates a new service +func (s *ServiceHandler) CreateServiceInStage(project string, stage string, serviceName string) (*models.EventContext, *models.Error) { + + service := models.Service{ServiceName: serviceName} + body, err := json.Marshal(service) + if err != nil { + return nil, buildErrorResponse(err.Error()) + } + return post(s.Scheme+"://"+s.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service", body, s) +} + +// GetAllServices returns a list of all services. +func (s *ServiceHandler) GetAllServices(project string, stage string) ([]*models.Service, error) { + + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + services := []*models.Service{} + + nextPageKey := "" + + for { + url, err := url.Parse(s.Scheme + "://" + s.getBaseURL() + "/v1/project/" + project + "/stage/" + stage + "/service") + if err != nil { + return nil, err + } + q := url.Query() + if nextPageKey != "" { + q.Set("nextPageKey", nextPageKey) + } + req, err := http.NewRequest("GET", url.String(), nil) + req.Header.Set("Content-Type", "application/json") + addAuthHeader(req, s) + + resp, err := s.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode == 200 { + var received models.Services + err = json.Unmarshal(body, &received) + if err != nil { + return nil, err + } + services = append(services, received.Services...) + + if received.NextPageKey == "" || received.NextPageKey == "0" { + break + } + nextPageKey = received.NextPageKey + } else { + var respErr models.Error + err = json.Unmarshal(body, &respErr) + if err != nil { + return nil, err + } + return nil, errors.New("Response Error Code: " + string(respErr.Code) + " Message: " + *respErr.Message) + } + } + + return services, nil +} diff --git a/pkg/configuration-service/utils/stageUtils.go b/pkg/api/utils/stageUtils.go similarity index 88% rename from pkg/configuration-service/utils/stageUtils.go rename to pkg/api/utils/stageUtils.go index 3ee54e64..47e308a6 100644 --- a/pkg/configuration-service/utils/stageUtils.go +++ b/pkg/api/utils/stageUtils.go @@ -1,4 +1,4 @@ -package utils +package api import ( "crypto/tls" @@ -9,7 +9,7 @@ import ( "net/url" "strings" - "github.com/keptn/go-utils/pkg/configuration-service/models" + "github.com/keptn/go-utils/pkg/api/models" ) // StageHandler handles stages @@ -23,14 +23,19 @@ type StageHandler struct { // NewStageHandler returns a new StageHandler func NewStageHandler(baseURL string) *StageHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") + scheme := "http" + if strings.Contains(baseURL, "https://") { + baseURL = strings.TrimPrefix(baseURL, "https://") + } else if strings.Contains(baseURL, "http://") { + baseURL = strings.TrimPrefix(baseURL, "http://") + scheme = "http" + } return &StageHandler{ BaseURL: baseURL, AuthHeader: "", AuthToken: "", HTTPClient: &http.Client{}, - Scheme: "http", + Scheme: scheme, } } @@ -67,12 +72,12 @@ func (s *StageHandler) getHTTPClient() *http.Client { } // CreateStage creates a new stage with the provided name -func (s *StageHandler) CreateStage(project string, stageName string) (*models.Error, error) { +func (s *StageHandler) CreateStage(project string, stageName string) (*models.EventContext, *models.Error) { stage := models.Stage{StageName: stageName} body, err := json.Marshal(stage) if err != nil { - return nil, err + return nil, buildErrorResponse(err.Error()) } return post(s.Scheme+"://"+s.BaseURL+"/v1/project/"+project+"/stage", body, s) } diff --git a/pkg/api/utils/xipIoResolver.go b/pkg/api/utils/xipIoResolver.go index 1abd6e0d..129cfa4d 100644 --- a/pkg/api/utils/xipIoResolver.go +++ b/pkg/api/utils/xipIoResolver.go @@ -1,4 +1,4 @@ -package utils +package api import ( "context" diff --git a/pkg/configuration-service/models/error.go b/pkg/configuration-service/models/error.go deleted file mode 100644 index 270bcd82..00000000 --- a/pkg/configuration-service/models/error.go +++ /dev/null @@ -1,67 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// Error error -// swagger:model Error -type Error struct { - - // Error code - Code int64 `json:"code,omitempty"` - - // Error message - // Required: true - Message *string `json:"message"` -} - -// Validate validates this error -func (m *Error) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateMessage(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *Error) validateMessage(formats strfmt.Registry) error { - - if err := validate.Required("message", "body", m.Message); err != nil { - return err - } - - return nil -} - -// MarshalBinary interface implementation -func (m *Error) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Error) UnmarshalBinary(b []byte) error { - var res Error - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/configuration-service/models/project.go b/pkg/configuration-service/models/project.go deleted file mode 100644 index 54a804ae..00000000 --- a/pkg/configuration-service/models/project.go +++ /dev/null @@ -1,52 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/swag" -) - -// Project project -// swagger:model Project -type Project struct { - - // Git remote URI - GitRemoteURI string `json:"gitRemoteURI,omitempty"` - - // Git token - GitToken string `json:"gitToken,omitempty"` - - // Git User - GitUser string `json:"gitUser,omitempty"` - - // Project name - ProjectName string `json:"projectName,omitempty"` -} - -// Validate validates this project -func (m *Project) Validate(formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (m *Project) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Project) UnmarshalBinary(b []byte) error { - var res Project - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/configuration-service/models/resource.go b/pkg/configuration-service/models/resource.go deleted file mode 100644 index 4a53d1ab..00000000 --- a/pkg/configuration-service/models/resource.go +++ /dev/null @@ -1,67 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// Resource resource -// swagger:model Resource -type Resource struct { - - // Resource content - ResourceContent string `json:"resourceContent,omitempty"` - - // Resource URI - // Required: true - ResourceURI *string `json:"resourceURI"` -} - -// Validate validates this resource -func (m *Resource) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateResourceURI(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *Resource) validateResourceURI(formats strfmt.Registry) error { - - if err := validate.Required("resourceURI", "body", m.ResourceURI); err != nil { - return err - } - - return nil -} - -// MarshalBinary interface implementation -func (m *Resource) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Resource) UnmarshalBinary(b []byte) error { - var res Resource - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/configuration-service/models/service.go b/pkg/configuration-service/models/service.go deleted file mode 100644 index 9de10bee..00000000 --- a/pkg/configuration-service/models/service.go +++ /dev/null @@ -1,43 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/swag" -) - -// Service service -// swagger:model Service -type Service struct { - - // Service name - ServiceName string `json:"serviceName,omitempty"` -} - -// Validate validates this service -func (m *Service) Validate(formats strfmt.Registry) error { - return nil -} - -// MarshalBinary interface implementation -func (m *Service) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Service) UnmarshalBinary(b []byte) error { - var res Service - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/configuration-service/utils/configServiceUtils.go b/pkg/configuration-service/utils/configServiceUtils.go deleted file mode 100644 index c3bef6bc..00000000 --- a/pkg/configuration-service/utils/configServiceUtils.go +++ /dev/null @@ -1,92 +0,0 @@ -package utils - -import ( - "bytes" - "crypto/tls" - "encoding/json" - "io/ioutil" - "net/http" - - "github.com/keptn/go-utils/pkg/configuration-service/models" -) - -// ConfigService represents the interface for accessing the configuration service -type ConfigService interface { - getBaseURL() string - getAuthToken() string - getAuthHeader() string - getHTTPClient() *http.Client -} - -func post(uri string, data []byte, c ConfigService) (*models.Error, error) { - - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - req, err := http.NewRequest("POST", uri, bytes.NewBuffer(data)) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, c) - - resp, err := c.getHTTPClient().Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if resp.StatusCode >= 200 && resp.StatusCode < 300 { - return nil, nil - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var respErr models.Error - err = json.Unmarshal(body, &respErr) - if err != nil { - return nil, err - } - - return &respErr, nil -} - -func delete(uri string, c ConfigService) (*models.Error, error) { - - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - req, err := http.NewRequest("DELETE", uri, nil) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, c) - - resp, err := c.getHTTPClient().Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if resp.StatusCode >= 200 && resp.StatusCode < 300 { - return nil, nil - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var respErr models.Error - err = json.Unmarshal(body, &respErr) - if err != nil { - return nil, err - } - - return &respErr, nil -} - -func buildErrorResponse(errorStr string) *models.Error { - err := models.Error{Message: &errorStr} - return &err -} - -func addAuthHeader(req *http.Request, c ConfigService) { - if c.getAuthHeader() != "" && c.getAuthToken() != "" { - req.Header.Set(c.getAuthHeader(), c.getAuthToken()) - } -} diff --git a/pkg/configuration-service/utils/projectUtils.go b/pkg/configuration-service/utils/projectUtils.go deleted file mode 100644 index 36da893d..00000000 --- a/pkg/configuration-service/utils/projectUtils.go +++ /dev/null @@ -1,126 +0,0 @@ -package utils - -import ( - "crypto/tls" - "encoding/json" - "io/ioutil" - "net/http" - "strings" - - "github.com/keptn/go-utils/pkg/configuration-service/models" -) - -// ProjectHandler handles projects -type ProjectHandler struct { - BaseURL string - AuthToken string - AuthHeader string - HTTPClient *http.Client - Scheme string -} - -// NewProjectHandler returns a new ProjectHandler -func NewProjectHandler(baseURL string) *ProjectHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") - return &ProjectHandler{ - BaseURL: baseURL, - AuthHeader: "", - AuthToken: "", - HTTPClient: &http.Client{}, - Scheme: "http", - } -} - -// NewAuthenticatedProjectHandler returns a new ProjectHandler that authenticates at the endpoint via the provided token -func NewAuthenticatedProjectHandler(baseURL string, authToken string, authHeader string, httpClient *http.Client, scheme string) *ProjectHandler { - if httpClient == nil { - httpClient = &http.Client{} - } - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") - return &ProjectHandler{ - BaseURL: baseURL, - AuthHeader: authHeader, - AuthToken: authToken, - HTTPClient: httpClient, - Scheme: scheme, - } -} - -func (p *ProjectHandler) getBaseURL() string { - return p.BaseURL -} - -func (p *ProjectHandler) getAuthToken() string { - return p.AuthToken -} - -func (p *ProjectHandler) getAuthHeader() string { - return p.AuthHeader -} - -func (p *ProjectHandler) getHTTPClient() *http.Client { - return p.HTTPClient -} - -// CreateProject creates a new project -func (p *ProjectHandler) CreateProject(project models.Project) (*models.Error, error) { - bodyStr, err := json.Marshal(project) - if err != nil { - return nil, err - } - return post(p.Scheme+"://"+p.getBaseURL()+"/v1/project", bodyStr, p) -} - -// DeleteProject deletes a project -func (p *ProjectHandler) DeleteProject(project models.Project) (*models.Error, error) { - return delete(p.Scheme+"://"+p.getBaseURL()+"/v1/project/"+project.ProjectName, p) -} - -// GetProject returns a project -func (p *ProjectHandler) GetProject(project models.Project) (*models.Project, *models.Error) { - return get(p.Scheme+"://"+p.getBaseURL()+"/v1/project/"+project.ProjectName, p) -} - -func get(uri string, c ConfigService) (*models.Project, *models.Error) { - - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - req, err := http.NewRequest("GET", uri, nil) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, c) - - resp, err := c.getHTTPClient().Do(req) - if err != nil { - return nil, buildErrorResponse(err.Error()) - } - defer resp.Body.Close() - - if resp.StatusCode >= 200 && resp.StatusCode < 300 { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, buildErrorResponse(err.Error()) - } - - var respProject models.Project - err = json.Unmarshal(body, &respProject) - if err != nil { - return nil, buildErrorResponse(err.Error()) - } - - return &respProject, nil - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, buildErrorResponse(err.Error()) - } - - var respErr models.Error - err = json.Unmarshal(body, &respErr) - if err != nil { - return nil, buildErrorResponse(err.Error()) - } - - return nil, &respErr -} diff --git a/pkg/configuration-service/utils/resourceUtils.go b/pkg/configuration-service/utils/resourceUtils.go deleted file mode 100644 index efd8a488..00000000 --- a/pkg/configuration-service/utils/resourceUtils.go +++ /dev/null @@ -1,362 +0,0 @@ -package utils - -import ( - "bytes" - "crypto/tls" - b64 "encoding/base64" - "encoding/json" - "errors" - "io/ioutil" - "net/http" - "net/url" - "strings" - - "github.com/keptn/go-utils/pkg/configuration-service/models" -) - -// ResourceHandler handles resources -type ResourceHandler struct { - BaseURL string - AuthToken string - AuthHeader string - HTTPClient *http.Client - Scheme string -} - -type resourceRequest struct { - Resources []*models.Resource `json:"resources"` -} - -// NewResourceHandler returns a new ResourceHandler -func NewResourceHandler(baseURL string) *ResourceHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") - return &ResourceHandler{ - BaseURL: baseURL, - AuthHeader: "", - AuthToken: "", - HTTPClient: &http.Client{}, - Scheme: "http", - } -} - -// NewAuthenticatedResourceHandler returns a new ResourceHandler that authenticates at the endpoint via the provided token -func NewAuthenticatedResourceHandler(baseURL string, authToken string, authHeader string, httpClient *http.Client, scheme string) *ResourceHandler { - if httpClient == nil { - httpClient = &http.Client{} - } - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") - return &ResourceHandler{ - BaseURL: baseURL, - AuthHeader: authHeader, - AuthToken: authToken, - HTTPClient: httpClient, - Scheme: scheme, - } -} - -func (r *ResourceHandler) getBaseURL() string { - return r.BaseURL -} - -func (r *ResourceHandler) getAuthToken() string { - return r.AuthToken -} - -func (r *ResourceHandler) getAuthHeader() string { - return r.AuthHeader -} - -func (r *ResourceHandler) getHTTPClient() *http.Client { - return r.HTTPClient -} - -// CreateProjectResources creates multiple project resources -func (r *ResourceHandler) CreateProjectResources(project string, resources []*models.Resource) (string, error) { - return r.createResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource", resources) -} - -// GetProjectResource retrieves a project resource from the configuration service -func (r *ResourceHandler) GetProjectResource(project string, resourceURI string) (*models.Resource, error) { - return r.getResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/resource/" + url.QueryEscape(resourceURI)) -} - -// UpdateProjectResource updates a project resource -func (r *ResourceHandler) UpdateProjectResource(project string, resource *models.Resource) (string, error) { - return r.updateResource(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource/"+url.QueryEscape(*resource.ResourceURI), resource) -} - -// DeleteProjectResource deletes a project resource -func (r *ResourceHandler) DeleteProjectResource(project string, resourceURI string) error { - return r.deleteResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/resource/" + url.QueryEscape(resourceURI)) -} - -// UpdateProjectResources updates multiple project resources -func (r *ResourceHandler) UpdateProjectResources(project string, resources []*models.Resource) (string, error) { - return r.updateResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/resource", resources) -} - -// CreateStageResources creates a stage resource -func (r *ResourceHandler) CreateStageResources(project string, stage string, resources []*models.Resource) (string, error) { - return r.createResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/resource", resources) -} - -// GetStageResource retrieves a stage resource from the configuration service -func (r *ResourceHandler) GetStageResource(project string, stage string, resourceURI string) (*models.Resource, error) { - return r.getResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/resource/" + url.QueryEscape(resourceURI)) -} - -// UpdateStageResource updates a stage resource -func (r *ResourceHandler) UpdateStageResource(project string, stage string, resource *models.Resource) (string, error) { - return r.updateResource(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/resource/"+url.QueryEscape(*resource.ResourceURI), resource) -} - -// UpdateStageResources updates multiple stage resources -func (r *ResourceHandler) UpdateStageResources(project string, stage string, resources []*models.Resource) (string, error) { - return r.updateResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/resource", resources) -} - -// DeleteStageResource deletes a stage resource -func (r *ResourceHandler) DeleteStageResource(project string, stage string, resourceURI string) error { - return r.deleteResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/resource/" + url.QueryEscape(resourceURI)) -} - -// CreateServiceResources creates a service resource -func (r *ResourceHandler) CreateServiceResources(project string, stage string, service string, resources []*models.Resource) (string, error) { - return r.createResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+service+"/resource", resources) -} - -// GetServiceResource retrieves a service resource from the configuration service -func (r *ResourceHandler) GetServiceResource(project string, stage string, service string, resourceURI string) (*models.Resource, error) { - return r.getResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/service/" + url.QueryEscape(service) + "/resource/" + url.QueryEscape(resourceURI)) -} - -// UpdateServiceResource updates a service resource -func (r *ResourceHandler) UpdateServiceResource(project string, stage string, service string, resource *models.Resource) (string, error) { - return r.updateResource(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+url.QueryEscape(service)+"/resource/"+url.QueryEscape(*resource.ResourceURI), resource) -} - -// UpdateServiceResources updates multiple service resources -func (r *ResourceHandler) UpdateServiceResources(project string, stage string, service string, resources []*models.Resource) (string, error) { - return r.updateResources(r.Scheme+"://"+r.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service/"+url.QueryEscape(service)+"/resource", resources) -} - -// DeleteServiceResource deletes a service resource -func (r *ResourceHandler) DeleteServiceResource(project string, stage string, service string, resourceURI string) error { - return r.deleteResource(r.Scheme + "://" + r.BaseURL + "/v1/project/" + project + "/stage/" + stage + "/service/" + url.QueryEscape(service) + "/resource/" + url.QueryEscape(resourceURI)) -} - -func (r *ResourceHandler) createResources(uri string, resources []*models.Resource) (string, error) { - return r.writeResources(uri, "POST", resources) -} - -func (r *ResourceHandler) updateResources(uri string, resources []*models.Resource) (string, error) { - return r.writeResources(uri, "PUT", resources) -} - -func (r *ResourceHandler) writeResources(uri string, method string, resources []*models.Resource) (string, error) { - - copiedResources := make([]*models.Resource, len(resources), len(resources)) - for i, val := range resources { - copiedResources[i] = &models.Resource{ResourceURI: val.ResourceURI, ResourceContent: b64.StdEncoding.EncodeToString([]byte(val.ResourceContent))} - } - resReq := &resourceRequest{ - Resources: copiedResources, - } - - resourceStr, err := json.Marshal(resReq) - if err != nil { - return "", err - } - req, err := http.NewRequest(method, uri, bytes.NewBuffer(resourceStr)) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, r) - - resp, err := r.HTTPClient.Do(req) - if err != nil { - return "", err - } - defer resp.Body.Close() - - var version models.Version - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", err - } - if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { - return "", errors.New(string(body)) - } - - err = json.Unmarshal(body, &version) - if err != nil { - return "", err - } - - return version.Version, nil -} - -func (r *ResourceHandler) updateResource(uri string, resource *models.Resource) (string, error) { - return r.writeResource(uri, "PUT", resource) -} - -func (r *ResourceHandler) writeResource(uri string, method string, resource *models.Resource) (string, error) { - - copiedResource := &models.Resource{ResourceURI: resource.ResourceURI, ResourceContent: b64.StdEncoding.EncodeToString([]byte(resource.ResourceContent))} - - resourceStr, err := json.Marshal(copiedResource) - if err != nil { - return "", err - } - req, err := http.NewRequest(method, uri, bytes.NewBuffer(resourceStr)) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, r) - - resp, err := r.HTTPClient.Do(req) - if err != nil { - return "", err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", err - } - - if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { - return "", errors.New(string(body)) - } - - var version models.Version - err = json.Unmarshal(body, &version) - if err != nil { - return "", err - } - - return version.Version, nil -} - -func (r *ResourceHandler) getResource(uri string) (*models.Resource, error) { - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - req, err := http.NewRequest("GET", uri, nil) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, r) - - resp, err := r.HTTPClient.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { - return nil, errors.New(string(body)) - } - - var resource models.Resource - err = json.Unmarshal(body, &resource) - if err != nil { - return nil, err - } - - // decode resource content - decodedStr, err := b64.StdEncoding.DecodeString(resource.ResourceContent) - if err != nil { - return nil, err - } - resource.ResourceContent = string(decodedStr) - - return &resource, nil -} - -func (r *ResourceHandler) deleteResource(uri string) error { - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - req, err := http.NewRequest("DELETE", uri, nil) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, r) - - resp, err := r.HTTPClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - return nil -} - -// GetAllStageResources returns a list of all resources. -func (r *ResourceHandler) GetAllStageResources(project string, stage string) ([]*models.Resource, error) { - url, err := url.Parse(r.Scheme + "://" + r.getBaseURL() + "/v1/project/" + project + "/stage/" + stage + "/resource") - if err != nil { - return nil, err - } - return r.getAllResources(url) -} - -// GetAllServiceResources returns a list of all resources. -func (r *ResourceHandler) GetAllServiceResources(project string, stage string, service string) ([]*models.Resource, error) { - url, err := url.Parse(r.Scheme + "://" + r.getBaseURL() + "/v1/project/" + project + "/stage/" + stage + - "/service/" + service + "/resource/") - if err != nil { - return nil, err - } - return r.getAllResources(url) -} - -func (r *ResourceHandler) getAllResources(u *url.URL) ([]*models.Resource, error) { - - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - resources := []*models.Resource{} - - nextPageKey := "" - - for { - if nextPageKey != "" { - q := u.Query() - q.Set("nextPageKey", nextPageKey) - u.RawQuery = q.Encode() - } - req, err := http.NewRequest("GET", u.String(), nil) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, r) - - resp, err := r.HTTPClient.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - if resp.StatusCode == 200 { - var received models.Resources - err = json.Unmarshal(body, &received) - if err != nil { - return nil, err - } - resources = append(resources, received.Resources...) - - if received.NextPageKey == "" || received.NextPageKey == "0" { - break - } - nextPageKey = received.NextPageKey - - } else { - var respErr models.Error - err = json.Unmarshal(body, &respErr) - if err != nil { - return nil, err - } - return nil, errors.New("Response Error Code: " + string(respErr.Code) + " Message: " + *respErr.Message) - } - } - - return resources, nil -} diff --git a/pkg/configuration-service/utils/serviceUtils.go b/pkg/configuration-service/utils/serviceUtils.go deleted file mode 100644 index caf10b47..00000000 --- a/pkg/configuration-service/utils/serviceUtils.go +++ /dev/null @@ -1,135 +0,0 @@ -package utils - -import ( - "crypto/tls" - "encoding/json" - "errors" - "io/ioutil" - "net/http" - "net/url" - "strings" - - "github.com/keptn/go-utils/pkg/configuration-service/models" -) - -// ServiceHandler handles services -type ServiceHandler struct { - BaseURL string - AuthToken string - AuthHeader string - HTTPClient *http.Client - Scheme string -} - -// NewServiceHandler returns a new ServiceHandler -func NewServiceHandler(baseURL string) *ServiceHandler { - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") - return &ServiceHandler{ - BaseURL: baseURL, - AuthHeader: "", - AuthToken: "", - HTTPClient: &http.Client{}, - Scheme: "http", - } -} - -// NewAuthenticatedServiceHandler returns a new ServiceHandler that authenticates at the endpoint via the provided token -func NewAuthenticatedServiceHandler(baseURL string, authToken string, authHeader string, httpClient *http.Client, scheme string) *ServiceHandler { - if httpClient == nil { - httpClient = &http.Client{} - } - baseURL = strings.TrimPrefix(baseURL, "http://") - baseURL = strings.TrimPrefix(baseURL, "https://") - return &ServiceHandler{ - BaseURL: baseURL, - AuthHeader: authHeader, - AuthToken: authToken, - HTTPClient: httpClient, - Scheme: scheme, - } -} - -func (s *ServiceHandler) getBaseURL() string { - return s.BaseURL -} - -func (s *ServiceHandler) getAuthToken() string { - return s.AuthToken -} - -func (s *ServiceHandler) getAuthHeader() string { - return s.AuthHeader -} - -func (s *ServiceHandler) getHTTPClient() *http.Client { - return s.HTTPClient -} - -// CreateService creates a new service -func (s *ServiceHandler) CreateService(project string, stage string, serviceName string) (*models.Error, error) { - - service := models.Service{ServiceName: serviceName} - body, err := json.Marshal(service) - if err != nil { - return nil, err - } - return post(s.Scheme+"://"+s.BaseURL+"/v1/project/"+project+"/stage/"+stage+"/service", body, s) -} - -// GetAllServices returns a list of all services. -func (s *ServiceHandler) GetAllServices(project string, stage string) ([]*models.Service, error) { - - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - services := []*models.Service{} - - nextPageKey := "" - - for { - url, err := url.Parse(s.Scheme + "://" + s.getBaseURL() + "/v1/project/" + project + "/stage/" + stage + "/service") - if err != nil { - return nil, err - } - q := url.Query() - if nextPageKey != "" { - q.Set("nextPageKey", nextPageKey) - } - req, err := http.NewRequest("GET", url.String(), nil) - req.Header.Set("Content-Type", "application/json") - addAuthHeader(req, s) - - resp, err := s.HTTPClient.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - if resp.StatusCode == 200 { - var received models.Services - err = json.Unmarshal(body, &received) - if err != nil { - return nil, err - } - services = append(services, received.Services...) - - if received.NextPageKey == "" || received.NextPageKey == "0" { - break - } - nextPageKey = received.NextPageKey - } else { - var respErr models.Error - err = json.Unmarshal(body, &respErr) - if err != nil { - return nil, err - } - return nil, errors.New("Response Error Code: " + string(respErr.Code) + " Message: " + *respErr.Message) - } - } - - return services, nil -} diff --git a/pkg/configuration-service/utils/sliUtils.go b/pkg/configuration-service/utils/sliUtils.go deleted file mode 100644 index c785fd18..00000000 --- a/pkg/configuration-service/utils/sliUtils.go +++ /dev/null @@ -1,84 +0,0 @@ -package utils - -import ( - "strings" - - "github.com/keptn/go-utils/pkg/configuration-service/models" - "gopkg.in/yaml.v2" -) - -// SLIConfig represents the struct of a SLI file -type SLIConfig struct { - Indicators map[string]string `json:"indicators" yaml:"indicators"` -} - -// GetSLIConfiguration retrieves the SLI configuration for a service considering SLI configuration on stage and project level. -// First, the configuration of project-level is retrieved, which is then overridden by configuration on stage level, -// overridden by configuration on service level. -func (r *ResourceHandler) GetSLIConfiguration(project string, stage string, service string, resourceURI string) (map[string]string, error) { - var res *models.Resource - var err error - SLIs := make(map[string]string) - - // get sli config from project - if project != "" { - res, err = r.GetProjectResource(project, resourceURI) - if err != nil { - // return error except "resource not found" type - if !strings.Contains(err.Error(), "resource not found") { - return nil, err - } - } - SLIs, err = addResourceContentToSLIMap(SLIs, res) - if err != nil { - return nil, err - } - } - - // get sli config from stage - if project != "" && stage != "" { - res, err = r.GetStageResource(project, stage, resourceURI) - if err != nil { - // return error except "resource not found" type - if !strings.Contains(err.Error(), "resource not found") { - return nil, err - } - } - SLIs, err = addResourceContentToSLIMap(SLIs, res) - if err != nil { - return nil, err - } - } - - // get sli config from service - if project != "" && stage != "" && service != "" { - res, err = r.GetServiceResource(project, stage, service, resourceURI) - if err != nil { - // return error except "resource not found" type - if !strings.Contains(err.Error(), "resource not found") { - return nil, err - } - } - SLIs, err = addResourceContentToSLIMap(SLIs, res) - if err != nil { - return nil, err - } - } - - return SLIs, nil -} - -func addResourceContentToSLIMap(SLIs map[string]string, resource *models.Resource) (map[string]string, error) { - if resource != nil { - sliConfig := SLIConfig{} - err := yaml.Unmarshal([]byte(resource.ResourceContent), &sliConfig) - if err != nil { - return nil, err - } - - for key, value := range sliConfig.Indicators { - SLIs[key] = value - } - } - return SLIs, nil -} diff --git a/pkg/configuration-service/utils/sliUtils_test.go b/pkg/configuration-service/utils/sliUtils_test.go deleted file mode 100644 index 8e44fa9f..00000000 --- a/pkg/configuration-service/utils/sliUtils_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package utils - -import ( - "testing" - - "github.com/keptn/go-utils/pkg/configuration-service/models" -) - -// TestAddResourceContentToSLIMap -func TestAddResourceContentToSLIMap(t *testing.T) { - SLIs := make(map[string]string) - resource := &models.Resource{} - resourceURI := "provider/sli.yaml" - resource.ResourceURI = &resourceURI - resource.ResourceContent = `--- -indicators: - error_rate: "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - response_time_p50: "builtin:service.response.time:merge(0):percentile(50)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - response_time_p90: "builtin:service.response.time:merge(0):percentile(90)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - response_time_p95: "builtin:service.response.time:merge(0):percentile(95)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - throughput: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" -` - SLIs, _ = addResourceContentToSLIMap(SLIs, resource) - - if len(SLIs) != 5 { - t.Errorf("Unexpected lenght of SLI map") - } -} - -// TestAddResourceContentToSLIMap -func TestAddMultipleResourceContentToSLIMap(t *testing.T) { - SLIs := make(map[string]string) - resource := &models.Resource{} - resourceURI := "provider/sli.yaml" - resource.ResourceURI = &resourceURI - resource.ResourceContent = `--- -indicators: - error_rate: "not defined" - response_time_p50: "builtin:service.response.time:merge(0):percentile(50)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - response_time_p90: "builtin:service.response.time:merge(0):percentile(90)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - response_time_p95: "builtin:service.response.time:merge(0):percentile(95)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - throughput: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" -` - SLIs, _ = addResourceContentToSLIMap(SLIs, resource) - - resource.ResourceContent = `--- -indicators: - error_rate: "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" - failure_rate: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" -` - SLIs, _ = addResourceContentToSLIMap(SLIs, resource) - - if len(SLIs) != 6 { - t.Errorf("Unexpected length of SLI map") - } - - if SLIs["error_rate"] != "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" { - t.Errorf("Unexpected value of error_rate SLI") - } -} diff --git a/pkg/events/deployment_strategy_test.go b/pkg/events/deployment_strategy_test.go deleted file mode 100644 index d002409c..00000000 --- a/pkg/events/deployment_strategy_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package events - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -// TestGetInvalidDeploymentStrategy tests whether an error is returned -// if an invalid test strategy is passed to GetDeploymentStrategy -func TestGetInvalidDeploymentStrategy(t *testing.T) { - _, err := GetDeploymentStrategy("invalidStrategy") - assert.Error(t, err) -} diff --git a/pkg/events/canaryAction.go b/pkg/lib/canary_action.go similarity index 98% rename from pkg/events/canaryAction.go rename to pkg/lib/canary_action.go index a7c1a9f7..12ef6a20 100644 --- a/pkg/events/canaryAction.go +++ b/pkg/lib/canary_action.go @@ -1,4 +1,4 @@ -package events +package keptn import ( "bytes" diff --git a/pkg/utils/cmdUtils.go b/pkg/lib/cmdUtils.go similarity index 98% rename from pkg/utils/cmdUtils.go rename to pkg/lib/cmdUtils.go index 3f7b4ca7..484e4954 100644 --- a/pkg/utils/cmdUtils.go +++ b/pkg/lib/cmdUtils.go @@ -1,4 +1,4 @@ -package utils +package keptn import ( "fmt" diff --git a/pkg/utils/combined_logger.go b/pkg/lib/combined_logger.go similarity index 99% rename from pkg/utils/combined_logger.go rename to pkg/lib/combined_logger.go index 7a6fa680..519f3360 100644 --- a/pkg/utils/combined_logger.go +++ b/pkg/lib/combined_logger.go @@ -1,4 +1,4 @@ -package utils +package keptn import ( "fmt" diff --git a/pkg/mongodb-datastore/utils/eventUtils.go b/pkg/lib/datastore.go similarity index 82% rename from pkg/mongodb-datastore/utils/eventUtils.go rename to pkg/lib/datastore.go index 111a964e..8da4e9c7 100644 --- a/pkg/mongodb-datastore/utils/eventUtils.go +++ b/pkg/lib/datastore.go @@ -1,16 +1,34 @@ -package utils +package keptn import ( "crypto/tls" "encoding/json" + "github.com/keptn/go-utils/pkg/api/models" "io/ioutil" "net/http" "strings" "time" - - "github.com/keptn/go-utils/pkg/mongodb-datastore/models" ) +// Datastore represents the interface for accessing Keptn's datastore +type Datastore interface { + getBaseURL() string + getAuthToken() string + getAuthHeader() string + getHTTPClient() *http.Client +} + +func buildErrorResponse(errorStr string) *models.Error { + err := models.Error{Message: &errorStr} + return &err +} + +func addAuthHeader(req *http.Request, datastore Datastore) { + if datastore.getAuthHeader() != "" && datastore.getAuthToken() != "" { + req.Header.Set(datastore.getAuthHeader(), datastore.getAuthToken()) + } +} + // EventHandler handles event type EventHandler struct { BaseURL string diff --git a/pkg/mongodb-datastore/utils/eventUtils_test.go b/pkg/lib/datastore_test.go similarity index 94% rename from pkg/mongodb-datastore/utils/eventUtils_test.go rename to pkg/lib/datastore_test.go index 7068e68a..ad8f7bc4 100644 --- a/pkg/mongodb-datastore/utils/eventUtils_test.go +++ b/pkg/lib/datastore_test.go @@ -1,16 +1,13 @@ -package utils +package keptn import ( "context" + "github.com/go-openapi/strfmt" + "github.com/stretchr/testify/assert" "net" "net/http" "net/http/httptest" "testing" - - strfmt "github.com/go-openapi/strfmt" - - keptnevents "github.com/keptn/go-utils/pkg/events" - "github.com/magiconair/properties/assert" ) // Helper function to build a test client with a httptest server @@ -94,7 +91,7 @@ func TestGetEventStatusOK(t *testing.T) { eventHandler := NewEventHandler("https://localhost") eventHandler.HTTPClient = httpClient - cloudEvent, errObj := eventHandler.GetEvent("8929e5e5-3826-488f-9257-708bfa974909", keptnevents.EvaluationDoneEventType) + cloudEvent, errObj := eventHandler.GetEvent("8929e5e5-3826-488f-9257-708bfa974909", EvaluationDoneEventType) if cloudEvent == nil { t.Error("no Keptn event returned") @@ -130,7 +127,7 @@ func TestGetEventStatusOKNoEvent(t *testing.T) { eventHandler := NewEventHandler("https://localhost") eventHandler.HTTPClient = httpClient - cloudEvent, errObj := eventHandler.GetEvent("8929e5e5-3826-488f-9257-708bfa974909", keptnevents.EvaluationDoneEventType) + cloudEvent, errObj := eventHandler.GetEvent("8929e5e5-3826-488f-9257-708bfa974909", EvaluationDoneEventType) if cloudEvent != nil { t.Error("do not expect a Keptn Cloud event") diff --git a/pkg/events/deploymentStrategy.go b/pkg/lib/deployment_strategy.go similarity index 99% rename from pkg/events/deploymentStrategy.go rename to pkg/lib/deployment_strategy.go index 7bf1ec0f..60848fcc 100644 --- a/pkg/events/deploymentStrategy.go +++ b/pkg/lib/deployment_strategy.go @@ -1,4 +1,4 @@ -package events +package keptn import ( "bytes" diff --git a/pkg/events/keptnEvents.go b/pkg/lib/events.go similarity index 65% rename from pkg/events/keptnEvents.go rename to pkg/lib/events.go index 1c630f2f..4e455903 100644 --- a/pkg/events/keptnEvents.go +++ b/pkg/lib/events.go @@ -1,4 +1,19 @@ -package events +package keptn + +import ( + "context" + "errors" + "fmt" + "github.com/cloudevents/sdk-go/pkg/cloudevents" + "github.com/cloudevents/sdk-go/pkg/cloudevents/client" + cloudeventshttp "github.com/cloudevents/sdk-go/pkg/cloudevents/transport/http" + "github.com/cloudevents/sdk-go/pkg/cloudevents/types" + "github.com/google/uuid" + "github.com/keptn/go-utils/pkg/api/models" + "log" + "net/url" + "time" +) import ( "encoding/json" @@ -43,6 +58,24 @@ const InternalGetSLIEventType = "sh.keptn.internal.event.get-sli" // InternalGetSLIDoneEventType is a CloudEvent for submitting SLI values const InternalGetSLIDoneEventType = "sh.keptn.internal.event.get-sli.done" +// KeptnBase contains properties that are shared among most Keptn events +type KeptnBase struct { + Project string `json:"project"` + // Service is the name of the new service + Service string `json:"service"` + // Stage is the name of the stage + Stage string `json:"stage"` + TestStrategy *string `json:"teststrategy,omitempty"` + // DeploymentStrategy is the deployment strategy + DeploymentStrategy *string `json:"deploymentstrategy,omitempty"` + // Tag of the new deployed artifact + Tag *string `json:"tag,omitempty"` + // Image of the new deployed artifact + Image *string `json:"image,omitempty"` + // Labels contains labels + Labels map[string]string `json:"labels"` +} + // ProjectCreateEventData represents the data for creating a new project type ProjectCreateEventData struct { // Project is the name of the project @@ -307,3 +340,202 @@ type InternalGetSLIDoneEventData struct { // Labels contains labels Labels map[string]string `json:"labels"` } + +// +// Sends a ConfigurationChangeEventType = "sh.keptn.event.configuration.change" +// +func (k *Keptn) SendConfigurationChangeEvent(incomingEvent *cloudevents.Event, labels map[string]string, eventSource string) error { + source, _ := url.Parse(eventSource) + contentType := "application/json" + + configurationChangeData := ConfigurationChangeEventData{} + + // if we have an incoming event we pre-populate data + if incomingEvent != nil { + incomingEvent.DataAs(&configurationChangeData) + } + + if k.KeptnBase.Project != "" { + configurationChangeData.Project = k.KeptnBase.Project + } + if k.KeptnBase.Service != "" { + configurationChangeData.Service = k.KeptnBase.Service + } + if k.KeptnBase.Stage != "" { + configurationChangeData.Stage = k.KeptnBase.Stage + } + if labels != nil { + configurationChangeData.Labels = labels + } + + event := cloudevents.Event{ + Context: cloudevents.EventContextV02{ + ID: uuid.New().String(), + Time: &types.Timestamp{Time: time.Now()}, + Type: ConfigurationChangeEventType, + Source: types.URLRef{URL: *source}, + ContentType: &contentType, + Extensions: map[string]interface{}{"shkeptncontext": k.KeptnContext}, + }.AsV02(), + Data: configurationChangeData, + } + + log.Println(fmt.Sprintf("%s", event)) + + return k.sendCloudEvent(event) +} + +// +// Sends a DeploymentFinishedEventType = "sh.keptn.events.deployment-finished" +// +func (k *Keptn) SendDeploymentFinishedEvent(incomingEvent *cloudevents.Event, teststrategy, deploymentstrategy, image, tag, deploymentURILocal, deploymentURIPublic string, labels map[string]string, eventSource string) error { + source, _ := url.Parse(eventSource) + contentType := "application/json" + + deploymentFinishedData := DeploymentFinishedEventData{} + + // if we have an incoming event we pre-populate data + if incomingEvent != nil { + incomingEvent.DataAs(&deploymentFinishedData) + } + + if k.KeptnBase.Project != "" { + deploymentFinishedData.Project = k.KeptnBase.Project + } + if k.KeptnBase.Service != "" { + deploymentFinishedData.Service = k.KeptnBase.Service + } + if k.KeptnBase.Stage != "" { + deploymentFinishedData.Stage = k.KeptnBase.Stage + } + if teststrategy != "" { + deploymentFinishedData.TestStrategy = teststrategy + } + if deploymentstrategy != "" { + deploymentFinishedData.DeploymentStrategy = deploymentstrategy + } + if image != "" { + deploymentFinishedData.Image = image + } + if tag != "" { + deploymentFinishedData.Tag = tag + } + + if labels != nil { + deploymentFinishedData.Labels = labels + } + + if deploymentURILocal != "" { + deploymentFinishedData.DeploymentURILocal = deploymentURILocal + } + + if deploymentURIPublic != "" { + deploymentFinishedData.DeploymentURIPublic = deploymentURIPublic + } + + event := cloudevents.Event{ + Context: cloudevents.EventContextV02{ + ID: uuid.New().String(), + Time: &types.Timestamp{Time: time.Now()}, + Type: DeploymentFinishedEventType, + Source: types.URLRef{URL: *source}, + ContentType: &contentType, + Extensions: map[string]interface{}{"shkeptncontext": k.KeptnContext}, + }.AsV02(), + Data: deploymentFinishedData, + } + + log.Println(fmt.Sprintf("%s", event)) + + return k.sendCloudEvent(event) + +} + +// +// Sends a TestsFinishedEventType = "sh.keptn.events.tests-finished" +// +func (k *Keptn) SendTestsFinishedEvent(incomingEvent *cloudevents.Event, teststrategy, deploymentstrategy string, startedAt time.Time, result string, labels map[string]string, eventSource string) error { + source, _ := url.Parse(eventSource) + contentType := "application/json" + + testFinishedData := TestsFinishedEventData{} + + // if we have an incoming event we pre-populate data + if incomingEvent != nil { + incomingEvent.DataAs(&testFinishedData) + } + + if k.KeptnBase.Project != "" { + testFinishedData.Project = k.KeptnBase.Project + } + if k.KeptnBase.Service != "" { + testFinishedData.Service = k.KeptnBase.Service + } + if k.KeptnBase.Stage != "" { + testFinishedData.Stage = k.KeptnBase.Stage + } + if teststrategy != "" { + testFinishedData.TestStrategy = teststrategy + } + if deploymentstrategy != "" { + testFinishedData.DeploymentStrategy = deploymentstrategy + } + + if labels != nil { + testFinishedData.Labels = labels + } + + // fill in timestamps + testFinishedData.Start = startedAt.Format(time.RFC3339) + testFinishedData.End = time.Now().Format(time.RFC3339) + + // set test result + testFinishedData.Result = result + + event := cloudevents.Event{ + Context: cloudevents.EventContextV02{ + ID: uuid.New().String(), + Time: &types.Timestamp{Time: time.Now()}, + Type: TestsFinishedEventType, + Source: types.URLRef{URL: *source}, + ContentType: &contentType, + Extensions: map[string]interface{}{"shkeptncontext": k.KeptnContext}, + }.AsV02(), + Data: testFinishedData, + } + + log.Println(fmt.Printf("%s", event)) + + return k.sendCloudEvent(event) +} + +func (k *Keptn) GetEvents(eventType string) (*models.KeptnContextExtendedCE, *models.Error) { + return k.eventHandler.GetEvent(k.KeptnContext, eventType) +} + +// +// Sends a CloudEvent to the event broker +// +func (k *Keptn) sendCloudEvent(event cloudevents.Event) error { + if k.useLocalFileSystem { + log.Println(fmt.Printf("%v", event.Data)) + return nil + } + transport, err := cloudeventshttp.New( + cloudeventshttp.WithTarget(k.eventBrokerURL), + cloudeventshttp.WithEncoding(cloudeventshttp.StructuredV02), + ) + if err != nil { + return errors.New("Failed to create transport:" + err.Error()) + } + + c, err := client.New(transport) + if err != nil { + return errors.New("Failed to create HTTP client:" + err.Error()) + } + + if _, _, err := c.Send(context.Background(), event); err != nil { + return errors.New("Failed to send cloudevent:, " + err.Error()) + } + return nil +} diff --git a/pkg/lib/keptn.go b/pkg/lib/keptn.go new file mode 100644 index 00000000..0a0fd249 --- /dev/null +++ b/pkg/lib/keptn.go @@ -0,0 +1,288 @@ +package keptn + +import ( + "encoding/json" + "fmt" + "github.com/cloudevents/sdk-go/pkg/cloudevents" + "github.com/keptn/go-utils/pkg/api/models" + api "github.com/keptn/go-utils/pkg/api/utils" + "gopkg.in/yaml.v2" + "log" + "os" + "regexp" + "strings" +) + +type KeptnOpts struct { + UseLocalFileSystem bool + ConfigurationServiceURL string + EventBrokerURL string + IncomingEvent *cloudevents.Event +} + +type Keptn struct { + KeptnContext string + + KeptnBase *KeptnBase + + eventBrokerURL string + useLocalFileSystem bool + resourceHandler *api.ResourceHandler + eventHandler *api.EventHandler +} + +// SLIConfig represents the struct of a SLI file +type SLIConfig struct { + Indicators map[string]string `json:"indicators" yaml:"indicators"` +} + +const configurationServiceURL = "configuration-service:8080" +const defaultEventBrokerURL = "http://event-broker.keptn.svc.cluster.local/keptn" + +func NewKeptn(incomingEvent *cloudevents.Event, opts KeptnOpts) (*Keptn, error) { + var shkeptncontext string + _ = incomingEvent.Context.ExtensionAs("shkeptncontext", &shkeptncontext) + + // create a base Keptn Event + keptnBase := &KeptnBase{} + + bytes, err := incomingEvent.DataBytes() + if err != nil { + return nil, err + } + err = json.Unmarshal(bytes, keptnBase) + if err != nil { + return nil, err + } + + k := &Keptn{ + KeptnBase: keptnBase, + KeptnContext: shkeptncontext, + useLocalFileSystem: opts.UseLocalFileSystem, + resourceHandler: nil, + } + csURL := configurationServiceURL + if opts.ConfigurationServiceURL != "" { + csURL = opts.ConfigurationServiceURL + } + + if opts.EventBrokerURL != "" { + k.eventBrokerURL = opts.EventBrokerURL + } else { + k.eventBrokerURL = defaultEventBrokerURL + } + + k.resourceHandler = api.NewResourceHandler(csURL) + k.eventHandler = api.NewEventHandler(csURL) + + return k, nil +} + +// GetShipyard returns the shipyard definition of a project +func (k *Keptn) GetShipyard() (*Shipyard, error) { + shipyardResource, err := k.resourceHandler.GetProjectResource(k.KeptnBase.Project, "shipyard.yaml") + if err != nil { + return nil, err + } + + shipyard := Shipyard{} + err = yaml.Unmarshal([]byte(shipyardResource.ResourceContent), &shipyard) + if err != nil { + return nil, err + } + return &shipyard, nil +} + +// GetSLIConfiguration retrieves the SLI configuration for a service considering SLI configuration on stage and project level. +// First, the configuration of project-level is retrieved, which is then overridden by configuration on stage level, +// overridden by configuration on service level. +func (k *Keptn) GetSLIConfiguration(project string, stage string, service string, resourceURI string) (map[string]string, error) { + var res *models.Resource + var err error + SLIs := make(map[string]string) + + // get sli config from project + if project != "" { + res, err = k.resourceHandler.GetProjectResource(project, resourceURI) + if err != nil { + // return error except "resource not found" type + if !strings.Contains(err.Error(), "resource not found") { + return nil, err + } + } + SLIs, err = addResourceContentToSLIMap(SLIs, res) + if err != nil { + return nil, err + } + } + + // get sli config from stage + if project != "" && stage != "" { + res, err = k.resourceHandler.GetStageResource(project, stage, resourceURI) + if err != nil { + // return error except "resource not found" type + if !strings.Contains(err.Error(), "resource not found") { + return nil, err + } + } + SLIs, err = addResourceContentToSLIMap(SLIs, res) + if err != nil { + return nil, err + } + } + + // get sli config from service + if project != "" && stage != "" && service != "" { + res, err = k.resourceHandler.GetServiceResource(project, stage, service, resourceURI) + if err != nil { + // return error except "resource not found" type + if !strings.Contains(err.Error(), "resource not found") { + return nil, err + } + } + SLIs, err = addResourceContentToSLIMap(SLIs, res) + if err != nil { + return nil, err + } + } + + return SLIs, nil +} + +func addResourceContentToSLIMap(SLIs map[string]string, resource *models.Resource) (map[string]string, error) { + if resource != nil { + sliConfig := SLIConfig{} + err := yaml.Unmarshal([]byte(resource.ResourceContent), &sliConfig) + if err != nil { + return nil, err + } + + for key, value := range sliConfig.Indicators { + SLIs[key] = value + } + } + return SLIs, nil +} + +func (k *Keptn) GetKeptnResource(resource string) (string, error) { + + // if we run in a runlocal mode we are just getting the file from the local disk + if k.useLocalFileSystem { + return _getKeptnResourceFromLocal(resource) + } + + // get it from Keptn + requestedResource, err := k.resourceHandler.GetServiceResource(k.KeptnBase.Project, k.KeptnBase.Stage, k.KeptnBase.Service, resource) + + // return Nil in case resource couldnt be retrieved + if err != nil || requestedResource.ResourceContent == "" { + fmt.Printf("Keptn Resource not found: %s - %s", resource, err) + return "", err + } + + // now store that file on the same directory structure locally + os.RemoveAll(resource) + pathArr := strings.Split(resource, "/") + directory := "" + for _, pathItem := range pathArr[0 : len(pathArr)-1] { + directory += pathItem + "/" + } + + if directory != "" { + err = os.MkdirAll(directory, os.ModePerm) + if err != nil { + return "", err + } + } + resourceFile, err := os.Create(resource) + if err != nil { + fmt.Errorf(err.Error()) + return "", err + } + defer resourceFile.Close() + + _, err = resourceFile.Write([]byte(requestedResource.ResourceContent)) + + if err != nil { + fmt.Errorf(err.Error()) + return "", err + } + + return strings.TrimSuffix(requestedResource.ResourceContent, "\n"), nil +} + +// +// replaces $ placeholders with actual values +// $CONTEXT, $EVENT, $SOURCE +// $PROJECT, $STAGE, $SERVICE, $DEPLOYMENT +// $TESTSTRATEGY +// $LABEL.XXXX -> will replace that with a label called XXXX +// $ENV.XXXX -> will replace that with an env variable called XXXX +// +func (k *Keptn) ReplaceKeptnPlaceholders(input string) string { + result := input + + // first we do the regular keptn values + result = strings.Replace(result, "$CONTEXT", k.KeptnContext, -1) + result = strings.Replace(result, "$PROJECT", k.KeptnBase.Project, -1) + result = strings.Replace(result, "$STAGE", k.KeptnBase.Stage, -1) + result = strings.Replace(result, "$SERVICE", k.KeptnBase.Service, -1) + if k.KeptnBase.DeploymentStrategy != nil { + result = strings.Replace(result, "$DEPLOYMENT", *k.KeptnBase.DeploymentStrategy, -1) + } + if k.KeptnBase.TestStrategy != nil { + result = strings.Replace(result, "$TESTSTRATEGY", *k.KeptnBase.TestStrategy, -1) + } + + // now we do the labels + for key, value := range k.KeptnBase.Labels { + result = strings.Replace(result, "$LABEL."+key, value, -1) + } + + // now we do all environment variables + for _, env := range os.Environ() { + pair := strings.SplitN(env, "=", 2) + result = strings.Replace(result, "$ENV."+pair[0], pair[1], -1) + } + + return result +} + +/** + * Retrieves a resource (=file) from the local file system. Basically checks if the file is available and if so returns it + */ +func _getKeptnResourceFromLocal(resource string) (string, error) { + if _, err := os.Stat(resource); err == nil { + return resource, nil + } else { + return "", err + } +} + +// ValidateKeptnEntityName checks whether the provided name represents a valid +// project, service, or stage name +func ValidateKeptnEntityName(name string) bool { + if len(name) == 0 { + return false + } + reg, err := regexp.Compile(`(^[a-z][a-z0-9-]*[a-z0-9]$)|(^[a-z][a-z0-9]*)`) + if err != nil { + log.Fatal(err) + } + processedString := reg.FindString(name) + return len(processedString) == len(name) +} + +// ValididateUnixDirectoryName checks whether the provided dirName contains +// any special character according to +// https://www.cyberciti.biz/faq/linuxunix-rules-for-naming-file-and-directory-names/ +func ValididateUnixDirectoryName(dirName string) bool { + return !(dirName == "." || + dirName == ".." || + strings.Contains(dirName, "/") || + strings.Contains(dirName, ">") || + strings.Contains(dirName, "<") || + strings.Contains(dirName, "|") || + strings.Contains(dirName, ":") || + strings.Contains(dirName, "&")) +} diff --git a/pkg/lib/keptn_test.go b/pkg/lib/keptn_test.go new file mode 100644 index 00000000..0a1603c6 --- /dev/null +++ b/pkg/lib/keptn_test.go @@ -0,0 +1,392 @@ +package keptn + +import ( + "encoding/json" + "github.com/cloudevents/sdk-go/pkg/cloudevents" + "github.com/go-test/deep" + "github.com/keptn/go-utils/pkg/api/models" + api "github.com/keptn/go-utils/pkg/api/utils" + "math/rand" + "net/http" + "net/http/httptest" + "os" + "testing" + "time" +) + +func TestNewKeptn(t *testing.T) { + incomingEvent := cloudevents.New(cloudevents.CloudEventsVersionV02) + incomingEvent.SetSource("test") + incomingEvent.SetExtension("shkeptncontext", "test-context") + incomingEvent.SetDataContentType(cloudevents.ApplicationCloudEventsJSON) + + keptnBase := &KeptnBase{ + Project: "sockshop", + Stage: "dev", + Service: "carts", + TestStrategy: nil, + DeploymentStrategy: nil, + Tag: nil, + Image: nil, + Labels: nil, + } + + marshal, _ := json.Marshal(keptnBase) + incomingEvent.Data = marshal + + incomingEvent.SetData(marshal) + incomingEvent.DataEncoded = true + incomingEvent.DataBinary = true + + type args struct { + incomingEvent *cloudevents.Event + opts KeptnOpts + } + tests := []struct { + name string + args args + want *Keptn + }{ + { + name: "Get 'in-cluster' Keptn", + args: args{ + incomingEvent: &incomingEvent, + opts: KeptnOpts{}, + }, + want: &Keptn{ + KeptnBase: keptnBase, + KeptnContext: "test-context", + eventBrokerURL: defaultEventBrokerURL, + useLocalFileSystem: false, + resourceHandler: &api.ResourceHandler{ + BaseURL: configurationServiceURL, + AuthHeader: "", + AuthToken: "", + HTTPClient: &http.Client{}, + Scheme: "http", + }, + eventHandler: &api.EventHandler{ + BaseURL: configurationServiceURL, + AuthToken: "", + AuthHeader: "", + HTTPClient: nil, + Scheme: "", + }, + }, + }, + { + name: "Get local Keptn", + args: args{ + incomingEvent: &incomingEvent, + opts: KeptnOpts{ + UseLocalFileSystem: true, + ConfigurationServiceURL: "", + EventBrokerURL: "", + }, + }, + want: &Keptn{ + KeptnBase: &KeptnBase{ + Project: "sockshop", + Stage: "dev", + Service: "carts", + TestStrategy: nil, + DeploymentStrategy: nil, + Tag: nil, + Image: nil, + Labels: nil, + }, + KeptnContext: "test-context", + eventBrokerURL: defaultEventBrokerURL, + useLocalFileSystem: true, + resourceHandler: &api.ResourceHandler{ + BaseURL: configurationServiceURL, + AuthHeader: "", + AuthToken: "", + HTTPClient: &http.Client{}, + Scheme: "http", + }, + eventHandler: &api.EventHandler{ + BaseURL: configurationServiceURL, + AuthToken: "", + AuthHeader: "", + HTTPClient: nil, + Scheme: "", + }, + }, + }, + { + name: "Get Keptn with custom configuration service URL", + args: args{ + incomingEvent: &incomingEvent, + opts: KeptnOpts{ + UseLocalFileSystem: false, + ConfigurationServiceURL: "custom-config:8080", + EventBrokerURL: "", + }, + }, + want: &Keptn{ + KeptnBase: &KeptnBase{ + Project: "sockshop", + Stage: "dev", + Service: "carts", + TestStrategy: nil, + DeploymentStrategy: nil, + Tag: nil, + Image: nil, + Labels: nil, + }, + KeptnContext: "test-context", + eventBrokerURL: defaultEventBrokerURL, + useLocalFileSystem: false, + resourceHandler: &api.ResourceHandler{ + BaseURL: "custom-config:8080", + AuthHeader: "", + AuthToken: "", + HTTPClient: &http.Client{}, + Scheme: "http", + }, + eventHandler: &api.EventHandler{ + BaseURL: "custom-config:8080", + AuthToken: "", + AuthHeader: "", + HTTPClient: nil, + Scheme: "", + }, + }, + }, + { + name: "Get Keptn with custom event brokerURL", + args: args{ + incomingEvent: &incomingEvent, + opts: KeptnOpts{ + UseLocalFileSystem: false, + ConfigurationServiceURL: "custom-config:8080", + EventBrokerURL: "custom-eb:8080", + }, + }, + want: &Keptn{ + KeptnBase: &KeptnBase{ + Project: "sockshop", + Stage: "dev", + Service: "carts", + TestStrategy: nil, + DeploymentStrategy: nil, + Tag: nil, + Image: nil, + Labels: nil, + }, + KeptnContext: "test-context", + eventBrokerURL: "custom-eb:8080", + useLocalFileSystem: false, + resourceHandler: &api.ResourceHandler{ + BaseURL: "custom-config:8080", + AuthHeader: "", + AuthToken: "", + HTTPClient: &http.Client{}, + Scheme: "http", + }, + eventHandler: &api.EventHandler{ + BaseURL: "custom-config:8080", + AuthToken: "", + AuthHeader: "", + HTTPClient: nil, + Scheme: "", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got, _ := NewKeptn(tt.args.incomingEvent, tt.args.opts); deep.Equal(got, tt.want) != nil { + t.Errorf("NewKeptn() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestKeptn_GetKeptnResource(t *testing.T) { + + ts := httptest.NewServer( + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(200) + + res := &models.Resource{ + ResourceContent: "dGVzdC1jb250ZW50Cg==", + ResourceURI: stringp("test-resource.file"), + } + marshal, _ := json.Marshal(res) + w.Write(marshal) + }), + ) + defer ts.Close() + + type fields struct { + KeptnBase *KeptnBase + KeptnContext string + eventBrokerURL string + useLocalFileSystem bool + resourceHandler *api.ResourceHandler + } + type args struct { + resource string + } + tests := []struct { + name string + fields fields + args args + want string + wantErr bool + }{ + { + name: "get a resource", + fields: fields{ + KeptnBase: &KeptnBase{ + Project: "sockshop", + Stage: "dev", + Service: "carts", + TestStrategy: nil, + DeploymentStrategy: nil, + Tag: nil, + Image: nil, + Labels: nil, + }, + eventBrokerURL: "", + useLocalFileSystem: false, + resourceHandler: api.NewResourceHandler(ts.URL), + }, + args: args{ + resource: "test-resource.file", + }, + want: "test-content", + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + k := &Keptn{ + KeptnBase: tt.fields.KeptnBase, + KeptnContext: tt.fields.KeptnContext, + eventBrokerURL: tt.fields.eventBrokerURL, + useLocalFileSystem: tt.fields.useLocalFileSystem, + resourceHandler: tt.fields.resourceHandler, + } + got, err := k.GetKeptnResource(tt.args.resource) + if (err != nil) != tt.wantErr { + t.Errorf("GetKeptnResource() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GetKeptnResource() got = %v, want %v", got, tt.want) + } + _ = os.RemoveAll(tt.args.resource) + }) + } +} + +// generateStringWithSpecialChars generates a string of the given length +// and containing at least one special character and digit. +func generateStringWithSpecialChars(length int) string { + rand.Seed(time.Now().UnixNano()) + + digits := "0123456789" + specials := "~=+%^*/()[]{}/!@#$?|" + all := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + + digits + specials + + buf := make([]byte, length) + buf[0] = digits[rand.Intn(len(digits))] + buf[1] = specials[rand.Intn(len(specials))] + + for i := 2; i < length; i++ { + buf[i] = all[rand.Intn(len(all))] + } + + rand.Shuffle(len(buf), func(i, j int) { + buf[i], buf[j] = buf[j], buf[i] + }) + + str := string(buf) + + return str +} + +// TestInvalidKeptnEntityName tests whether a random string containing a special character or digit +// does not pass the name validation. +func TestInvalidKeptnEntityName(t *testing.T) { + invalidName := generateStringWithSpecialChars(8) + if ValidateKeptnEntityName(invalidName) { + t.Fatalf("%s starts with upper case letter(s) or contains special character(s), but passed the name validation", invalidName) + } +} + +func TestInvalidKeptnEntityName2(t *testing.T) { + if ValidateKeptnEntityName("sockshop-") { + t.Fatalf("project name must not end with hyphen") + } +} + +func TestValidKeptnEntityName(t *testing.T) { + if !ValidateKeptnEntityName("sockshop-test") { + t.Fatalf("project should be valid") + } +} + +// TestAddResourceContentToSLIMap +func TestAddResourceContentToSLIMap(t *testing.T) { + SLIs := make(map[string]string) + resource := &models.Resource{} + resourceURI := "provider/sli.yaml" + resource.ResourceURI = &resourceURI + resource.ResourceContent = `--- +indicators: + error_rate: "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p50: "builtin:service.response.time:merge(0):percentile(50)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p90: "builtin:service.response.time:merge(0):percentile(90)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p95: "builtin:service.response.time:merge(0):percentile(95)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + throughput: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" +` + SLIs, _ = addResourceContentToSLIMap(SLIs, resource) + + if len(SLIs) != 5 { + t.Errorf("Unexpected lenght of SLI map") + } +} + +// TestAddResourceContentToSLIMap +func TestAddMultipleResourceContentToSLIMap(t *testing.T) { + SLIs := make(map[string]string) + resource := &models.Resource{} + resourceURI := "provider/sli.yaml" + resource.ResourceURI = &resourceURI + resource.ResourceContent = `--- +indicators: + error_rate: "not defined" + response_time_p50: "builtin:service.response.time:merge(0):percentile(50)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p90: "builtin:service.response.time:merge(0):percentile(90)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + response_time_p95: "builtin:service.response.time:merge(0):percentile(95)?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + throughput: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" +` + SLIs, _ = addResourceContentToSLIMap(SLIs, resource) + + resource.ResourceContent = `--- +indicators: + error_rate: "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" + failure_rate: "builtin:service.requestCount.total:merge(0):count?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" +` + SLIs, _ = addResourceContentToSLIMap(SLIs, resource) + + if len(SLIs) != 6 { + t.Errorf("Unexpected length of SLI map") + } + + if SLIs["error_rate"] != "builtin:service.errors.total.count:merge(0):avg?scope=tag(keptn_project:$PROJECT),tag(keptn_stage:$STAGE),tag(keptn_service:$SERVICE),tag(keptn_deployment:$DEPLOYMENT)" { + t.Errorf("Unexpected value of error_rate SLI") + } +} + +func stringp(s string) *string { + return &s +} diff --git a/pkg/utils/logger.go b/pkg/lib/logger.go similarity index 99% rename from pkg/utils/logger.go rename to pkg/lib/logger.go index 3da0eaca..3fa7353b 100644 --- a/pkg/utils/logger.go +++ b/pkg/lib/logger.go @@ -1,4 +1,4 @@ -package utils +package keptn import ( "encoding/json" diff --git a/pkg/models/remediations.go b/pkg/lib/remediations.go similarity index 97% rename from pkg/models/remediations.go rename to pkg/lib/remediations.go index 9a141304..1de27756 100644 --- a/pkg/models/remediations.go +++ b/pkg/lib/remediations.go @@ -1,4 +1,4 @@ -package models +package keptn // Remediations contains remediation definitions for a service type Remediations struct { diff --git a/pkg/models/v2/service_level_objectives.go b/pkg/lib/service_level_objectives.go similarity index 99% rename from pkg/models/v2/service_level_objectives.go rename to pkg/lib/service_level_objectives.go index 17b42dde..b20cb201 100644 --- a/pkg/models/v2/service_level_objectives.go +++ b/pkg/lib/service_level_objectives.go @@ -1,4 +1,4 @@ -package v2 +package keptn type SLOComparison struct { CompareWith string `json:"compare_with" yaml:"compare_with"` // single_result|several_results diff --git a/pkg/models/shipyard.go b/pkg/lib/shipyard.go similarity index 96% rename from pkg/models/shipyard.go rename to pkg/lib/shipyard.go index 36b8e204..400f3b5c 100644 --- a/pkg/models/shipyard.go +++ b/pkg/lib/shipyard.go @@ -1,4 +1,4 @@ -package models +package keptn // Shipyard defines the name, deployment strategy and test strategy of each stage type Shipyard struct { diff --git a/pkg/utils/websocketutil.go b/pkg/lib/websocketutil.go similarity index 99% rename from pkg/utils/websocketutil.go rename to pkg/lib/websocketutil.go index b77ba6e0..c475c7e8 100644 --- a/pkg/utils/websocketutil.go +++ b/pkg/lib/websocketutil.go @@ -1,4 +1,4 @@ -package utils +package keptn import ( "encoding/json" diff --git a/pkg/models/service_indicators.go b/pkg/models/service_indicators.go deleted file mode 100644 index 97b5f5a5..00000000 --- a/pkg/models/service_indicators.go +++ /dev/null @@ -1,19 +0,0 @@ -package models - -// ServiceIndicators contains the definition of service indicators -type ServiceIndicators struct { - Indicators []*ServiceIndicator `json:"indicators" yaml:"indicators"` -} - -// ServiceIndicator describes a service indicator -type ServiceIndicator struct { - Metric string `json:"metric" yaml:"metric"` - Source string `json:"source" yaml:"source"` - Query string `json:"query" yaml:"query"` - QueryObject []*ServiceIndicatorQueryObject `json:"queryObject" yaml:"queryObject"` -} - -type ServiceIndicatorQueryObject struct { - Key string `json:"key" yaml:"key"` - Value string `json:"value" yaml:"value"` -} diff --git a/pkg/models/service_objectives.go b/pkg/models/service_objectives.go deleted file mode 100644 index 99f87981..00000000 --- a/pkg/models/service_objectives.go +++ /dev/null @@ -1,16 +0,0 @@ -package models - -// ServiceObjectives describes objectives for a service -type ServiceObjectives struct { - Pass int `json:"pass" yaml:"pass"` - Warning int `json:"warning" yaml:"warning"` - Objectives []*ServiceObjective `json:"objectives" yaml:"objectives"` -} - -// ServiceObjective describes a service objective -type ServiceObjective struct { - Metric string `json:"metric" yaml:"metric"` - Threshold float32 `json:"threshold" yaml:"threshold"` - Timeframe string `json:"timeframe" yaml:"timeframe"` - Score float32 `json:"score" yaml:"score"` -} diff --git a/pkg/mongodb-datastore/models/contenttype.go b/pkg/mongodb-datastore/models/contenttype.go deleted file mode 100644 index 1ab19ad2..00000000 --- a/pkg/mongodb-datastore/models/contenttype.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Contenttype contenttype -// swagger:model contenttype -type Contenttype string - -// Validate validates this contenttype -func (m Contenttype) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/mongodb-datastore/models/data.go b/pkg/mongodb-datastore/models/data.go deleted file mode 100644 index 3c7d4098..00000000 --- a/pkg/mongodb-datastore/models/data.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -// Data data -// swagger:model data -type Data interface{} diff --git a/pkg/mongodb-datastore/models/error.go b/pkg/mongodb-datastore/models/error.go deleted file mode 100644 index 9a60acf0..00000000 --- a/pkg/mongodb-datastore/models/error.go +++ /dev/null @@ -1,70 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// Error error -// swagger:model error -type Error struct { - - // code - Code int64 `json:"code,omitempty"` - - // fields - Fields string `json:"fields,omitempty"` - - // message - // Required: true - Message *string `json:"message"` -} - -// Validate validates this error -func (m *Error) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateMessage(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *Error) validateMessage(formats strfmt.Registry) error { - - if err := validate.Required("message", "body", m.Message); err != nil { - return err - } - - return nil -} - -// MarshalBinary interface implementation -func (m *Error) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Error) UnmarshalBinary(b []byte) error { - var res Error - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/mongodb-datastore/models/event.go b/pkg/mongodb-datastore/models/event.go deleted file mode 100644 index 85d36c48..00000000 --- a/pkg/mongodb-datastore/models/event.go +++ /dev/null @@ -1,179 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" -) - -// Event event -// swagger:model event -type Event struct { - - // contenttype - Contenttype Contenttype `json:"contenttype,omitempty"` - - // data - Data Data `json:"data,omitempty"` - - // extensions - Extensions Extensions `json:"extensions,omitempty"` - - // id - // Required: true - ID ID `json:"id"` - - // source - // Required: true - Source Source `json:"source"` - - // specversion - // Required: true - Specversion Specversion `json:"specversion"` - - // time - // Format: date-time - Time Time `json:"time,omitempty"` - - // type - // Required: true - Type Type `json:"type"` -} - -// Validate validates this event -func (m *Event) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateContenttype(formats); err != nil { - res = append(res, err) - } - - if err := m.validateID(formats); err != nil { - res = append(res, err) - } - - if err := m.validateSource(formats); err != nil { - res = append(res, err) - } - - if err := m.validateSpecversion(formats); err != nil { - res = append(res, err) - } - - if err := m.validateTime(formats); err != nil { - res = append(res, err) - } - - if err := m.validateType(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *Event) validateContenttype(formats strfmt.Registry) error { - - if swag.IsZero(m.Contenttype) { // not required - return nil - } - - if err := m.Contenttype.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("contenttype") - } - return err - } - - return nil -} - -func (m *Event) validateID(formats strfmt.Registry) error { - - if err := m.ID.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("id") - } - return err - } - - return nil -} - -func (m *Event) validateSource(formats strfmt.Registry) error { - - if err := m.Source.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("source") - } - return err - } - - return nil -} - -func (m *Event) validateSpecversion(formats strfmt.Registry) error { - - if err := m.Specversion.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("specversion") - } - return err - } - - return nil -} - -func (m *Event) validateTime(formats strfmt.Registry) error { - - if swag.IsZero(m.Time) { // not required - return nil - } - - if err := m.Time.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("time") - } - return err - } - - return nil -} - -func (m *Event) validateType(formats strfmt.Registry) error { - - if err := m.Type.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("type") - } - return err - } - - return nil -} - -// MarshalBinary interface implementation -func (m *Event) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Event) UnmarshalBinary(b []byte) error { - var res Event - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/mongodb-datastore/models/events.go b/pkg/mongodb-datastore/models/events.go deleted file mode 100644 index 350e486d..00000000 --- a/pkg/mongodb-datastore/models/events.go +++ /dev/null @@ -1,86 +0,0 @@ -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the generate command - -import ( - "strconv" - - errors "github.com/go-openapi/errors" - strfmt "github.com/go-openapi/strfmt" - swag "github.com/go-openapi/swag" -) - -// Events get events o k body -// swagger:model GetEventsOKBody -type Events struct { - - // events - Events []*KeptnContextExtendedCE `json:"events"` - - // Pointer to the next page - NextPageKey string `json:"nextPageKey,omitempty"` - - // Size of the returned page - PageSize int64 `json:"pageSize,omitempty"` - - // Total number of events - TotalCount int64 `json:"totalCount,omitempty"` -} - -// Validate validates this get events o k body -func (o *Events) Validate(formats strfmt.Registry) error { - var res []error - - if err := o.validateEvents(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (o *Events) validateEvents(formats strfmt.Registry) error { - - if swag.IsZero(o.Events) { // not required - return nil - } - - for i := 0; i < len(o.Events); i++ { - if swag.IsZero(o.Events[i]) { // not required - continue - } - - if o.Events[i] != nil { - if err := o.Events[i].Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("getEventsOK" + "." + "events" + "." + strconv.Itoa(i)) - } - return err - } - } - - } - - return nil -} - -// MarshalBinary interface implementation -func (o *Events) MarshalBinary() ([]byte, error) { - if o == nil { - return nil, nil - } - return swag.WriteJSON(o) -} - -// UnmarshalBinary interface implementation -func (o *Events) UnmarshalBinary(b []byte) error { - var res Events - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *o = res - return nil -} diff --git a/pkg/mongodb-datastore/models/extensions.go b/pkg/mongodb-datastore/models/extensions.go deleted file mode 100644 index d098318b..00000000 --- a/pkg/mongodb-datastore/models/extensions.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -// Extensions extensions -// swagger:model extensions -type Extensions interface{} diff --git a/pkg/mongodb-datastore/models/id.go b/pkg/mongodb-datastore/models/id.go deleted file mode 100644 index 7ff8ceed..00000000 --- a/pkg/mongodb-datastore/models/id.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// ID id -// swagger:model id -type ID string - -// Validate validates this id -func (m ID) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/mongodb-datastore/models/keptn_context_extended_c_e.go b/pkg/mongodb-datastore/models/keptn_context_extended_c_e.go deleted file mode 100644 index f2540a81..00000000 --- a/pkg/mongodb-datastore/models/keptn_context_extended_c_e.go +++ /dev/null @@ -1,102 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" -) - -// KeptnContextExtendedCE keptn context extended c e -// swagger:model KeptnContextExtendedCE -type KeptnContextExtendedCE struct { - Event - - // shkeptncontext - Shkeptncontext string `json:"shkeptncontext,omitempty"` -} - -// UnmarshalJSON unmarshals this object from a JSON structure -func (m *KeptnContextExtendedCE) UnmarshalJSON(raw []byte) error { - // AO0 - var aO0 Event - if err := swag.ReadJSON(raw, &aO0); err != nil { - return err - } - m.Event = aO0 - - // AO1 - var dataAO1 struct { - Shkeptncontext string `json:"shkeptncontext,omitempty"` - } - if err := swag.ReadJSON(raw, &dataAO1); err != nil { - return err - } - - m.Shkeptncontext = dataAO1.Shkeptncontext - - return nil -} - -// MarshalJSON marshals this object to a JSON structure -func (m KeptnContextExtendedCE) MarshalJSON() ([]byte, error) { - _parts := make([][]byte, 0, 2) - - aO0, err := swag.WriteJSON(m.Event) - if err != nil { - return nil, err - } - _parts = append(_parts, aO0) - - var dataAO1 struct { - Shkeptncontext string `json:"shkeptncontext,omitempty"` - } - - dataAO1.Shkeptncontext = m.Shkeptncontext - - jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1) - if errAO1 != nil { - return nil, errAO1 - } - _parts = append(_parts, jsonDataAO1) - - return swag.ConcatJSON(_parts...), nil -} - -// Validate validates this keptn context extended c e -func (m *KeptnContextExtendedCE) Validate(formats strfmt.Registry) error { - var res []error - - // validation for a type composition with Event - if err := m.Event.Validate(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -// MarshalBinary interface implementation -func (m *KeptnContextExtendedCE) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *KeptnContextExtendedCE) UnmarshalBinary(b []byte) error { - var res KeptnContextExtendedCE - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/mongodb-datastore/models/log_entry.go b/pkg/mongodb-datastore/models/log_entry.go deleted file mode 100644 index bb965638..00000000 --- a/pkg/mongodb-datastore/models/log_entry.go +++ /dev/null @@ -1,83 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// LogEntry log entry -// swagger:model LogEntry -type LogEntry struct { - - // event Id - EventID string `json:"eventId,omitempty"` - - // keptn context - KeptnContext string `json:"keptnContext,omitempty"` - - // keptn service - KeptnService string `json:"keptnService,omitempty"` - - // log level - LogLevel string `json:"logLevel,omitempty"` - - // message - Message string `json:"message,omitempty"` - - // timestamp - // Format: date-time - Timestamp strfmt.DateTime `json:"timestamp,omitempty"` -} - -// Validate validates this log entry -func (m *LogEntry) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateTimestamp(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *LogEntry) validateTimestamp(formats strfmt.Registry) error { - - if swag.IsZero(m.Timestamp) { // not required - return nil - } - - if err := validate.FormatOf("timestamp", "body", "date-time", m.Timestamp.String(), formats); err != nil { - return err - } - - return nil -} - -// MarshalBinary interface implementation -func (m *LogEntry) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *LogEntry) UnmarshalBinary(b []byte) error { - var res LogEntry - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/mongodb-datastore/models/source.go b/pkg/mongodb-datastore/models/source.go deleted file mode 100644 index 9ef1769a..00000000 --- a/pkg/mongodb-datastore/models/source.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Source source -// swagger:model source -type Source string - -// Validate validates this source -func (m Source) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/mongodb-datastore/models/specversion.go b/pkg/mongodb-datastore/models/specversion.go deleted file mode 100644 index 5dea0caf..00000000 --- a/pkg/mongodb-datastore/models/specversion.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Specversion specversion -// swagger:model specversion -type Specversion string - -// Validate validates this specversion -func (m Specversion) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/mongodb-datastore/models/time.go b/pkg/mongodb-datastore/models/time.go deleted file mode 100644 index fbc3e48d..00000000 --- a/pkg/mongodb-datastore/models/time.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// Time time -// swagger:model time -type Time strfmt.DateTime - -// UnmarshalJSON sets a Time value from JSON input -func (m *Time) UnmarshalJSON(b []byte) error { - return ((*strfmt.DateTime)(m)).UnmarshalJSON(b) -} - -// MarshalJSON retrieves a Time value as JSON output -func (m Time) MarshalJSON() ([]byte, error) { - return (strfmt.DateTime(m)).MarshalJSON() -} - -// Validate validates this time -func (m Time) Validate(formats strfmt.Registry) error { - var res []error - - if err := validate.FormatOf("", "body", "date-time", strfmt.DateTime(m).String(), formats); err != nil { - return err - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -// MarshalBinary interface implementation -func (m *Time) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Time) UnmarshalBinary(b []byte) error { - var res Time - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/mongodb-datastore/models/type.go b/pkg/mongodb-datastore/models/type.go deleted file mode 100644 index 80ec79f8..00000000 --- a/pkg/mongodb-datastore/models/type.go +++ /dev/null @@ -1,19 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - strfmt "github.com/go-openapi/strfmt" -) - -// Type type -// swagger:model type -type Type string - -// Validate validates this type -func (m Type) Validate(formats strfmt.Registry) error { - return nil -} diff --git a/pkg/mongodb-datastore/utils/datastoreUtils.go b/pkg/mongodb-datastore/utils/datastoreUtils.go deleted file mode 100644 index 31ed13f8..00000000 --- a/pkg/mongodb-datastore/utils/datastoreUtils.go +++ /dev/null @@ -1,26 +0,0 @@ -package utils - -import ( - "net/http" - - "github.com/keptn/go-utils/pkg/mongodb-datastore/models" -) - -// Datastore represents the interface for accessing Keptn's datastore -type Datastore interface { - getBaseURL() string - getAuthToken() string - getAuthHeader() string - getHTTPClient() *http.Client -} - -func buildErrorResponse(errorStr string) *models.Error { - err := models.Error{Message: &errorStr} - return &err -} - -func addAuthHeader(req *http.Request, datastore Datastore) { - if datastore.getAuthHeader() != "" && datastore.getAuthToken() != "" { - req.Header.Set(datastore.getAuthHeader(), datastore.getAuthToken()) - } -} diff --git a/pkg/utils/fileUtils.go b/pkg/utils/fileUtils.go deleted file mode 100644 index 88ca8ca5..00000000 --- a/pkg/utils/fileUtils.go +++ /dev/null @@ -1,64 +0,0 @@ -package utils - -import ( - "fmt" - "os" - "path/filepath" - "runtime" - "strings" -) - -const keptnFolderName = ".keptn" - -// GetKeptnDirectory returns a path, which is used to store logs and possibly creds -func GetKeptnDirectory() (string, error) { - - keptnDir := UserHomeDir() + string(os.PathSeparator) + keptnFolderName + string(os.PathSeparator) - - if _, err := os.Stat(keptnDir); os.IsNotExist(err) { - err := os.MkdirAll(keptnDir, os.ModePerm) - fmt.Println("keptn creates the folder " + keptnDir + " to store logs and possibly creds.") - if err != nil { - return "", err - } - } - - return keptnDir, nil -} - -// UserHomeDir returns the HOME directory by taking into account the operating system -func UserHomeDir() string { - if runtime.GOOS == "windows" { - home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") - if home == "" { - home = os.Getenv("USERPROFILE") - } - return home - } - return os.Getenv("HOME") -} - -// ExpandTilde expands ~ to HOME -func ExpandTilde(fileName string) string { - if fileName == "~" { - return UserHomeDir() - } else if strings.HasPrefix(fileName, "~/") { - return filepath.Join(UserHomeDir(), fileName[2:]) - } - return fileName -} - -// GetFiles returns a list of files in a directory filtered by the provided suffix -func GetFiles(workingPath string, suffixes ...string) ([]string, error) { - var files []string - err := filepath.Walk(workingPath, func(path string, info os.FileInfo, err error) error { - for _, suffix := range suffixes { - if strings.HasSuffix(path, suffix) { - files = append(files, path) - break - } - } - return nil - }) - return files, err -} diff --git a/pkg/utils/gitHubUtils.go b/pkg/utils/gitHubUtils.go deleted file mode 100644 index 1ffeda10..00000000 --- a/pkg/utils/gitHubUtils.go +++ /dev/null @@ -1,98 +0,0 @@ -package utils - -import ( - "fmt" - "os" - - "gopkg.in/src-d/go-git.v4" - "gopkg.in/src-d/go-git.v4/config" - "gopkg.in/src-d/go-git.v4/plumbing" - "gopkg.in/src-d/go-git.v4/plumbing/transport/http" -) - -// Checkout clons a GitHub repo and checks out the specified branch -func Checkout(gitHubOrg string, project string, branch string) (*git.Repository, error) { - - err := os.RemoveAll(project) - if err != nil { - return nil, err - } - - var repo *git.Repository - if os.Getenv("GITHUB_USERNAME") != "" && os.Getenv("GITHUB_TOKEN") != "" { - // If credentials are available, use them - repo, err = git.PlainClone(project, false, &git.CloneOptions{ - URL: "https://github.com/" + gitHubOrg + "/" + project + ".git", - Auth: &http.BasicAuth{ - Username: os.Getenv("GITHUB_USERNAME"), // anything except an empty string - Password: os.Getenv("GITHUB_TOKEN"), - }, - }) - } else { - repo, err = git.PlainClone(project, false, &git.CloneOptions{ - URL: "https://github.com/" + gitHubOrg + "/" + project + ".git", - }) - } - w, err := repo.Worktree() - if err != nil { - return nil, err - } - - err = repo.Fetch(&git.FetchOptions{ - RefSpecs: []config.RefSpec{"refs/*:refs/*", "HEAD:refs/heads/HEAD"}, - }) - if err != nil { - return nil, err - } - - // Checking out branch - return repo, w.Checkout(&git.CheckoutOptions{ - Branch: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", branch)), - Force: true, - }) -} - -// CheckoutPrevCommit moves the HEAD pointer to the previous commit. It returns the original HEAD. -func CheckoutPrevCommit(repo *git.Repository) (*plumbing.Reference, error) { - - ref, err := repo.Head() - if err != nil { - return nil, err - } - - commitIter, err := repo.Log(&git.LogOptions{From: ref.Hash()}) - if err != nil { - return nil, err - } - - _, err = commitIter.Next() - if err != nil { - return nil, err - } - c, err := commitIter.Next() - if err != nil { - return nil, err - } - - w, err := repo.Worktree() - if err != nil { - return nil, err - } - - return ref, w.Checkout(&git.CheckoutOptions{ - Hash: c.Hash, - }) -} - -// CheckoutReference moves the HEAD pointer to the specified reference. -func CheckoutReference(repo *git.Repository, ref *plumbing.Reference) error { - - w, err := repo.Worktree() - if err != nil { - return err - } - - return w.Checkout(&git.CheckoutOptions{ - Hash: ref.Hash(), - }) -} diff --git a/pkg/utils/helmUtils.go b/pkg/utils/helmUtils.go deleted file mode 100644 index 9dc7af43..00000000 --- a/pkg/utils/helmUtils.go +++ /dev/null @@ -1,187 +0,0 @@ -package utils - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "strings" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - kyaml "k8s.io/apimachinery/pkg/util/yaml" - "k8s.io/helm/pkg/chartutil" - "k8s.io/helm/pkg/proto/hapi/chart" - "k8s.io/helm/pkg/renderutil" - "k8s.io/helm/pkg/timeconv" - - "github.com/keptn/go-utils/pkg/configuration-service/models" - "github.com/keptn/go-utils/pkg/configuration-service/utils" -) - -func getHelmChartURI(chartName string) string { - return "helm/" + chartName + ".tgz" -} - -// StoreChart stores a chart in the configuration service -func StoreChart(project string, service string, stage string, chartName string, helmChart []byte, configServiceURL string) error { - resourceHandler := utils.NewResourceHandler(configServiceURL) - - uri := getHelmChartURI(chartName) - resource := models.Resource{ResourceURI: &uri, ResourceContent: string(helmChart)} - - _, err := resourceHandler.CreateServiceResources(project, stage, service, []*models.Resource{&resource}) - if err != nil { - return fmt.Errorf("Error when storing chart %s of service %s in project %s: %s", - chartName, service, project, err.Error()) - } - return nil -} - -// GetChart reads the chart from the configuration service -func GetChart(project string, service string, stage string, chartName string, configServiceURL string) (*chart.Chart, error) { - resourceHandler := utils.NewResourceHandler(configServiceURL) - - resource, err := resourceHandler.GetServiceResource(project, stage, service, getHelmChartURI(chartName)) - if err != nil { - return nil, fmt.Errorf("Error when reading chart %s from project %s: %s", - chartName, project, err.Error()) - } - - ch, err := LoadChart([]byte(resource.ResourceContent)) - if err != nil { - return nil, fmt.Errorf("Error when reading chart %s from project %s: %s", - chartName, project, err.Error()) - } - return ch, nil -} - -// LoadChart converts a byte array into a Chart -func LoadChart(data []byte) (*chart.Chart, error) { - return chartutil.LoadArchive(bytes.NewReader(data)) -} - -// LoadChartFromPath loads a directory or Helm chart into a Chart -func LoadChartFromPath(path string) (*chart.Chart, error) { - return chartutil.Load(path) -} - -// PackageChart packages the chart and returns it -func PackageChart(ch *chart.Chart) ([]byte, error) { - helmPackage, err := ioutil.TempDir("", "") - if err != nil { - return nil, fmt.Errorf("Error when packaging chart: %s", err.Error()) - } - defer os.RemoveAll(helmPackage) - - name, err := chartutil.Save(ch, helmPackage) - if err != nil { - return nil, fmt.Errorf("Error when packaging chart: %s", err.Error()) - } - - data, err := ioutil.ReadFile(name) - if err != nil { - return nil, fmt.Errorf("Error when packaging chart: %s", err.Error()) - } - return data, nil -} - -// GetRenderedDeployments returns all deployments contained in the provided chart -func GetRenderedDeployments(ch *chart.Chart) ([]*appsv1.Deployment, error) { - - renderOpts := renderutil.Options{ - ReleaseOptions: chartutil.ReleaseOptions{ - Name: ch.Metadata.Name, - IsInstall: false, - IsUpgrade: false, - Time: timeconv.Now(), - }, - } - ch.Values.Raw += ` -keptn: - project: prj, - service: svc, - deployment: dpl` - renderedTemplates, err := renderutil.Render(ch, ch.Values, renderOpts) - if err != nil { - return nil, err - } - - deployments := make([]*appsv1.Deployment, 0, 0) - - for _, v := range renderedTemplates { - dec := kyaml.NewYAMLToJSONDecoder(strings.NewReader(v)) - for { - var dpl appsv1.Deployment - err := dec.Decode(&dpl) - if err == io.EOF { - break - } - if err != nil { - fmt.Println(err) - continue - } - - if IsDeployment(&dpl) { - deployments = append(deployments, &dpl) - } - } - } - - return deployments, nil -} - -// GetRenderedServices returns all services contained in the provided chart -func GetRenderedServices(ch *chart.Chart) ([]*corev1.Service, error) { - - renderOpts := renderutil.Options{ - ReleaseOptions: chartutil.ReleaseOptions{ - Name: ch.Metadata.Name, - IsInstall: false, - IsUpgrade: false, - Time: timeconv.Now(), - }, - } - ch.Values.Raw += ` -keptn: - project: prj, - service: svc, - deployment: dpl` - renderedTemplates, err := renderutil.Render(ch, ch.Values, renderOpts) - if err != nil { - return nil, err - } - - services := make([]*corev1.Service, 0, 0) - - for _, v := range renderedTemplates { - dec := kyaml.NewYAMLToJSONDecoder(strings.NewReader(v)) - for { - var svc corev1.Service - err := dec.Decode(&svc) - if err == io.EOF { - break - } - if err != nil { - continue - } - - if IsService(&svc) { - services = append(services, &svc) - } - } - } - - return services, nil -} - -// IsService tests whether the provided struct is a service -func IsService(svc *corev1.Service) bool { - return strings.ToLower(svc.Kind) == "service" -} - -// IsDeployment tests whether the provided struct is a deployment -func IsDeployment(dpl *appsv1.Deployment) bool { - return strings.ToLower(dpl.Kind) == "deployment" -} diff --git a/pkg/utils/keptnUtils.go b/pkg/utils/keptnUtils.go deleted file mode 100644 index 5130cc25..00000000 --- a/pkg/utils/keptnUtils.go +++ /dev/null @@ -1,66 +0,0 @@ -package utils - -import ( - "log" - "regexp" - "strings" - - "github.com/keptn/go-utils/pkg/configuration-service/utils" - "github.com/keptn/go-utils/pkg/models" - "gopkg.in/yaml.v2" -) - -// KeptnHandler provides an interface to keptn resources -type KeptnHandler struct { - ResourceHandler *utils.ResourceHandler -} - -// NewKeptnHandler returns a new KeptnHandler instance -func NewKeptnHandler(rh *utils.ResourceHandler) *KeptnHandler { - return &KeptnHandler{ - ResourceHandler: rh, - } -} - -// GetShipyard returns the shipyard definition of a project -func (k *KeptnHandler) GetShipyard(project string) (*models.Shipyard, error) { - shipyardResource, err := k.ResourceHandler.GetProjectResource(project, "shipyard.yaml") - if err != nil { - return nil, err - } - - shipyard := models.Shipyard{} - err = yaml.Unmarshal([]byte(shipyardResource.ResourceContent), &shipyard) - if err != nil { - return nil, err - } - return &shipyard, nil -} - -// ValidateKeptnEntityName checks whether the provided name represents a valid -// project, service, or stage name -func ValidateKeptnEntityName(name string) bool { - if len(name) == 0 { - return false - } - reg, err := regexp.Compile(`(^[a-z][a-z0-9-]*[a-z0-9]$)|(^[a-z][a-z0-9]*)`) - if err != nil { - log.Fatal(err) - } - processedString := reg.FindString(name) - return len(processedString) == len(name) -} - -// ValididateUnixDirectoryName checks whether the provided dirName contains -// any special character according to -// https://www.cyberciti.biz/faq/linuxunix-rules-for-naming-file-and-directory-names/ -func ValididateUnixDirectoryName(dirName string) bool { - return !(dirName == "." || - dirName == ".." || - strings.Contains(dirName, "/") || - strings.Contains(dirName, ">") || - strings.Contains(dirName, "<") || - strings.Contains(dirName, "|") || - strings.Contains(dirName, ":") || - strings.Contains(dirName, "&")) -} diff --git a/pkg/utils/keptnUtils_test.go b/pkg/utils/keptnUtils_test.go deleted file mode 100644 index 85c9de6f..00000000 --- a/pkg/utils/keptnUtils_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package utils - -import ( - "math/rand" - "testing" - "time" -) - -// generateStringWithSpecialChars generates a string of the given length -// and containing at least one special character and digit. -func generateStringWithSpecialChars(length int) string { - rand.Seed(time.Now().UnixNano()) - - digits := "0123456789" - specials := "~=+%^*/()[]{}/!@#$?|" - all := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + - "abcdefghijklmnopqrstuvwxyz" + - digits + specials - - buf := make([]byte, length) - buf[0] = digits[rand.Intn(len(digits))] - buf[1] = specials[rand.Intn(len(specials))] - - for i := 2; i < length; i++ { - buf[i] = all[rand.Intn(len(all))] - } - - rand.Shuffle(len(buf), func(i, j int) { - buf[i], buf[j] = buf[j], buf[i] - }) - - str := string(buf) - - return str -} - -// TestInvalidKeptnEntityName tests whether a random string containing a special character or digit -// does not pass the name validation. -func TestInvalidKeptnEntityName(t *testing.T) { - invalidName := generateStringWithSpecialChars(8) - if ValidateKeptnEntityName(invalidName) { - t.Fatalf("%s starts with upper case letter(s) or contains special character(s), but passed the name validation", invalidName) - } -} - -func TestInvalidKeptnEntityName2(t *testing.T) { - if ValidateKeptnEntityName("sockshop-") { - t.Fatalf("project name must not end with hyphen") - } -} - -func TestValidKeptnEntityName(t *testing.T) { - if !ValidateKeptnEntityName("sockshop-test") { - t.Fatalf("project should be valid") - } -} diff --git a/pkg/utils/kubeUtils.go b/pkg/utils/kubeUtils.go deleted file mode 100644 index 2e81d655..00000000 --- a/pkg/utils/kubeUtils.go +++ /dev/null @@ -1,243 +0,0 @@ -package utils - -import ( - "fmt" - "path/filepath" - "strings" - "time" - - "k8s.io/client-go/kubernetes" - v1 "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/util/retry" - - appsv1 "k8s.io/api/apps/v1" - typesv1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - apierr "k8s.io/apimachinery/pkg/api/errors" - - // Initialize all known client auth plugins. - _ "github.com/Azure/go-autorest/autorest" - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" -) - -// DoHelmUpgrade executes a helm update and upgrade -func DoHelmUpgrade(project string, stage string) error { - helmChart := fmt.Sprintf("%s/helm-chart", project) - projectStage := fmt.Sprintf("%s-%s", project, stage) - _, err := ExecuteCommand("helm", []string{"init", "--client-only"}) - if err != nil { - return err - } - _, err = ExecuteCommand("helm", []string{"dep", "update", helmChart}) - if err != nil { - return err - } - _, err = ExecuteCommand("helm", []string{"upgrade", "--install", projectStage, helmChart, "--namespace", projectStage, "--wait"}) - return err -} - -// RestartPodsWithSelector restarts the pods which are found in the provided namespace and selector -func RestartPodsWithSelector(useInClusterConfig bool, namespace string, selector string) error { - clientset, err := GetKubeAPI(useInClusterConfig) - if err != nil { - return err - } - pods, err := clientset.Pods(namespace).List(metav1.ListOptions{LabelSelector: selector}) - if err != nil { - return err - } - for _, pod := range pods.Items { - if err := clientset.Pods(namespace).Delete(pod.Name, &metav1.DeleteOptions{}); err != nil { - return err - } - } - return nil -} - -func WaitForPodsWithSelector(useInClusterConfig bool, namespace string, selector string, - retries int, waitingTime time.Duration) error { - - clientset, err := GetKubeAPI(useInClusterConfig) - if err != nil { - return err - } - - for i := 0; i < retries; i++ { - pods, err := clientset.Pods(namespace).List(metav1.ListOptions{LabelSelector: selector}) - if err != nil { - return err - } - for _, pod := range pods.Items { - for _, cond := range pod.Status.Conditions { - if cond.Type != typesv1.PodReady { - time.Sleep(waitingTime) - break - } - } - } - } - return nil -} - -func ScaleDeployment(useInClusterConfig bool, deployment string, namespace string, replicas int32) error { - clientset, err := GetClientset(useInClusterConfig) - if err != nil { - return err - } - deploymentsClient := clientset.AppsV1().Deployments(namespace) - - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - // Retrieve the latest version of Deployment before attempting update - // RetryOnConflict uses exponential backoff to avoid exhausting the apiserver - result, getErr := deploymentsClient.Get(deployment, metav1.GetOptions{}) - if getErr != nil { - return fmt.Errorf("Failed to get latest version of Deployment: %v", getErr) - } - - result.Spec.Replicas = int32Ptr(replicas) - _, updateErr := deploymentsClient.Update(result) - return updateErr - }) - return retryErr -} - -func int32Ptr(i int32) *int32 { return &i } - -// WaitForDeploymentToBeRolledOut waits until the deployment is Available -func WaitForDeploymentToBeRolledOut(useInClusterConfig bool, deploymentName string, namespace string) error { - clientset, err := GetClientset(useInClusterConfig) - if err != nil { - return err - } - - deployment, err := getDeployment(clientset, namespace, deploymentName) - for { - - var cond *appsv1.DeploymentCondition - - for i := range deployment.Status.Conditions { - c := deployment.Status.Conditions[i] - if c.Type == appsv1.DeploymentProgressing { - cond = &c - break - } - } - - if cond != nil && cond.Reason == "ProgressDeadlineExceeded" { - return fmt.Errorf("Deployment %q exceeded its progress deadline", deployment.Name) - } - if !(deployment.Spec.Replicas != nil && deployment.Status.UpdatedReplicas < *deployment.Spec.Replicas || - deployment.Status.Replicas > deployment.Status.UpdatedReplicas || - deployment.Status.AvailableReplicas < deployment.Status.UpdatedReplicas) { - return nil - } - - time.Sleep(2 * time.Second) - deployment, err = getDeployment(clientset, namespace, deploymentName) - if err != nil { - return err - } - } -} - -// WaitForDeploymentsInNamespace waits until all deployments in a namespace are available -func WaitForDeploymentsInNamespace(useInClusterConfig bool, namespace string) error { - clientset, err := GetClientset(useInClusterConfig) - if err != nil { - return err - } - deps, err := clientset.AppsV1().Deployments(namespace).List(metav1.ListOptions{}) - for _, dep := range deps.Items { - if err := WaitForDeploymentToBeRolledOut(useInClusterConfig, dep.Name, namespace); err != nil { - return err - } - } - return nil -} - -func getDeployment(clientset *kubernetes.Clientset, namespace string, deploymentName string) (*appsv1.Deployment, error) { - dep, err := clientset.AppsV1().Deployments(namespace).Get(deploymentName, metav1.GetOptions{}) - if err != nil && - strings.Contains(err.Error(), "the object has been modified; please apply your changes to the latest version and try again") { - time.Sleep(10 * time.Second) - return clientset.AppsV1().Deployments(namespace).Get(deploymentName, metav1.GetOptions{}) - } - return dep, nil -} - -// GetKubeAPI returns the CoreV1Interface -func GetKubeAPI(useInClusterConfig bool) (v1.CoreV1Interface, error) { - - clientset, err := GetClientset(useInClusterConfig) - if err != nil { - return nil, err - } - - return clientset.CoreV1(), nil -} - -// GetClientset returns the kubernetes Clientset -func GetClientset(useInClusterConfig bool) (*kubernetes.Clientset, error) { - - var config *rest.Config - var err error - if useInClusterConfig { - config, err = rest.InClusterConfig() - } else { - kubeconfig := filepath.Join( - UserHomeDir(), ".kube", "config", - ) - config, err = clientcmd.BuildConfigFromFlags("", kubeconfig) - } - if err != nil { - return nil, err - } - - return kubernetes.NewForConfig(config) -} - -// GetKeptnDomain reads the configmap keptn-domain in namespace keptn and returns -// the contained app_domain -func GetKeptnDomain(useInClusterConfig bool) (string, error) { - api, err := GetKubeAPI(useInClusterConfig) - if err != nil { - return "", err - } - - cm, err := api.ConfigMaps("keptn").Get("keptn-domain", metav1.GetOptions{}) - if err != nil { - return "", err - } - return cm.Data["app_domain"], nil -} - -// CreateNamespace creates a new Kubernetes namespace with the provided name -func CreateNamespace(useInClusterConfig bool, namespace string) error { - - ns := &typesv1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}} - clientset, err := GetClientset(useInClusterConfig) - if err != nil { - return err - } - _, err = clientset.CoreV1().Namespaces().Create(ns) - return err -} - -// ExistsNamespace checks whether a namespace with the provided name exists -func ExistsNamespace(useInClusterConfig bool, namespace string) (bool, error) { - clientset, err := GetClientset(useInClusterConfig) - if err != nil { - return false, err - } - _, err = clientset.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) - if err != nil { - if statusErr, ok := err.(*apierr.StatusError); ok && statusErr.ErrStatus.Reason == metav1.StatusReasonNotFound { - return false, nil - } - return false, err - } - return true, nil -} diff --git a/swagger.yaml b/swagger.yaml new file mode 100644 index 00000000..f4451091 --- /dev/null +++ b/swagger.yaml @@ -0,0 +1,240 @@ +swagger: '2.0' + +info: + title: Keptn API Models + version: 0.1.0 + +definitions: + Error: + type: object + required: + - message + properties: + code: + type: integer + format: int64 + description: Error code + message: + type: string + description: Error message + + Version: + type: object + properties: + version: + type: string + description: Version identifier + + CreateProject: + type: object + required: + - name + - shipyard + properties: + name: + type: string + shipyard: + type: string + gitUser: + type: string + gitToken: + type: string + gitRemoteURL: + type: string + + Project: + type: object + properties: + projectName: + type: string + description: Project name + gitUser: + type: string + description: Git User + gitRemoteURI: + type: string + description: Git remote URI + gitToken: + type: string + description: Git token + stages: + type: array + items: + $ref: '#/definitions/Stage' + + Projects: + type: object + properties: + nextPageKey: + type: string + description: Pointer to next page, base64 encoded + totalCount: + type: number + description: Total number of projects + pageSize: + type: number + description: Size of returned page + projects: + type: array + items: + $ref: '#/definitions/Project' + + Stage: + type: object + properties: + stageName: + type: string + description: Stage name + services: + type: array + items: + $ref: '#/definitions/Service' + + Stages: + type: object + properties: + nextPageKey: + type: string + description: Pointer to next page, base64 encoded + totalCount: + type: number + description: Total number of stages + pageSize: + type: number + description: Size of returned page + stages: + type: array + items: + $ref: '#/definitions/Stage' + + + CreateService: + type: object + required: + - serviceName + properties: + serviceName: + type: string + helmChart: + type: string + deploymentStrategies: + type: object + additionalProperties: + type: string + Service: + type: object + properties: + serviceName: + type: string + description: Service name + + Services: + type: object + properties: + nextPageKey: + type: string + description: Pointer to next page, base64 encoded + totalCount: + type: number + description: Total number of services + pageSize: + type: number + description: Size of returned page + services: + type: array + items: + $ref: '#/definitions/Service' + + Resource: + type: object + required: + - resourceURI + properties: + resourceURI: + type: string + description: Resource URI + resourceContent: + type: string + # format: byte + description: Resource content + + Resources: + type: object + properties: + nextPageKey: + type: string + description: Pointer to next page, base64 encoded + totalCount: + type: number + description: Total number of resources + pageSize: + type: number + description: Size of returned page + resources: + type: array + items: + $ref: '#/definitions/Resource' + + EventContext: + type: object + required: + - token + - keptnContext + properties: + token: + type: string + keptnContext: + type: string + + KeptnContextExtendedCE: + type: object + properties: # CloudEvents v0.2 properties (https://raw.githubusercontent.com/cloudevents/spec/v0.2/spec.json#/definitions/event) + shkeptncontext: + type: string + specversion: + type: string + contenttype: + type: string + data: + type: ["object", "string"] + id: + type: string + time: + type: string + format: date-time + type: + type: string + extensions: + type: object + source: + format: uri-reference + type: string + required: + - data + - source + - type + + Events: + type: object + properties: + nextPageKey: + type: string + description: Pointer to next page, base64 encoded + totalCount: + type: number + description: Total number of resources + pageSize: + type: number + description: Size of returned page + events: + type: array + items: + $ref: '#/definitions/KeptnContextExtendedCE' + +# dummy path that is required by go-swagger +paths: + '/dummy': + get: + responses: + '200': + description: Success