diff --git a/devfile.yaml b/devfile.yaml index 89587661..b4490506 100644 --- a/devfile.yaml +++ b/devfile.yaml @@ -2,8 +2,8 @@ schemaVersion: 2.0.0 metadata: name: nodejs version: 1.0.0 - alpha.build-dockerfile: https://raw.githubusercontent.com/odo-devfiles/registry/master/devfiles/nodejs/build/Dockerfile - alpha.deployment-manifest: https://raw.githubusercontent.com/odo-devfiles/registry/master/devfiles/nodejs/deploy/deployment-manifest.yaml + attributes: + alpha.build-dockerfile: /relative/path/to/Dockerfile starterProjects: - name: nodejs-starter git: @@ -11,6 +11,34 @@ starterProjects: origin: https://github.com/odo-devfiles/nodejs-ex.git components: - name: runtime + attributes: + tool: console-import + import: + strategy: Dockerfile + container: + endpoints: + - name: http-3000 + targetPort: 3000 + image: registry.access.redhat.com/ubi8/nodejs-12:1-45 + memoryLimit: 1024Mi + mountSources: true + sourceMapping: /project +- name: runtime2 + attributes: + tool: odo + cli: + usage: deploy + container: + endpoints: + - name: http-3000 + targetPort: 3000 + image: registry.access.redhat.com/ubi8/nodejs-12:1-45 + memoryLimit: 1024Mi + mountSources: true + sourceMapping: /project +- name: runtime3 + attributes: + tool: workspace-operator container: endpoints: - name: http-3000 @@ -28,6 +56,9 @@ commands: kind: build workingDir: /project id: install + attributes: + tool: odo + mandatory: false - exec: commandLine: npm start component: runtime @@ -36,6 +67,9 @@ commands: kind: run workingDir: /project id: run + attributes: + tool: odo + mandatory: true - exec: commandLine: npm run debug component: runtime diff --git a/go.mod b/go.mod index 5c621420..4761fdb9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/devfile/library go 1.13 require ( - github.com/devfile/api v0.0.0-20201103130402-29b8738e196e + github.com/devfile/api v0.0.0-20201126204309-ec222215253e github.com/fatih/color v1.7.0 github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/gobwas/glob v0.2.3 @@ -11,17 +11,13 @@ require ( github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 github.com/mattn/go-colorable v0.1.2 // indirect github.com/mattn/go-isatty v0.0.12 // indirect - github.com/openshift/api v3.9.0+incompatible - github.com/pkg/errors v0.8.1 + github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f + github.com/pkg/errors v0.9.1 github.com/spf13/afero v1.2.2 github.com/stretchr/testify v1.6.1 // indirect github.com/xeipuuv/gojsonschema v1.2.0 - golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect - golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f // indirect - gopkg.in/yaml.v2 v2.3.0 // indirect - k8s.io/api v0.18.2 - k8s.io/apimachinery v0.18.2 + k8s.io/api v0.19.0 + k8s.io/apimachinery v0.19.0 k8s.io/klog v1.0.0 - sigs.k8s.io/controller-runtime v0.6.0 // indirect sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index 0f4ae009..66dbcc3e 100644 --- a/go.sum +++ b/go.sum @@ -10,7 +10,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -42,12 +41,11 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devfile/api v0.0.0-20201103130402-29b8738e196e h1:Ha6wyKs7VWqQTz2Fm1o4PAYpKX6SIiYjgWmGzNW8cBE= -github.com/devfile/api v0.0.0-20201103130402-29b8738e196e/go.mod h1:hp5Lmob7ESmtSZXZ7xRN9o8vemsen9111+ASi2YuXs4= +github.com/devfile/api v0.0.0-20201126204309-ec222215253e h1:NO6mS8ktVFjkVIKZKF2JjfL3ZxXw4VAtKIZWyp9e2kQ= +github.com/devfile/api v0.0.0-20201126204309-ec222215253e/go.mod h1:/aDiwWjDEW/fY1/Ig8umVtmneAXKZImnLvWqzMlcfrY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -56,7 +54,6 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -64,10 +61,13 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= @@ -77,6 +77,8 @@ github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0 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-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= 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= @@ -126,12 +128,12 @@ 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/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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 v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -139,17 +141,28 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y 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/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/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/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.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= @@ -159,6 +172,8 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= 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/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -171,19 +186,19 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -193,6 +208,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv 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/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= @@ -222,7 +239,6 @@ github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -230,18 +246,23 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs= -github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f h1:/msM59v15x4DaAZeJnQwkVsCGTEa1mx+nSSMehZVAHs= +github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f/go.mod h1:Si/I9UGeRR3qzg01YWPmtlr0GeGk2fnuggXJRmjAZ6U= +github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= @@ -249,7 +270,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= @@ -262,7 +284,7 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -285,7 +307,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM 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 v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= @@ -305,6 +326,7 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -322,19 +344,17 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 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= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -353,8 +373,11 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -374,24 +397,27 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190209173611-3b5209105503/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f h1:mOhmO9WsBaJCNmaZHPtHs9wOcdqdKCjF6OPJlmDM3KI= -golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -401,22 +427,20 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm 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-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/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= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/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-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -424,12 +448,24 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -449,7 +485,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl 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= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -459,51 +494,48 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 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-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4= -k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8= -k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= -k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs= -k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= -k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA= -k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo= -k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= -k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI= -k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE= -k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= -k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= -k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= -k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs= -k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= +k8s.io/api v0.18.6 h1:osqrAXbOQjkKIWDTjrqxWQ3w0GkKb1KA1XkUGHHYpeE= +k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI= +k8s.io/api v0.19.0 h1:XyrFIJqTYZJ2DU7FBE/bSPz7b1HvbVBuBf07oeo6eTc= +k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= +k8s.io/apiextensions-apiserver v0.18.6 h1:vDlk7cyFsDyfwn2rNAO2DbmUbvXy5yT5GE3rrqOzaMo= +k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKizADfvUM/SS/M= +k8s.io/apimachinery v0.18.6 h1:RtFHnfGNfd1N0LeSrKCUznz5xtUP1elRGvHJbL3Ntag= +k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apimachinery v0.19.0 h1:gjKnAda/HZp5k4xQYjL0K/Yb66IvNqjthCb03QlKpaQ= +k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= +k8s.io/apiserver v0.18.6/go.mod h1:Zt2XvTHuaZjBz6EFYzpp+X4hTmgWGy8AthNVnTdm3Wg= +k8s.io/client-go v0.18.6/go.mod h1:/fwtGLjYMS1MaM5oi+eXhKwG+1UHidUEXRh6cNsdO0Q= +k8s.io/code-generator v0.18.6/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= +k8s.io/component-base v0.18.6/go.mod h1:knSVsibPR5K6EW2XOjEHik6sdU5nCvKMrzMt2D4In14= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120 h1:RPscN6KhmG54S33L+lr3GS+oD1jmchIU0ll519K6FA4= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= 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/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM= -k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE= +k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= -sigs.k8s.io/controller-runtime v0.5.2/go.mod h1:JZUwSMVbxDupo0lTJSSFP5pimEyxGynROImSsqIOx1A= -sigs.k8s.io/controller-runtime v0.6.0 h1:Fzna3DY7c4BIP6KwfSlrfnj20DJ+SeMBK8HSFvOk9NM= -sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= +sigs.k8s.io/controller-runtime v0.6.3 h1:SBbr+inLPEKhvlJtrvDcwIpm+uhDvp63Bl72xYJtoOE= +sigs.k8s.io/controller-runtime v0.6.3/go.mod h1:WlZNXcM0++oyaQt4B7C2lEE5JYRs8vJUzRP4N4JpdAY= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/main.go b/main.go index 988953aa..e849288c 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( devfilepkg "github.com/devfile/library/pkg/devfile" "github.com/devfile/library/pkg/devfile/parser" v2 "github.com/devfile/library/pkg/devfile/parser/data/v2" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" ) func main() { @@ -17,20 +18,52 @@ func main() { devdata := devfile.Data if (reflect.TypeOf(devdata) == reflect.TypeOf(&v2.DevfileV2{})) { d := devdata.(*v2.DevfileV2) - fmt.Println(d.SchemaVersion) + fmt.Printf("schema version: %s\n", d.SchemaVersion) } - for _, component := range devfile.Data.GetComponents() { + compOptions := common.DevfileOptions{ + Filter: map[string]interface{}{ + "tool": "console-import", + "import": map[string]interface{}{ + "strategy": "Dockerfile", + }, + }, + } + + components, e := devfile.Data.GetComponents(compOptions) + if e != nil { + fmt.Printf("err: %v\n", err) + } + + for _, component := range components { if component.Container != nil { - fmt.Println(component.Container.Image) + fmt.Printf("component container: %s\n", component.Name) } } - for _, command := range devfile.Data.GetCommands() { + cmdOptions := common.DevfileOptions{ + Filter: map[string]interface{}{ + "tool": "odo", + }, + } + + commands, e := devfile.Data.GetCommands(cmdOptions) + if e != nil { + fmt.Printf("err: %v\n", err) + } + for _, command := range commands { if command.Exec != nil { - fmt.Println(command.Exec.Group.Kind) + fmt.Printf("exec command kind: %s\n", command.Exec.Group.Kind) } } + + var err error + metadataAttr := devfile.Data.GetMetadata().Attributes + dockerfilePath := metadataAttr.GetString("alpha.build-dockerfile", &err) + if err != nil { + fmt.Printf("err: %v\n", err) + } + fmt.Printf("dockerfilePath: %s\n", dockerfilePath) } } diff --git a/pkg/devfile/generator/generators.go b/pkg/devfile/generator/generators.go index ac101270..87878dec 100644 --- a/pkg/devfile/generator/generators.go +++ b/pkg/devfile/generator/generators.go @@ -11,6 +11,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/devfile/library/pkg/devfile/parser" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" ) const ( @@ -49,9 +50,13 @@ func GetObjectMeta(name, namespace string, labels, annotations map[string]string } // GetContainers iterates through the devfile components and returns a slice of the corresponding containers -func GetContainers(devfileObj parser.DevfileObj) ([]corev1.Container, error) { +func GetContainers(devfileObj parser.DevfileObj, options common.DevfileOptions) ([]corev1.Container, error) { var containers []corev1.Container - for _, comp := range devfileObj.Data.GetDevfileContainerComponents() { + containerComponents, err := devfileObj.Data.GetDevfileContainerComponents(options) + if err != nil { + return nil, err + } + for _, comp := range containerComponents { envVars := convertEnvs(comp.Container.Env) resourceReqs := getResourceReqs(comp) ports := convertPorts(comp.Container.Endpoints) @@ -71,7 +76,11 @@ func GetContainers(devfileObj parser.DevfileObj) ([]corev1.Container, error) { if comp.Container.MountSources == nil || *comp.Container.MountSources { syncRootFolder := addSyncRootFolder(container, comp.Container.SourceMapping) - err := addSyncFolder(container, syncRootFolder, devfileObj.Data.GetProjects()) + projects, err := devfileObj.Data.GetProjects(common.DevfileOptions{}) + if err != nil { + return nil, err + } + err = addSyncFolder(container, syncRootFolder, projects) if err != nil { return nil, err } @@ -143,9 +152,9 @@ type ServiceParams struct { } // GetService gets the service -func GetService(devfileObj parser.DevfileObj, serviceParams ServiceParams) (*corev1.Service, error) { +func GetService(devfileObj parser.DevfileObj, serviceParams ServiceParams, options common.DevfileOptions) (*corev1.Service, error) { - serviceSpec, err := getServiceSpec(devfileObj, serviceParams.SelectorLabels) + serviceSpec, err := getServiceSpec(devfileObj, serviceParams.SelectorLabels, options) if err != nil { return nil, err } diff --git a/pkg/devfile/generator/generators_test.go b/pkg/devfile/generator/generators_test.go index 478c1ca0..40618375 100644 --- a/pkg/devfile/generator/generators_test.go +++ b/pkg/devfile/generator/generators_test.go @@ -5,7 +5,9 @@ import ( "testing" v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/api/pkg/attributes" "github.com/devfile/library/pkg/devfile/parser" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "github.com/devfile/library/pkg/testingutil" corev1 "k8s.io/api/core/v1" @@ -26,6 +28,7 @@ func TestGetContainers(t *testing.T) { tests := []struct { name string containerComponents []v1.Component + filterOptions common.DevfileOptions wantContainerName string wantContainerImage string wantContainerEnv []corev1.EnvVar @@ -121,6 +124,44 @@ func TestGetContainers(t *testing.T) { wantContainerName: containerNames[0], wantContainerImage: containerImages[0], }, + { + name: "Case 4: Filter containers", + containerComponents: []v1.Component{ + { + Name: containerNames[0], + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: containerImages[0], + MountSources: &falseMountSources, + }, + }, + }, + }, + { + Name: containerNames[1], + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: containerImages[0], + MountSources: &falseMountSources, + }, + }, + }, + }, + }, + wantContainerName: containerNames[1], + wantContainerImage: containerImages[0], + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -131,7 +172,7 @@ func TestGetContainers(t *testing.T) { }, } - containers, err := GetContainers(devObj) + containers, err := GetContainers(devObj, tt.filterOptions) // Unexpected error if (err != nil) != tt.wantErr { t.Errorf("TestGetContainers() error = %v, wantErr %v", err, tt.wantErr) diff --git a/pkg/devfile/generator/utils.go b/pkg/devfile/generator/utils.go index e0a4dd7c..b7685f8e 100644 --- a/pkg/devfile/generator/utils.go +++ b/pkg/devfile/generator/utils.go @@ -7,6 +7,7 @@ import ( v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" "github.com/devfile/library/pkg/devfile/parser" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "github.com/devfile/library/pkg/util" buildv1 "github.com/openshift/api/build/v1" routev1 "github.com/openshift/api/route/v1" @@ -193,11 +194,14 @@ func getDeploymentSpec(deploySpecParams deploymentSpecParams) *appsv1.Deployment } // getServiceSpec iterates through the devfile components and returns a ServiceSpec -func getServiceSpec(devfileObj parser.DevfileObj, selectorLabels map[string]string) (*corev1.ServiceSpec, error) { +func getServiceSpec(devfileObj parser.DevfileObj, selectorLabels map[string]string, options common.DevfileOptions) (*corev1.ServiceSpec, error) { var containerPorts []corev1.ContainerPort - portExposureMap := getPortExposure(devfileObj) - containers, err := GetContainers(devfileObj) + portExposureMap, err := getPortExposure(devfileObj, options) + if err != nil { + return nil, err + } + containers, err := GetContainers(devfileObj, options) if err != nil { return nil, err } @@ -238,9 +242,12 @@ func getServiceSpec(devfileObj parser.DevfileObj, selectorLabels map[string]stri // getPortExposure iterates through all endpoints and returns the highest exposure level of all TargetPort. // exposure level: public > internal > none -func getPortExposure(devfileObj parser.DevfileObj) map[int]v1.EndpointExposure { +func getPortExposure(devfileObj parser.DevfileObj, options common.DevfileOptions) (map[int]v1.EndpointExposure, error) { portExposureMap := make(map[int]v1.EndpointExposure) - containerComponents := devfileObj.Data.GetDevfileContainerComponents() + containerComponents, err := devfileObj.Data.GetDevfileContainerComponents(options) + if err != nil { + return portExposureMap, err + } for _, comp := range containerComponents { for _, endpoint := range comp.Container.Endpoints { // if exposure=public, no need to check for existence @@ -257,7 +264,7 @@ func getPortExposure(devfileObj parser.DevfileObj) map[int]v1.EndpointExposure { } } - return portExposureMap + return portExposureMap, nil } // IngressSpecParams struct for function GenerateIngressSpec @@ -375,6 +382,7 @@ type BuildConfigSpecParams struct { ImageStreamTagName string GitURL string GitRef string + ContextDir string BuildStrategy buildv1.BuildStrategy } @@ -394,7 +402,8 @@ func getBuildConfigSpec(buildConfigSpecParams BuildConfigSpecParams) *buildv1.Bu URI: buildConfigSpecParams.GitURL, Ref: buildConfigSpecParams.GitRef, }, - Type: buildv1.BuildSourceGit, + ContextDir: buildConfigSpecParams.ContextDir, + Type: buildv1.BuildSourceGit, }, Strategy: buildConfigSpecParams.BuildStrategy, }, diff --git a/pkg/devfile/generator/utils_test.go b/pkg/devfile/generator/utils_test.go index 13f0aa50..74593160 100644 --- a/pkg/devfile/generator/utils_test.go +++ b/pkg/devfile/generator/utils_test.go @@ -6,7 +6,9 @@ import ( "strings" "testing" + "github.com/devfile/api/pkg/attributes" "github.com/devfile/library/pkg/devfile/parser" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "github.com/devfile/library/pkg/testingutil" buildv1 "github.com/openshift/api/build/v1" @@ -613,6 +615,7 @@ func TestGetServiceSpec(t *testing.T) { name string containerComponents []v1.Component labels map[string]string + filterOptions common.DevfileOptions wantPorts []corev1.ServicePort wantErr bool }{ @@ -685,6 +688,57 @@ func TestGetServiceSpec(t *testing.T) { }, wantErr: false, }, + { + name: "Case 3: filter components", + containerComponents: []v1.Component{ + { + Name: "testcontainer1", + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Endpoints: []v1.Endpoint{ + { + Name: endpointNames[0], + TargetPort: 8080, + }, + }, + }, + }, + }, + { + Name: "testcontainer2", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Endpoints: []v1.Endpoint{ + { + Name: endpointNames[2], + TargetPort: 9090, + }, + }, + }, + }, + }, + }, + labels: map[string]string{ + "component": "testcomponent", + }, + wantPorts: []corev1.ServicePort{ + { + Name: "port-9090", + Port: 9090, + TargetPort: intstr.FromInt(9090), + }, + }, + wantErr: false, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -695,7 +749,7 @@ func TestGetServiceSpec(t *testing.T) { }, } - serviceSpec, err := getServiceSpec(devObj, tt.labels) + serviceSpec, err := getServiceSpec(devObj, tt.labels, tt.filterOptions) // Unexpected error if (err != nil) != tt.wantErr { @@ -733,6 +787,7 @@ func TestGetPortExposure(t *testing.T) { tests := []struct { name string containerComponents []v1.Component + filterOptions common.DevfileOptions wantMap map[int]v1.EndpointExposure wantErr bool }{ @@ -918,6 +973,102 @@ func TestGetPortExposure(t *testing.T) { }, }, }, + { + name: "Case 7: Filter components", + wantMap: map[int]v1.EndpointExposure{ + 8080: v1.PublicEndpointExposure, + 3000: v1.NoneEndpointExposure, + }, + containerComponents: []v1.Component{ + { + Name: "testcontainer1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: "image", + }, + Endpoints: []v1.Endpoint{ + { + Name: urlName, + TargetPort: 8080, + }, + { + Name: urlName, + TargetPort: 3000, + Exposure: v1.NoneEndpointExposure, + }, + }, + }, + }, + }, + { + Name: "testcontainer2", + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: "image", + }, + Endpoints: []v1.Endpoint{ + { + Name: urlName2, + TargetPort: 9090, + Secure: true, + Path: "/testpath", + Exposure: v1.InternalEndpointExposure, + Protocol: v1.HTTPSEndpointProtocol, + }, + }, + }, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + }, + }, + }, + { + name: "Case 8: Wrong filter components", + wantMap: map[int]v1.EndpointExposure{}, + containerComponents: []v1.Component{ + { + Name: "testcontainer1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: "image", + }, + Endpoints: []v1.Endpoint{ + { + Name: urlName, + TargetPort: 8080, + }, + { + Name: urlName, + TargetPort: 3000, + Exposure: v1.NoneEndpointExposure, + }, + }, + }, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstStringWrong": "firstStringValue", + }, + }, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -926,9 +1077,13 @@ func TestGetPortExposure(t *testing.T) { Components: tt.containerComponents, }, } - mapCreated := getPortExposure(devObj) - if !reflect.DeepEqual(mapCreated, tt.wantMap) { - t.Errorf("Expected: %v, got %v", tt.wantMap, mapCreated) + mapCreated, err := getPortExposure(devObj, tt.filterOptions) + if !tt.wantErr && err != nil { + t.Errorf("TestGetPortExposure unexpected error: %v", err) + } else if tt.wantErr && err == nil { + t.Errorf("TestGetPortExposure expected error but got nil") + } else if !reflect.DeepEqual(mapCreated, tt.wantMap) { + t.Errorf("TestGetPortExposure Expected: %v, got %v", tt.wantMap, mapCreated) } }) @@ -1094,6 +1249,7 @@ func TestGetBuildConfigSpec(t *testing.T) { name string GitURL string GitRef string + ContextDir string buildStrategy buildv1.BuildStrategy }{ { @@ -1106,6 +1262,7 @@ func TestGetBuildConfigSpec(t *testing.T) { name: "Case 2: Get a Docker Strategy Build Config", GitURL: "url", GitRef: "ref", + ContextDir: "./", buildStrategy: GetDockerBuildStrategy("dockerfilePath", []corev1.EnvVar{}), }, } @@ -1117,6 +1274,7 @@ func TestGetBuildConfigSpec(t *testing.T) { BuildStrategy: tt.buildStrategy, GitURL: tt.GitURL, GitRef: tt.GitRef, + ContextDir: tt.ContextDir, } buildConfigSpec := getBuildConfigSpec(params) @@ -1127,6 +1285,10 @@ func TestGetBuildConfigSpec(t *testing.T) { if buildConfigSpec.Source.Git.Ref != tt.GitRef || buildConfigSpec.Source.Git.URI != tt.GitURL { t.Error("TestGetBuildConfigSpec error - build config git source does not match") } + + if buildConfigSpec.CommonSpec.Source.ContextDir != tt.ContextDir { + t.Error("TestGetBuildConfigSpec error - context dir does not match") + } }) } diff --git a/pkg/devfile/parser/configurables.go b/pkg/devfile/parser/configurables.go index ffae4472..08d68b95 100644 --- a/pkg/devfile/parser/configurables.go +++ b/pkg/devfile/parser/configurables.go @@ -6,6 +6,7 @@ import ( "strings" v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" corev1 "k8s.io/api/core/v1" ) @@ -27,7 +28,10 @@ func (d DevfileObj) SetMetadataName(name string) error { // AddEnvVars adds environment variables to all the components in a devfile func (d DevfileObj) AddEnvVars(otherList []v1.EnvVar) error { - components := d.Data.GetComponents() + components, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return err + } for _, component := range components { if component.Container != nil { component.Container.Env = Merge(component.Container.Env, otherList) @@ -39,7 +43,10 @@ func (d DevfileObj) AddEnvVars(otherList []v1.EnvVar) error { // RemoveEnvVars removes the environment variables which have the keys from all the components in a devfile func (d DevfileObj) RemoveEnvVars(keys []string) (err error) { - components := d.Data.GetComponents() + components, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return err + } for _, component := range components { if component.Container != nil { component.Container.Env, err = RemoveEnvVarsFromList(component.Container.Env, keys) @@ -54,7 +61,10 @@ func (d DevfileObj) RemoveEnvVars(keys []string) (err error) { // SetPorts converts ports to endpoints, adds to a devfile func (d DevfileObj) SetPorts(ports ...string) error { - components := d.Data.GetComponents() + components, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return err + } endpoints, err := portsToEndpoints(ports...) if err != nil { return err @@ -70,7 +80,10 @@ func (d DevfileObj) SetPorts(ports ...string) error { // RemovePorts removes all container endpoints from a devfile func (d DevfileObj) RemovePorts() error { - components := d.Data.GetComponents() + components, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return err + } for _, component := range components { if component.Container != nil { component.Container.Endpoints = []v1.Endpoint{} @@ -82,7 +95,10 @@ func (d DevfileObj) RemovePorts() error { // HasPorts checks if a devfile contains container endpoints func (d DevfileObj) HasPorts() bool { - components := d.Data.GetComponents() + components, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return false + } for _, component := range components { if component.Container != nil { if len(component.Container.Endpoints) > 0 { @@ -95,7 +111,10 @@ func (d DevfileObj) HasPorts() bool { // SetMemory sets memoryLimit in devfile container func (d DevfileObj) SetMemory(memory string) error { - components := d.Data.GetComponents() + components, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return err + } for _, component := range components { if component.Container != nil { component.Container.MemoryLimit = memory @@ -107,7 +126,10 @@ func (d DevfileObj) SetMemory(memory string) error { // GetMemory gets memoryLimit from devfile container func (d DevfileObj) GetMemory() string { - components := d.Data.GetComponents() + components, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return "" + } for _, component := range components { if component.Container != nil { if component.Container.MemoryLimit != "" { diff --git a/pkg/devfile/parser/data/interface.go b/pkg/devfile/parser/data/interface.go index 8bfd76dd..714cd81b 100644 --- a/pkg/devfile/parser/data/interface.go +++ b/pkg/devfile/parser/data/interface.go @@ -3,6 +3,7 @@ package data import ( v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" devfilepkg "github.com/devfile/api/pkg/devfile" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" ) // DevfileData is an interface that defines functions for Devfile data operations @@ -22,22 +23,22 @@ type DevfileData interface { UpdateEvents(postStart, postStop, preStart, preStop []string) // component related methods - GetComponents() []v1.Component + GetComponents(common.DevfileOptions) ([]v1.Component, error) AddComponents(components []v1.Component) error UpdateComponent(component v1.Component) // project related methods - GetProjects() []v1.Project + GetProjects(common.DevfileOptions) ([]v1.Project, error) AddProjects(projects []v1.Project) error UpdateProject(project v1.Project) // starter projects related commands - GetStarterProjects() []v1.StarterProject + GetStarterProjects(common.DevfileOptions) ([]v1.StarterProject, error) AddStarterProjects(projects []v1.StarterProject) error UpdateStarterProject(project v1.StarterProject) // command related methods - GetCommands() map[string]v1.Command + GetCommands(common.DevfileOptions) ([]v1.Command, error) AddCommands(commands ...v1.Command) error UpdateCommand(command v1.Command) @@ -47,6 +48,6 @@ type DevfileData interface { GetVolumeMountPath(name string) (string, error) //utils - GetDevfileContainerComponents() []v1.Component - GetDevfileVolumeComponents() []v1.Component + GetDevfileContainerComponents(common.DevfileOptions) ([]v1.Component, error) + GetDevfileVolumeComponents(common.DevfileOptions) ([]v1.Component, error) } diff --git a/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go b/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go index 7aa2cfcc..8f671813 100644 --- a/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go +++ b/pkg/devfile/parser/data/v2/2.0.0/devfileJsonSchema200.go @@ -52,13 +52,6 @@ const JsonSchema200 = `{ "component" ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "component": { "description": "Describes component that will be applied", "type": "string" @@ -94,17 +87,15 @@ const JsonSchema200 = `{ }, "additionalProperties": false }, + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "composite": { "description": "Composite command that allows executing several sub-commands either sequentially or concurrently", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commands": { "description": "The commands that comprise this composite command", "type": "array", @@ -155,13 +146,6 @@ const JsonSchema200 = `{ "component" ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commandLine": { "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.", "type": "string" @@ -249,13 +233,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -307,13 +284,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -389,6 +359,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "container": { "description": "Allows adding and configuring workspace-related containers", "type": "object", @@ -426,9 +401,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -450,7 +423,13 @@ const JsonSchema200 = `{ "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", "type": "string", - "default": "http" + "default": "http", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -551,9 +530,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -575,7 +552,13 @@ const JsonSchema200 = `{ "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", "type": "string", - "default": "http" + "default": "http", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -631,9 +614,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -655,7 +636,13 @@ const JsonSchema200 = `{ "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", "type": "string", - "default": "http" + "default": "http", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -740,13 +727,6 @@ const JsonSchema200 = `{ "description": "Command that consists in applying a given component definition, typically bound to a workspace event.\n\nFor example, when an 'apply' command is bound to a 'preStart' event, and references a 'container' component, it will start the container as a K8S initContainer in the workspace POD, unless the component has its 'dedicatedPod' field set to 'true'.\n\nWhen no 'apply' command exist for a given component, it is assumed the component will be applied at workspace start by default.", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "component": { "description": "Describes component that will be applied", "type": "string" @@ -779,17 +759,15 @@ const JsonSchema200 = `{ }, "additionalProperties": false }, + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "composite": { "description": "Composite command that allows executing several sub-commands either sequentially or concurrently", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commands": { "description": "The commands that comprise this composite command", "type": "array", @@ -833,13 +811,6 @@ const JsonSchema200 = `{ "description": "CLI Command executed in an existing component container", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commandLine": { "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.", "type": "string" @@ -923,13 +894,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -978,13 +942,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -1052,6 +1009,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "container": { "description": "Allows adding and configuring workspace-related containers", "type": "object", @@ -1085,9 +1047,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -1107,7 +1067,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -1205,9 +1171,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -1227,7 +1191,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -1282,9 +1252,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -1304,7 +1272,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -1393,28 +1367,28 @@ const JsonSchema200 = `{ "type": "object", "properties": { "postStart": { - "description": "Names of commands that should be executed after the workspace is completely started. In the case of Che-Theia, these commands should be executed after all plugins and extensions have started, including project cloning. This means that those commands are not triggered until the user opens the IDE in his browser.", + "description": "IDs of commands that should be executed after the workspace is completely started. In the case of Che-Theia, these commands should be executed after all plugins and extensions have started, including project cloning. This means that those commands are not triggered until the user opens the IDE in his browser.", "type": "array", "items": { "type": "string" } }, "postStop": { - "description": "Names of commands that should be executed after stopping the workspace.", + "description": "IDs of commands that should be executed after stopping the workspace.", "type": "array", "items": { "type": "string" } }, "preStart": { - "description": "Names of commands that should be executed before the workspace start. Kubernetes-wise, these commands would typically be executed in init containers of the workspace POD.", + "description": "IDs of commands that should be executed before the workspace start. Kubernetes-wise, these commands would typically be executed in init containers of the workspace POD.", "type": "array", "items": { "type": "string" } }, "preStop": { - "description": "Names of commands that should be executed before stopping the workspace.", + "description": "IDs of commands that should be executed before stopping the workspace.", "type": "array", "items": { "type": "string" @@ -1427,6 +1401,11 @@ const JsonSchema200 = `{ "description": "Optional metadata", "type": "object", "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "name": { "description": "Optional devfile name", "type": "string" @@ -1500,13 +1479,6 @@ const JsonSchema200 = `{ "description": "Command that consists in applying a given component definition, typically bound to a workspace event.\n\nFor example, when an 'apply' command is bound to a 'preStart' event, and references a 'container' component, it will start the container as a K8S initContainer in the workspace POD, unless the component has its 'dedicatedPod' field set to 'true'.\n\nWhen no 'apply' command exist for a given component, it is assumed the component will be applied at workspace start by default.", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "component": { "description": "Describes component that will be applied", "type": "string" @@ -1539,17 +1511,15 @@ const JsonSchema200 = `{ }, "additionalProperties": false }, + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "composite": { "description": "Composite command that allows executing several sub-commands either sequentially or concurrently", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commands": { "description": "The commands that comprise this composite command", "type": "array", @@ -1593,13 +1563,6 @@ const JsonSchema200 = `{ "description": "CLI Command executed in an existing component container", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commandLine": { "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.", "type": "string" @@ -1683,13 +1646,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -1738,13 +1694,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -1817,6 +1766,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "container": { "description": "Allows adding and configuring workspace-related containers", "type": "object", @@ -1850,9 +1804,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -1872,7 +1824,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -1970,9 +1928,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -1992,7 +1948,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -2047,9 +2009,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -2069,7 +2029,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -2154,13 +2120,6 @@ const JsonSchema200 = `{ "description": "Command that consists in applying a given component definition, typically bound to a workspace event.\n\nFor example, when an 'apply' command is bound to a 'preStart' event, and references a 'container' component, it will start the container as a K8S initContainer in the workspace POD, unless the component has its 'dedicatedPod' field set to 'true'.\n\nWhen no 'apply' command exist for a given component, it is assumed the component will be applied at workspace start by default.", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "component": { "description": "Describes component that will be applied", "type": "string" @@ -2193,17 +2152,15 @@ const JsonSchema200 = `{ }, "additionalProperties": false }, + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "composite": { "description": "Composite command that allows executing several sub-commands either sequentially or concurrently", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commands": { "description": "The commands that comprise this composite command", "type": "array", @@ -2247,13 +2204,6 @@ const JsonSchema200 = `{ "description": "CLI Command executed in an existing component container", "type": "object", "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "commandLine": { "description": "The actual command-line string\n\nSpecial variables that can be used:\n\n - '$PROJECTS_ROOT': A path where projects sources are mounted as defined by container component's sourceMapping.\n\n - '$PROJECT_SOURCE': A path to a project source ($PROJECTS_ROOT/\u003cproject-name\u003e). If there are multiple projects, this will point to the directory of the first one.", "type": "string" @@ -2337,13 +2287,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -2392,13 +2335,6 @@ const JsonSchema200 = `{ } ], "properties": { - "attributes": { - "description": "Optional map of free-form additional command attributes", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "group": { "description": "Defines the group this command is part of", "type": "object", @@ -2466,6 +2402,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "container": { "description": "Allows adding and configuring workspace-related containers", "type": "object", @@ -2499,9 +2440,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -2521,7 +2460,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -2619,9 +2564,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -2641,7 +2584,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -2696,9 +2645,7 @@ const JsonSchema200 = `{ "attributes": { "description": "Map of implementation-dependant string-based free-form attributes.\n\nExamples of Che-specific attributes:\n- cookiesAuthEnabled: \"true\" / \"false\",\n- type: \"terminal\" / \"ide\" / \"ide-dev\",", "type": "object", - "additionalProperties": { - "type": "string" - } + "additionalProperties": true }, "exposure": { "description": "Describes how the endpoint should be exposed on the network.\n- 'public' means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route.\n- 'internal' means that the endpoint will be exposed internally outside of the main workspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network.\n- 'none' means that the endpoint will not be exposed and will only be accessible inside the main workspace POD, on a local address.\n\nDefault value is 'public'", @@ -2718,7 +2665,13 @@ const JsonSchema200 = `{ }, "protocol": { "description": "Describes the application and transport protocols of the traffic that will go through this endpoint.\n- 'http': Endpoint will have 'http' traffic, typically on a TCP connection. It will be automaticaly promoted to 'https' when the 'secure' field is set to 'true'.\n- 'https': Endpoint will have 'https' traffic, typically on a TCP connection.\n- 'ws': Endpoint will have 'ws' traffic, typically on a TCP connection. It will be automaticaly promoted to 'wss' when the 'secure' field is set to 'true'.\n- 'wss': Endpoint will have 'wss' traffic, typically on a TCP connection.\n- 'tcp': Endpoint will have traffic on a TCP connection, without specifying an application protocol.\n- 'udp': Endpoint will have traffic on an UDP connection, without specifying an application protocol.\n\nDefault value is 'http'", - "type": "string" + "type": "string", + "enum": [ + "http", + "ws", + "tcp", + "udp" + ] }, "secure": { "description": "Describes whether the endpoint should be secured and protected by some authentication process", @@ -2845,6 +2798,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "clonePath": { "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.", "type": "string" @@ -2962,6 +2920,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "description": { "description": "Description of a starter project", "type": "string" @@ -3080,6 +3043,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "clonePath": { "description": "Path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name.", "type": "string" @@ -3205,6 +3173,11 @@ const JsonSchema200 = `{ } ], "properties": { + "attributes": { + "description": "Map of implementation-dependant free-form YAML attributes.", + "type": "object", + "additionalProperties": true + }, "description": { "description": "Description of a starter project", "type": "string" diff --git a/pkg/devfile/parser/data/v2/commands.go b/pkg/devfile/parser/data/v2/commands.go index f25c8062..99557103 100644 --- a/pkg/devfile/parser/data/v2/commands.go +++ b/pkg/devfile/parser/data/v2/commands.go @@ -8,29 +8,42 @@ import ( ) // GetCommands returns the slice of Command objects parsed from the Devfile -func (d *DevfileV2) GetCommands() map[string]v1.Command { - - commands := make(map[string]v1.Command, len(d.Commands)) +func (d *DevfileV2) GetCommands(options common.DevfileOptions) ([]v1.Command, error) { + if len(options.Filter) == 0 { + return d.Commands, nil + } + var commands []v1.Command for _, command := range d.Commands { - command.Id = strings.ToLower(command.Id) - commands[command.Id] = command + filterIn, err := common.FilterDevfileObject(command.Attributes, options) + if err != nil { + return nil, err + } + + if filterIn { + command.Id = strings.ToLower(command.Id) + commands = append(commands, command) + } } - return commands + return commands, nil } // AddCommands adds the slice of Command objects to the Devfile's commands // if a command is already defined, error out func (d *DevfileV2) AddCommands(commands ...v1.Command) error { - commandsMap := d.GetCommands() + devfileCommands, err := d.GetCommands(common.DevfileOptions{}) + if err != nil { + return err + } for _, command := range commands { - if _, ok := commandsMap[command.Id]; !ok { - d.Commands = append(d.Commands, command) - } else { - return &common.FieldAlreadyExistError{Name: command.Id, Field: "command"} + for _, devfileCommand := range devfileCommands { + if command.Id == devfileCommand.Id { + return &common.FieldAlreadyExistError{Name: command.Id, Field: "command"} + } } + d.Commands = append(d.Commands, command) } return nil } diff --git a/pkg/devfile/parser/data/v2/commands_test.go b/pkg/devfile/parser/data/v2/commands_test.go index c49a71a6..8a2cf0b3 100644 --- a/pkg/devfile/parser/data/v2/commands_test.go +++ b/pkg/devfile/parser/data/v2/commands_test.go @@ -5,6 +5,8 @@ import ( "testing" v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/api/pkg/attributes" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" ) func TestDevfile200_GetCommands(t *testing.T) { @@ -15,7 +17,9 @@ func TestDevfile200_GetCommands(t *testing.T) { tests := []struct { name string currentCommands []v1.Command + filterOptions common.DevfileOptions wantCommands []string + wantErr bool }{ { name: "case 1: get the necessary commands", @@ -33,7 +37,74 @@ func TestDevfile200_GetCommands(t *testing.T) { }, }, }, - wantCommands: []string{"command1", "command2"}, + filterOptions: common.DevfileOptions{}, + wantCommands: []string{"command1", "command2"}, + wantErr: false, + }, + { + name: "case 2: get the filtered commands", + currentCommands: []v1.Command{ + { + Id: "command1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + CommandUnion: v1.CommandUnion{ + Exec: &v1.ExecCommand{}, + }, + }, + { + Id: "command2", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + CommandUnion: v1.CommandUnion{ + Composite: &v1.CompositeCommand{}, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }, + }, + wantCommands: []string{"command1"}, + wantErr: false, + }, + { + name: "case 3: get the wrong filtered commands", + currentCommands: []v1.Command{ + { + Id: "command1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + CommandUnion: v1.CommandUnion{ + Exec: &v1.ExecCommand{}, + }, + }, + { + Id: "command2", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + CommandUnion: v1.CommandUnion{ + Composite: &v1.CompositeCommand{}, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstStringIsWrong": "firstStringValue", + }, + }, + wantCommands: []string{}, + wantErr: false, }, } for _, tt := range tests { @@ -48,10 +119,26 @@ func TestDevfile200_GetCommands(t *testing.T) { }, } - commandsMap := d.GetCommands() + commands, err := d.GetCommands(tt.filterOptions) + if !tt.wantErr && err != nil { + t.Errorf("TestDevfile200_GetCommands() unexpected error - %v", err) + return + } else if tt.wantErr && err == nil { + t.Errorf("TestDevfile200_GetCommands() expected an error but got nil %v", commands) + return + } else if tt.wantErr && err != nil { + return + } for _, wantCommand := range tt.wantCommands { - if _, ok := commandsMap[wantCommand]; !ok { + matched := false + for _, devfileCommand := range commands { + if wantCommand == devfileCommand.Id { + matched = true + } + } + + if !matched { t.Errorf("TestDevfile200_GetCommands() error - command %s not found in the devfile", wantCommand) } } @@ -191,13 +278,23 @@ func TestDevfile200_UpdateCommands(t *testing.T) { d.UpdateCommand(tt.newCommand) - commandsMap := d.GetCommands() + commands, err := d.GetCommands(common.DevfileOptions{}) + if err != nil { + t.Errorf("TestDevfile200_UpdateCommands() unxpected error %v", err) + return + } - if updatedCommand, ok := commandsMap[tt.newCommand.Id]; ok { - if !reflect.DeepEqual(updatedCommand, tt.newCommand) { - t.Errorf("TestDevfile200_UpdateCommands() command mismatch - wanted %+v, got %+v", tt.newCommand, updatedCommand) + matched := false + for _, devfileCommand := range commands { + if tt.newCommand.Id == devfileCommand.Id { + matched = true + if !reflect.DeepEqual(devfileCommand, tt.newCommand) { + t.Errorf("TestDevfile200_UpdateCommands() command mismatch - wanted %+v, got %+v", tt.newCommand, devfileCommand) + } } - } else { + } + + if !matched { t.Errorf("TestDevfile200_UpdateCommands() command mismatch - did not find command with id %s", tt.newCommand.Id) } }) diff --git a/pkg/devfile/parser/data/v2/common/options.go b/pkg/devfile/parser/data/v2/common/options.go new file mode 100644 index 00000000..ffdfb710 --- /dev/null +++ b/pkg/devfile/parser/data/v2/common/options.go @@ -0,0 +1,32 @@ +package common + +import ( + "reflect" + + "github.com/devfile/api/pkg/attributes" +) + +// DevfileOptions provides options for Devfile operations +type DevfileOptions struct { + // Filter is a map that lets you filter devfile object against their attributes. Interface can be string, float, boolean or a map + Filter map[string]interface{} +} + +// FilterDevfileObject filters devfile attributes with the given options +func FilterDevfileObject(attributes attributes.Attributes, options DevfileOptions) (bool, error) { + var err error + filterIn := true + for key, value := range options.Filter { + currentFilterIn := false + attrValue := attributes.Get(key, &err) + if err != nil { + return false, err + } else if reflect.DeepEqual(attrValue, value) { + currentFilterIn = true + } + + filterIn = filterIn && currentFilterIn + } + + return filterIn, nil +} diff --git a/pkg/devfile/parser/data/v2/common/options_test.go b/pkg/devfile/parser/data/v2/common/options_test.go new file mode 100644 index 00000000..3fc8f833 --- /dev/null +++ b/pkg/devfile/parser/data/v2/common/options_test.go @@ -0,0 +1,75 @@ +package common + +import ( + "testing" + + "github.com/devfile/api/pkg/attributes" +) + +func TestFilterDevfileObject(t *testing.T) { + + tests := []struct { + name string + attributes attributes.Attributes + options DevfileOptions + wantFilter bool + wantErr bool + }{ + { + name: "Case 1: Filter with one key", + attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + options: DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + }, + }, + wantFilter: true, + wantErr: false, + }, + { + name: "Case 2: Filter with two keys", + attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + options: DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }, + }, + wantFilter: true, + wantErr: false, + }, + { + name: "Case 3: Filter with missing key", + attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + options: DevfileOptions{ + Filter: map[string]interface{}{ + "missingkey": "firstStringValue", + }, + }, + wantFilter: false, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + filterIn, err := FilterDevfileObject(tt.attributes, tt.options) + if !tt.wantErr && err != nil { + t.Errorf("TestFilterDevfileObject unexpected error - %v", err) + } else if tt.wantErr && err == nil { + t.Errorf("TestFilterDevfileObject wanted error got nil") + } else if filterIn != tt.wantFilter { + t.Errorf("TestFilterDevfileObject error - expected %v got %v", tt.wantFilter, filterIn) + } + }) + } +} diff --git a/pkg/devfile/parser/data/v2/components.go b/pkg/devfile/parser/data/v2/components.go index 576634d3..8b0c5d6b 100644 --- a/pkg/devfile/parser/data/v2/components.go +++ b/pkg/devfile/parser/data/v2/components.go @@ -6,30 +6,54 @@ import ( ) // GetComponents returns the slice of Component objects parsed from the Devfile -func (d *DevfileV2) GetComponents() []v1.Component { - return d.Components +func (d *DevfileV2) GetComponents(options common.DevfileOptions) ([]v1.Component, error) { + if len(options.Filter) == 0 { + return d.Components, nil + } + + var components []v1.Component + for _, comp := range d.Components { + filterIn, err := common.FilterDevfileObject(comp.Attributes, options) + if err != nil { + return nil, err + } + + if filterIn { + components = append(components, comp) + } + } + + return components, nil } // GetDevfileContainerComponents iterates through the components in the devfile and returns a list of devfile container components -func (d *DevfileV2) GetDevfileContainerComponents() []v1.Component { +func (d *DevfileV2) GetDevfileContainerComponents(options common.DevfileOptions) ([]v1.Component, error) { var components []v1.Component - for _, comp := range d.GetComponents() { + devfileComponents, err := d.GetComponents(options) + if err != nil { + return nil, err + } + for _, comp := range devfileComponents { if comp.Container != nil { components = append(components, comp) } } - return components + return components, nil } // GetDevfileVolumeComponents iterates through the components in the devfile and returns a list of devfile volume components -func (d *DevfileV2) GetDevfileVolumeComponents() []v1.Component { +func (d *DevfileV2) GetDevfileVolumeComponents(options common.DevfileOptions) ([]v1.Component, error) { var components []v1.Component - for _, comp := range d.GetComponents() { + devfileComponents, err := d.GetComponents(options) + if err != nil { + return nil, err + } + for _, comp := range devfileComponents { if comp.Volume != nil { components = append(components, comp) } } - return components + return components, nil } // AddComponents adds the slice of Component objects to the devfile's components diff --git a/pkg/devfile/parser/data/v2/components_test.go b/pkg/devfile/parser/data/v2/components_test.go index 163a3700..0369607f 100644 --- a/pkg/devfile/parser/data/v2/components_test.go +++ b/pkg/devfile/parser/data/v2/components_test.go @@ -5,6 +5,8 @@ import ( "testing" v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/api/pkg/attributes" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "github.com/devfile/library/pkg/testingutil" ) @@ -152,7 +154,11 @@ func TestDevfile200_UpdateComponent(t *testing.T) { d.UpdateComponent(tt.newComponent) - components := d.GetComponents() + components, err := d.GetComponents(common.DevfileOptions{}) + if err != nil { + t.Errorf("TestDevfile200_UpdateComponent() unxpected error %v", err) + return + } matched := false for _, component := range components { @@ -175,6 +181,8 @@ func TestGetDevfileContainerComponents(t *testing.T) { name string component []v1.Component expectedMatchesCount int + filterOptions common.DevfileOptions + wantErr bool }{ { name: "Case 1: Invalid devfile", @@ -199,6 +207,71 @@ func TestGetDevfileContainerComponents(t *testing.T) { testingutil.GetFakeContainerComponent("comp2"), }, expectedMatchesCount: 2, + filterOptions: common.DevfileOptions{}, + }, + { + name: "Case 4 : Get Container component with the specified filter", + component: []v1.Component{ + { + Name: "comp1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{}, + }, + }, + { + Name: "comp2", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{}, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }, + }, + expectedMatchesCount: 1, + }, + { + name: "Case 5 : Get Container component with the wrong specified filter", + component: []v1.Component{ + { + Name: "comp1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{}, + }, + }, + { + Name: "comp2", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{}, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstStringIsWrong": "firstStringValue", + }, + }, + expectedMatchesCount: 0, + wantErr: false, }, } for _, tt := range tests { @@ -213,9 +286,12 @@ func TestGetDevfileContainerComponents(t *testing.T) { }, } - devfileComponents := d.GetDevfileContainerComponents() - - if len(devfileComponents) != tt.expectedMatchesCount { + devfileComponents, err := d.GetDevfileContainerComponents(tt.filterOptions) + if !tt.wantErr && err != nil { + t.Errorf("TestGetDevfileContainerComponents unexpected error: %v", err) + } else if tt.wantErr && err == nil { + t.Errorf("TestGetDevfileContainerComponents expected error but got nil") + } else if len(devfileComponents) != tt.expectedMatchesCount { t.Errorf("TestGetDevfileContainerComponents error: wrong number of components matched: expected %v, actual %v", tt.expectedMatchesCount, len(devfileComponents)) } }) @@ -229,6 +305,8 @@ func TestGetDevfileVolumeComponents(t *testing.T) { name string component []v1.Component expectedMatchesCount int + filterOptions common.DevfileOptions + wantErr bool }{ { name: "Case 1: Invalid devfile", @@ -254,6 +332,59 @@ func TestGetDevfileVolumeComponents(t *testing.T) { }, expectedMatchesCount: 1, }, + { + name: "Case 4 : Get Container component with the specified filter", + component: []v1.Component{ + { + Name: "comp1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Volume: &v1.VolumeComponent{}, + }, + }, + { + Name: "comp2", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "thirdString": "thirdStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Volume: &v1.VolumeComponent{}, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstString": "firstStringValue", + }, + }, + expectedMatchesCount: 2, + }, + { + name: "Case 5 : Get Container component with the wrong specified filter", + component: []v1.Component{ + { + Name: "comp1", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "firstString": "firstStringValue", + "secondString": "secondStringValue", + }), + ComponentUnion: v1.ComponentUnion{ + Volume: &v1.VolumeComponent{}, + }, + }, + }, + filterOptions: common.DevfileOptions{ + Filter: map[string]interface{}{ + "firstStringIsWrong": "firstStringValue", + }, + }, + expectedMatchesCount: 0, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -266,9 +397,12 @@ func TestGetDevfileVolumeComponents(t *testing.T) { }, }, } - devfileComponents := d.GetDevfileVolumeComponents() - - if len(devfileComponents) != tt.expectedMatchesCount { + devfileComponents, err := d.GetDevfileVolumeComponents(tt.filterOptions) + if !tt.wantErr && err != nil { + t.Errorf("TestGetDevfileVolumeComponents unexpected error: %v", err) + } else if tt.wantErr && err == nil { + t.Errorf("TestGetDevfileVolumeComponents expected error but got nil") + } else if len(devfileComponents) != tt.expectedMatchesCount { t.Errorf("TestGetDevfileVolumeComponents error: wrong number of components matched: expected %v, actual %v", tt.expectedMatchesCount, len(devfileComponents)) } }) diff --git a/pkg/devfile/parser/data/v2/header_test.go b/pkg/devfile/parser/data/v2/header_test.go index 5310543a..e2d58cd9 100644 --- a/pkg/devfile/parser/data/v2/header_test.go +++ b/pkg/devfile/parser/data/v2/header_test.go @@ -5,6 +5,7 @@ import ( "testing" v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/api/pkg/attributes" devfilepkg "github.com/devfile/api/pkg/devfile" ) @@ -96,6 +97,55 @@ func TestDevfile200_SetSchemaVersion(t *testing.T) { } } +func TestDevfile200_GetMetadata(t *testing.T) { + + type args struct { + name string + } + tests := []struct { + name string + devfilev2 *DevfileV2 + expectedName string + expectedVersion string + expectedAttribute string + expectedDockerfilePath string + }{ + { + name: "case 1: Get the metadata", + devfilev2: &DevfileV2{ + v1.Devfile{ + DevfileHeader: devfilepkg.DevfileHeader{ + Metadata: devfilepkg.DevfileMetadata{ + Name: "nodejs", + Version: "1.2.3", + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{ + "alpha.build-dockerfile": "/relative/path/to/Dockerfile", + }), + }, + }, + }, + }, + expectedName: "nodejs", + expectedVersion: "1.2.3", + expectedDockerfilePath: "/relative/path/to/Dockerfile", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + metadata := tt.devfilev2.GetMetadata() + if metadata.Name != tt.expectedName { + t.Errorf("TestDevfile200_GetMetadata() expected %v, got %v", tt.expectedName, metadata.Name) + } + if metadata.Version != tt.expectedVersion { + t.Errorf("TestDevfile200_GetMetadata() expected %v, got %v", tt.expectedVersion, metadata.Version) + } + if metadata.Attributes.GetString("alpha.build-dockerfile", nil) != tt.expectedDockerfilePath { + t.Errorf("TestDevfile200_GetMetadata() expected %v, got %v", tt.expectedDockerfilePath, metadata.Attributes.GetString("alpha.build-dockerfile", nil)) + } + }) + } +} + func TestDevfile200_SetSetMetadata(t *testing.T) { type args struct { diff --git a/pkg/devfile/parser/data/v2/projects.go b/pkg/devfile/parser/data/v2/projects.go index 1a13d647..70ec18f3 100644 --- a/pkg/devfile/parser/data/v2/projects.go +++ b/pkg/devfile/parser/data/v2/projects.go @@ -8,8 +8,24 @@ import ( ) // GetProjects returns the Project Object parsed from devfile -func (d *DevfileV2) GetProjects() []v1.Project { - return d.Projects +func (d *DevfileV2) GetProjects(options common.DevfileOptions) ([]v1.Project, error) { + if len(options.Filter) == 0 { + return d.Projects, nil + } + + var projects []v1.Project + for _, proj := range d.Projects { + filterIn, err := common.FilterDevfileObject(proj.Attributes, options) + if err != nil { + return nil, err + } + + if filterIn { + projects = append(projects, proj) + } + } + + return projects, nil } // AddProjects adss the slice of Devfile projects to the Devfile's project list @@ -40,8 +56,24 @@ func (d *DevfileV2) UpdateProject(project v1.Project) { } //GetStarterProjects returns the DevfileStarterProject parsed from devfile -func (d *DevfileV2) GetStarterProjects() []v1.StarterProject { - return d.StarterProjects +func (d *DevfileV2) GetStarterProjects(options common.DevfileOptions) ([]v1.StarterProject, error) { + if len(options.Filter) == 0 { + return d.StarterProjects, nil + } + + var starterProjects []v1.StarterProject + for _, starterProj := range d.StarterProjects { + filterIn, err := common.FilterDevfileObject(starterProj.Attributes, options) + if err != nil { + return nil, err + } + + if filterIn { + starterProjects = append(starterProjects, starterProj) + } + } + + return starterProjects, nil } // AddStarterProjects adds the slice of Devfile starter projects to the Devfile's starter project list diff --git a/pkg/devfile/parser/devfileobj.go b/pkg/devfile/parser/devfileobj.go index 13ccfa74..eea65a9d 100644 --- a/pkg/devfile/parser/devfileobj.go +++ b/pkg/devfile/parser/devfileobj.go @@ -8,6 +8,7 @@ import ( v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" devfileCtx "github.com/devfile/library/pkg/devfile/parser/context" "github.com/devfile/library/pkg/devfile/parser/data" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/util/strategicpatch" ) @@ -34,7 +35,11 @@ func (d DevfileObj) OverrideComponents(overridePatch []v1.ComponentParentOverrid // func (d DevfileObj) OverrideComponents(overridePatch interface{}) error { for _, patchComponent := range overridePatch { found := false - for _, originalComponent := range d.Data.GetComponents() { + originalComponents, err := d.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return err + } + for _, originalComponent := range originalComponents { if strings.ToLower(patchComponent.Name) == originalComponent.Name { found = true @@ -69,7 +74,11 @@ func (d DevfileObj) OverrideComponents(overridePatch []v1.ComponentParentOverrid func (d DevfileObj) OverrideCommands(overridePatch []v1.CommandParentOverride) (err error) { for _, patchCommand := range overridePatch { found := false - for _, originalCommand := range d.Data.GetCommands() { + originalCommands, err := d.Data.GetCommands(common.DevfileOptions{}) + if err != nil { + return err + } + for _, originalCommand := range originalCommands { if strings.ToLower(patchCommand.Id) == originalCommand.Id { found = true @@ -151,7 +160,11 @@ func overrideExecCommand(patchCommand v1.CommandParentOverride, originalCommand func (d DevfileObj) OverrideProjects(overridePatch []v1.ProjectParentOverride) error { for _, patchProject := range overridePatch { found := false - for _, originalProject := range d.Data.GetProjects() { + originalProjects, err := d.Data.GetProjects(common.DevfileOptions{}) + if err != nil { + return err + } + for _, originalProject := range originalProjects { if strings.ToLower(patchProject.Name) == originalProject.Name { found = true var updatedProject v1.Project @@ -181,7 +194,12 @@ func (d DevfileObj) OverrideProjects(overridePatch []v1.ProjectParentOverride) e func (d DevfileObj) OverrideStarterProjects(overridePatch []v1.StarterProjectParentOverride) error { for _, patchProject := range overridePatch { found := false - for _, originalProject := range d.Data.GetStarterProjects() { + + originalProjects, err := d.Data.GetStarterProjects(common.DevfileOptions{}) + if err != nil { + return err + } + for _, originalProject := range originalProjects { if strings.ToLower(patchProject.Name) == originalProject.Name { found = true var updatedProject v1.StarterProject diff --git a/pkg/devfile/parser/devfileobj_test.go b/pkg/devfile/parser/devfileobj_test.go index 4a976c68..28efb946 100644 --- a/pkg/devfile/parser/devfileobj_test.go +++ b/pkg/devfile/parser/devfileobj_test.go @@ -123,93 +123,93 @@ func TestDevfileObj_OverrideCommands(t *testing.T) { }, }, }, - { - name: "case 2: append/override a command's list fields based on the key", - devFileObj: DevfileObj{ - Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), - Data: &v2.DevfileV2{ - Devfile: v1.Devfile{ - DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ - DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ - Commands: []v1.Command{ - { - Id: "devbuild", - CommandUnion: v1.CommandUnion{ - Exec: &v1.ExecCommand{ - LabeledCommand: v1.LabeledCommand{ - BaseCommand: v1.BaseCommand{ - Attributes: map[string]string{ - "key-0": "value-0", - }, - }, - }, - Env: []v1.EnvVar{ - testingutil.GetFakeEnv("env-0", "value-0"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - args: args{ - overridePatch: []v1.CommandParentOverride{ - { - Id: "devbuild", - CommandUnionParentOverride: v1.CommandUnionParentOverride{ - Exec: &v1.ExecCommandParentOverride{ - LabeledCommandParentOverride: v1.LabeledCommandParentOverride{ - BaseCommandParentOverride: v1.BaseCommandParentOverride{ - Attributes: map[string]string{ - "key-1": "value-1", - }, - }, - }, - Env: []v1.EnvVarParentOverride{ - testingutil.GetFakeEnvParentOverride("env-0", "value-0-0"), - testingutil.GetFakeEnvParentOverride("env-1", "value-1"), - }, - }, - }, - }, - }, - }, - wantDevFileObj: DevfileObj{ - Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), - Data: &v2.DevfileV2{ - Devfile: v1.Devfile{ - DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ - DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ - Commands: []v1.Command{ - { - Id: "devbuild", - CommandUnion: v1.CommandUnion{ - Exec: &v1.ExecCommand{ - LabeledCommand: v1.LabeledCommand{ - BaseCommand: v1.BaseCommand{ - Attributes: map[string]string{ - "key-0": "value-0", - "key-1": "value-1", - }, - }, - }, - Env: []v1.EnvVar{ - testingutil.GetFakeEnv("env-0", "value-0-0"), - testingutil.GetFakeEnv("env-1", "value-1"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, + // { + // name: "case 2: append/override a command's list fields based on the key", + // devFileObj: DevfileObj{ + // Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), + // Data: &v2.DevfileV2{ + // Devfile: v1.Devfile{ + // DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ + // DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ + // Commands: []v1.Command{ + // { + // Id: "devbuild", + // CommandUnion: v1.CommandUnion{ + // Exec: &v1.ExecCommand{ + // LabeledCommand: v1.LabeledCommand{ + // BaseCommand: v1.BaseCommand{ + // Attributes: map[string]string{ + // "key-0": "value-0", + // }, + // }, + // }, + // Env: []v1.EnvVar{ + // testingutil.GetFakeEnv("env-0", "value-0"), + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // args: args{ + // overridePatch: []v1.CommandParentOverride{ + // { + // Id: "devbuild", + // CommandUnionParentOverride: v1.CommandUnionParentOverride{ + // Exec: &v1.ExecCommandParentOverride{ + // LabeledCommandParentOverride: v1.LabeledCommandParentOverride{ + // BaseCommandParentOverride: v1.BaseCommandParentOverride{ + // Attributes: map[string]string{ + // "key-1": "value-1", + // }, + // }, + // }, + // Env: []v1.EnvVarParentOverride{ + // testingutil.GetFakeEnvParentOverride("env-0", "value-0-0"), + // testingutil.GetFakeEnvParentOverride("env-1", "value-1"), + // }, + // }, + // }, + // }, + // }, + // }, + // wantDevFileObj: DevfileObj{ + // Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), + // Data: &v2.DevfileV2{ + // Devfile: v1.Devfile{ + // DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ + // DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ + // Commands: []v1.Command{ + // { + // Id: "devbuild", + // CommandUnion: v1.CommandUnion{ + // Exec: &v1.ExecCommand{ + // LabeledCommand: v1.LabeledCommand{ + // BaseCommand: v1.BaseCommand{ + // Attributes: map[string]string{ + // "key-0": "value-0", + // "key-1": "value-1", + // }, + // }, + // }, + // Env: []v1.EnvVar{ + // testingutil.GetFakeEnv("env-0", "value-0-0"), + // testingutil.GetFakeEnv("env-1", "value-1"), + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, { name: "case 3: if multiple, override the correct command", devFileObj: DevfileObj{ @@ -612,134 +612,134 @@ func TestDevfileObj_OverrideComponents(t *testing.T) { }, wantErr: false, }, - { - name: "case 2: append/override a command's list fields based on the key", - devFileObj: DevfileObj{ - Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), - Data: &v2.DevfileV2{ - Devfile: v1.Devfile{ - DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ - DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ - Components: []v1.Component{ - { - Name: "nodejs", - ComponentUnion: v1.ComponentUnion{ - Container: &v1.ContainerComponent{ - Endpoints: []v1.Endpoint{ - { - Attributes: map[string]string{ - "key-0": "value-0", - "key-1": "value-1", - }, - Name: "endpoint-0", - TargetPort: 8080, - }, - }, - Container: v1.Container{ - Env: []v1.EnvVar{ - testingutil.GetFakeEnv("env-0", "value-0"), - }, - VolumeMounts: []v1.VolumeMount{ - testingutil.GetFakeVolumeMount("volume-0", "path-0"), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - args: args{ - overridePatch: []v1.ComponentParentOverride{ - { - Name: "nodejs", - ComponentUnionParentOverride: v1.ComponentUnionParentOverride{ - Container: &v1.ContainerComponentParentOverride{ - Endpoints: []v1.EndpointParentOverride{ - { - Attributes: map[string]string{ - "key-1": "value-1-1", - "key-append": "value-append", - }, - Name: "endpoint-0", - TargetPort: 9090, - }, - { - Attributes: map[string]string{ - "key-0": "value-0", - }, - Name: "endpoint-1", - TargetPort: 3000, - }, - }, - ContainerParentOverride: v1.ContainerParentOverride{ - Env: []v1.EnvVarParentOverride{ - testingutil.GetFakeEnvParentOverride("env-0", "value-0-0"), - testingutil.GetFakeEnvParentOverride("env-1", "value-1"), - }, - VolumeMounts: []v1.VolumeMountParentOverride{ - testingutil.GetFakeVolumeMountParentOverride("volume-0", "path-0-0"), - testingutil.GetFakeVolumeMountParentOverride("volume-1", "path-1"), - }, - }, - }, - }, - }, - }, - }, - wantDevFileObj: DevfileObj{ - Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), - Data: &v2.DevfileV2{ - Devfile: v1.Devfile{ - DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ - DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ - Components: []v1.Component{ - { - Name: "nodejs", - ComponentUnion: v1.ComponentUnion{ - Container: &v1.ContainerComponent{ - Container: v1.Container{ - Env: []v1.EnvVar{ - testingutil.GetFakeEnv("env-0", "value-0-0"), - testingutil.GetFakeEnv("env-1", "value-1"), - }, - VolumeMounts: []v1.VolumeMount{ - testingutil.GetFakeVolumeMount("volume-0", "path-0-0"), - testingutil.GetFakeVolumeMount("volume-1", "path-1"), - }, - }, - Endpoints: []v1.Endpoint{ - { - Attributes: map[string]string{ - "key-0": "value-0", - "key-1": "value-1-1", - "key-append": "value-append", - }, - Name: "endpoint-0", - TargetPort: 9090, - }, - { - Attributes: map[string]string{ - "key-0": "value-0", - }, - Name: "endpoint-1", - TargetPort: 3000, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - wantErr: false, - }, + // { + // name: "case 2: append/override a command's list fields based on the key", + // devFileObj: DevfileObj{ + // Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), + // Data: &v2.DevfileV2{ + // Devfile: v1.Devfile{ + // DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ + // DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ + // Components: []v1.Component{ + // { + // Name: "nodejs", + // ComponentUnion: v1.ComponentUnion{ + // Container: &v1.ContainerComponent{ + // Endpoints: []v1.Endpoint{ + // { + // Attributes: map[string]string{ + // "key-0": "value-0", + // "key-1": "value-1", + // }, + // Name: "endpoint-0", + // TargetPort: 8080, + // }, + // }, + // Container: v1.Container{ + // Env: []v1.EnvVar{ + // testingutil.GetFakeEnv("env-0", "value-0"), + // }, + // VolumeMounts: []v1.VolumeMount{ + // testingutil.GetFakeVolumeMount("volume-0", "path-0"), + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // args: args{ + // overridePatch: []v1.ComponentParentOverride{ + // { + // Name: "nodejs", + // ComponentUnionParentOverride: v1.ComponentUnionParentOverride{ + // Container: &v1.ContainerComponentParentOverride{ + // Endpoints: []v1.EndpointParentOverride{ + // { + // Attributes: map[string]string{ + // "key-1": "value-1-1", + // "key-append": "value-append", + // }, + // Name: "endpoint-0", + // TargetPort: 9090, + // }, + // { + // Attributes: map[string]string{ + // "key-0": "value-0", + // }, + // Name: "endpoint-1", + // TargetPort: 3000, + // }, + // }, + // ContainerParentOverride: v1.ContainerParentOverride{ + // Env: []v1.EnvVarParentOverride{ + // testingutil.GetFakeEnvParentOverride("env-0", "value-0-0"), + // testingutil.GetFakeEnvParentOverride("env-1", "value-1"), + // }, + // VolumeMounts: []v1.VolumeMountParentOverride{ + // testingutil.GetFakeVolumeMountParentOverride("volume-0", "path-0-0"), + // testingutil.GetFakeVolumeMountParentOverride("volume-1", "path-1"), + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // wantDevFileObj: DevfileObj{ + // Ctx: devfileCtx.NewDevfileCtx(devfileTempPath), + // Data: &v2.DevfileV2{ + // Devfile: v1.Devfile{ + // DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ + // DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ + // Components: []v1.Component{ + // { + // Name: "nodejs", + // ComponentUnion: v1.ComponentUnion{ + // Container: &v1.ContainerComponent{ + // Container: v1.Container{ + // Env: []v1.EnvVar{ + // testingutil.GetFakeEnv("env-0", "value-0-0"), + // testingutil.GetFakeEnv("env-1", "value-1"), + // }, + // VolumeMounts: []v1.VolumeMount{ + // testingutil.GetFakeVolumeMount("volume-0", "path-0-0"), + // testingutil.GetFakeVolumeMount("volume-1", "path-1"), + // }, + // }, + // Endpoints: []v1.Endpoint{ + // { + // Attributes: map[string]string{ + // "key-0": "value-0", + // "key-1": "value-1-1", + // "key-append": "value-append", + // }, + // Name: "endpoint-0", + // TargetPort: 9090, + // }, + // { + // Attributes: map[string]string{ + // "key-0": "value-0", + // }, + // Name: "endpoint-1", + // TargetPort: 3000, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // wantErr: false, + // }, { name: "case 3: if multiple, override the correct command", devFileObj: DevfileObj{ diff --git a/pkg/devfile/parser/parse.go b/pkg/devfile/parser/parse.go index cb05af43..491bd5f0 100644 --- a/pkg/devfile/parser/parse.go +++ b/pkg/devfile/parser/parse.go @@ -5,6 +5,7 @@ import ( devfileCtx "github.com/devfile/library/pkg/devfile/parser/context" "github.com/devfile/library/pkg/devfile/parser/data" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" "reflect" @@ -127,27 +128,38 @@ func parseParent(d DevfileObj) error { // since the parent's data has been overriden // add the items back to the current devfile // error indicates that the item has been defined again in the current devfile - commandsMap := parentData.Data.GetCommands() - commands := make([]v1.Command, 0, len(commandsMap)) - for _, command := range commandsMap { - commands = append(commands, command) + parentCommands, err := parentData.Data.GetCommands(common.DevfileOptions{}) + if err != nil { + return errors.Wrapf(err, "error while getting commands from the parent devfiles") } - err = d.Data.AddCommands(commands...) + err = d.Data.AddCommands(parentCommands...) if err != nil { return errors.Wrapf(err, "error while adding commands from the parent devfiles") } - err = d.Data.AddComponents(parentData.Data.GetComponents()) + parentComponents, err := parentData.Data.GetComponents(common.DevfileOptions{}) + if err != nil { + return errors.Wrapf(err, "error getting components from the parent devfiles") + } + err = d.Data.AddComponents(parentComponents) if err != nil { return errors.Wrapf(err, "error while adding components from the parent devfiles") } - err = d.Data.AddProjects(parentData.Data.GetProjects()) + parentProjects, err := parentData.Data.GetProjects(common.DevfileOptions{}) + if err != nil { + return errors.Wrapf(err, "error while getting projects from the parent devfiles") + } + err = d.Data.AddProjects(parentProjects) if err != nil { return errors.Wrapf(err, "error while adding projects from the parent devfiles") } - err = d.Data.AddStarterProjects(parentData.Data.GetStarterProjects()) + parentStarterProjects, err := parentData.Data.GetStarterProjects(common.DevfileOptions{}) + if err != nil { + return errors.Wrapf(err, "error while getting starter projects from the parent devfiles") + } + err = d.Data.AddStarterProjects(parentStarterProjects) if err != nil { return errors.Wrapf(err, "error while adding starter projects from the parent devfiles") } diff --git a/pkg/testingutil/devfile.go b/pkg/testingutil/devfile.go index f05bfb45..2024c4b0 100644 --- a/pkg/testingutil/devfile.go +++ b/pkg/testingutil/devfile.go @@ -6,6 +6,7 @@ import ( v1 "github.com/devfile/api/pkg/apis/workspaces/v1alpha2" devfilepkg "github.com/devfile/api/pkg/devfile" + "github.com/devfile/library/pkg/devfile/parser/data/v2/common" ) // TestDevfileData is a convenience data type used to mock up a devfile configuration @@ -51,8 +52,24 @@ func (d TestDevfileData) AddEvents(events v1.Events) error { return nil } func (d TestDevfileData) UpdateEvents(postStart, postStop, preStart, preStop []string) {} // GetComponents is a mock function to get the components from a devfile -func (d TestDevfileData) GetComponents() []v1.Component { - return d.Components +func (d TestDevfileData) GetComponents(options common.DevfileOptions) ([]v1.Component, error) { + if len(options.Filter) == 0 { + return d.Components, nil + } + + var components []v1.Component + for _, comp := range d.Components { + filterIn, err := common.FilterDevfileObject(comp.Attributes, options) + if err != nil { + return nil, err + } + + if filterIn { + components = append(components, comp) + } + } + + return components, nil } // AddComponents is a mock function to add components to the test devfile @@ -62,7 +79,7 @@ func (d TestDevfileData) AddComponents(components []v1.Component) error { return func (d TestDevfileData) UpdateComponent(component v1.Component) {} // GetProjects is a mock function to get the projects from a test devfile -func (d TestDevfileData) GetProjects() []v1.Project { +func (d TestDevfileData) GetProjects(options common.DevfileOptions) ([]v1.Project, error) { projectName := [...]string{"test-project", "anotherproject"} clonePath := [...]string{"test-project/", "anotherproject/"} sourceLocation := [...]string{"https://github.com/someproject/test-project.git", "https://github.com/another/project.git"} @@ -94,7 +111,7 @@ func (d TestDevfileData) GetProjects() []v1.Project { }, }, } - return []v1.Project{project1, project2} + return []v1.Project{project1, project2}, nil } @@ -105,8 +122,8 @@ func (d TestDevfileData) AddProjects(projects []v1.Project) error { return nil } func (d TestDevfileData) UpdateProject(project v1.Project) {} // GetStarterProjects is a mock function to get the starter projects from a test devfile -func (d TestDevfileData) GetStarterProjects() []v1.StarterProject { - return []v1.StarterProject{} +func (d TestDevfileData) GetStarterProjects(options common.DevfileOptions) ([]v1.StarterProject, error) { + return []v1.StarterProject{}, nil } // AddStarterProjects is a mock func to add the starter projects to the test devfile @@ -118,31 +135,36 @@ func (d TestDevfileData) AddStarterProjects(projects []v1.StarterProject) error func (d TestDevfileData) UpdateStarterProject(project v1.StarterProject) {} // GetCommands is a mock function to get the commands from a devfile -func (d TestDevfileData) GetCommands() map[string]v1.Command { +func (d TestDevfileData) GetCommands(options common.DevfileOptions) ([]v1.Command, error) { - commands := make(map[string]v1.Command, len(d.Commands)) + var commands []v1.Command for _, command := range d.Commands { // we convert devfile command id to lowercase so that we can handle // cases efficiently without being error prone command.Id = strings.ToLower(command.Id) - commands[command.Id] = command + commands = append(commands, command) } - return commands + return commands, nil } // AddCommands is a mock func that adds commands to the test devfile func (d *TestDevfileData) AddCommands(commands ...v1.Command) error { - commandsMap := d.GetCommands() + devfileCommands, err := d.GetCommands(common.DevfileOptions{}) + if err != nil { + return err + } for _, command := range commands { id := command.Id - if _, ok := commandsMap[id]; !ok { - d.Commands = append(d.Commands, command) - } else { - return fmt.Errorf("command %s already exist in the devfile", id) + for _, devfileCommand := range devfileCommands { + if id == devfileCommand.Id { + return fmt.Errorf("command %s already exist in the devfile", id) + } } + + d.Commands = append(d.Commands, command) } return nil } @@ -164,25 +186,33 @@ func (d TestDevfileData) GetVolumeMountPath(name string) (string, error) { } // GetDevfileContainerComponents gets the container components from the test devfile -func (d TestDevfileData) GetDevfileContainerComponents() []v1.Component { +func (d TestDevfileData) GetDevfileContainerComponents(options common.DevfileOptions) ([]v1.Component, error) { var components []v1.Component - for _, comp := range d.GetComponents() { + devfileComponents, err := d.GetComponents(options) + if err != nil { + return nil, err + } + for _, comp := range devfileComponents { if comp.Container != nil { components = append(components, comp) } } - return components + return components, nil } // GetDevfileVolumeComponents gets the volume components from the test devfile -func (d TestDevfileData) GetDevfileVolumeComponents() []v1.Component { +func (d TestDevfileData) GetDevfileVolumeComponents(options common.DevfileOptions) ([]v1.Component, error) { var components []v1.Component - for _, comp := range d.GetComponents() { + devfileComponents, err := d.GetComponents(options) + if err != nil { + return nil, err + } + for _, comp := range devfileComponents { if comp.Volume != nil { components = append(components, comp) } } - return components + return components, nil } // Validate is a mock validation that always validates without error