mirror of https://github.com/k3s-io/k3s
vendor kustomize
parent
7693a1d5fe
commit
23a9b0c239
|
@ -4163,6 +4163,116 @@
|
|||
"ImportPath": "k8s.io/utils/trace",
|
||||
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/commands/build",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/constants",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/expansion",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/factory",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/fs",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/git",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/gvk",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/image",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/internal/error",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/loader",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/resid",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/resmap",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/resource",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/target",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/types",
|
||||
"Comment": "v2.0.1",
|
||||
"Rev": "ce7e5ee2c30cc5856fea01fe423cf167f2a2d0c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff/fieldpath",
|
||||
"Rev": "e5e029740eb81ee0217ecf9d950c25a0eeb9688a"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,14 +6,50 @@
|
|||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/PuerkitoBio/purell",
|
||||
"Rev": "8a290539e2e8629dbc4e6bad948158f790ec31f4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
"Rev": "782f4967f2dc4564575ca782fe2d04090b5faca8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/emicklei/go-restful",
|
||||
"Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/emicklei/go-restful/log",
|
||||
"Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/evanphx/json-patch",
|
||||
"Rev": "d4020504c68b6bfa818032bedfb48e33e9638506"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ghodss/yaml",
|
||||
"Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/jsonpointer",
|
||||
"Rev": "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/jsonreference",
|
||||
"Rev": "8483a886a90412cd6858df4ea3483dce9c8e35a3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/spec",
|
||||
"Rev": "5bae59e25b21498baea7f9d46e9c147ec106a42e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/swag",
|
||||
"Rev": "5899d5c5e619fda5fa86e14795a835f473ca284c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||
"Rev": "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
||||
|
@ -82,6 +118,18 @@
|
|||
"ImportPath": "github.com/json-iterator/go",
|
||||
"Rev": "ab8a2e0c74be9d3be70b3184d9acc634935ded82"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mailru/easyjson/buffer",
|
||||
"Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mailru/easyjson/jlexer",
|
||||
"Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mailru/easyjson/jwriter",
|
||||
"Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/modern-go/concurrent",
|
||||
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||
|
@ -94,6 +142,10 @@
|
|||
"ImportPath": "github.com/peterbourgon/diskv",
|
||||
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pkg/errors",
|
||||
"Rev": "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pmezard/go-difflib/difflib",
|
||||
"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
|
||||
|
@ -190,6 +242,10 @@
|
|||
"ImportPath": "golang.org/x/text/unicode/norm",
|
||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/width",
|
||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/time/rate",
|
||||
"Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
||||
|
@ -350,6 +406,10 @@
|
|||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/validation",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
@ -362,6 +422,10 @@
|
|||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
@ -442,6 +506,10 @@
|
|||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
@ -458,6 +526,10 @@
|
|||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
@ -478,6 +550,10 @@
|
|||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
@ -566,6 +642,14 @@
|
|||
"ImportPath": "k8s.io/klog",
|
||||
"Rev": "8139d8cb77af419532b33dfa7dd09fbc5f1d344f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/common",
|
||||
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
||||
"Rev": "ced9eb3070a5f1c548ef46e8dfe2a97c208d9f03"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/discovery",
|
||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
@ -614,6 +698,94 @@
|
|||
"ImportPath": "k8s.io/utils/integer",
|
||||
"Rev": "ed37f7428a91fc2a81070808937195dcd46d320e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/commands/build",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/constants",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/expansion",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/factory",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/fs",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/git",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/gvk",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/image",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/internal/error",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/loader",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/resid",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/resmap",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/resource",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/target",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/kustomize/pkg/types",
|
||||
"Rev": "0184d5b69700607a1b9280f303152e2959bc19e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff/fieldpath",
|
||||
"Rev": "e5e029740eb81ee0217ecf9d950c25a0eeb9688a"
|
||||
|
|
|
@ -482,6 +482,24 @@ filegroup(
|
|||
"//vendor/k8s.io/utils/pointer:all-srcs",
|
||||
"//vendor/k8s.io/utils/strings:all-srcs",
|
||||
"//vendor/k8s.io/utils/trace:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/commands/build:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/constants:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/expansion:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/factory:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/fs:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/git:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/gvk:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/image:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/internal/error:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/loader:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/patch:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resid:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resmap:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resource:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/target:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers:all-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/types:all-srcs",
|
||||
"//vendor/sigs.k8s.io/structured-merge-diff/fieldpath:all-srcs",
|
||||
"//vendor/sigs.k8s.io/structured-merge-diff/merge:all-srcs",
|
||||
"//vendor/sigs.k8s.io/structured-merge-diff/schema:all-srcs",
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,33 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["build.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/commands/build",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/commands/build",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/constants:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/loader:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resmap:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/target:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package build
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/pkg/constants"
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
|
||||
"sigs.k8s.io/kustomize/pkg/loader"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/target"
|
||||
)
|
||||
|
||||
// Options contain the options for running a build
|
||||
type Options struct {
|
||||
kustomizationPath string
|
||||
outputPath string
|
||||
}
|
||||
|
||||
// NewOptions creates a Options object
|
||||
func NewOptions(p, o string) *Options {
|
||||
return &Options{
|
||||
kustomizationPath: p,
|
||||
outputPath: o,
|
||||
}
|
||||
}
|
||||
|
||||
var examples = `
|
||||
Use the file somedir/kustomization.yaml to generate a set of api resources:
|
||||
build somedir
|
||||
|
||||
Use a url pointing to a remote directory/kustomization.yaml to generate a set of api resources:
|
||||
build url
|
||||
The url should follow hashicorp/go-getter URL format described in
|
||||
https://github.com/hashicorp/go-getter#url-format
|
||||
|
||||
url examples:
|
||||
sigs.k8s.io/kustomize//examples/multibases?ref=v1.0.6
|
||||
github.com/Liujingfang1/mysql
|
||||
github.com/Liujingfang1/kustomize//examples/helloWorld?ref=repoUrl2
|
||||
`
|
||||
|
||||
// NewCmdBuild creates a new build command.
|
||||
func NewCmdBuild(
|
||||
out io.Writer, fs fs.FileSystem,
|
||||
rf *resmap.Factory,
|
||||
ptf transformer.Factory) *cobra.Command {
|
||||
var o Options
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "build [path]",
|
||||
Short: "Print current configuration per contents of " + constants.KustomizationFileNames[0],
|
||||
Example: examples,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := o.Validate(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return o.RunBuild(out, fs, rf, ptf)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(
|
||||
&o.outputPath,
|
||||
"output", "o", "",
|
||||
"If specified, write the build output to this path.")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Validate validates build command.
|
||||
func (o *Options) Validate(args []string) error {
|
||||
if len(args) > 1 {
|
||||
return errors.New("specify one path to " + constants.KustomizationFileNames[0])
|
||||
}
|
||||
if len(args) == 0 {
|
||||
o.kustomizationPath = "./"
|
||||
} else {
|
||||
o.kustomizationPath = args[0]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunBuild runs build command.
|
||||
func (o *Options) RunBuild(
|
||||
out io.Writer, fSys fs.FileSystem,
|
||||
rf *resmap.Factory, ptf transformer.Factory) error {
|
||||
ldr, err := loader.NewLoader(o.kustomizationPath, fSys)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ldr.Cleanup()
|
||||
kt, err := target.NewKustTarget(ldr, fSys, rf, ptf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allResources, err := kt.MakeCustomizedResMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Output the objects.
|
||||
res, err := allResources.EncodeAsYaml()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if o.outputPath != "" {
|
||||
return fSys.WriteFile(o.outputPath, res)
|
||||
}
|
||||
_, err = out.Write(res)
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["constants.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/constants",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/constants",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package constants holds global constants for the kustomize tool.
|
||||
package constants
|
||||
|
||||
// KustomizationFileNames is a list of filenames that can be recognized and consumbed
|
||||
// by Kustomize.
|
||||
// In each directory, Kustomize searches for file with the name in this list.
|
||||
// Only one match is allowed.
|
||||
var KustomizationFileNames = []string{
|
||||
"kustomization.yaml",
|
||||
"kustomization.yml",
|
||||
"Kustomization",
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["expand.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/expansion",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/expansion",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package expansion provides functions find and replace $(FOO) style variables in strings.
|
||||
package expansion
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
const (
|
||||
operator = '$'
|
||||
referenceOpener = '('
|
||||
referenceCloser = ')'
|
||||
)
|
||||
|
||||
// syntaxWrap returns the input string wrapped by the expansion syntax.
|
||||
func syntaxWrap(input string) string {
|
||||
return string(operator) + string(referenceOpener) + input + string(referenceCloser)
|
||||
}
|
||||
|
||||
// MappingFuncFor returns a mapping function for use with Expand that
|
||||
// implements the expansion semantics defined in the expansion spec; it
|
||||
// returns the input string wrapped in the expansion syntax if no mapping
|
||||
// for the input is found.
|
||||
func MappingFuncFor(context ...map[string]string) func(string) string {
|
||||
return func(input string) string {
|
||||
for _, vars := range context {
|
||||
val, ok := vars[input]
|
||||
if ok {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
return syntaxWrap(input)
|
||||
}
|
||||
}
|
||||
|
||||
// Expand replaces variable references in the input string according to
|
||||
// the expansion spec using the given mapping function to resolve the
|
||||
// values of variables.
|
||||
func Expand(input string, mapping func(string) string) string {
|
||||
var buf bytes.Buffer
|
||||
checkpoint := 0
|
||||
for cursor := 0; cursor < len(input); cursor++ {
|
||||
if input[cursor] == operator && cursor+1 < len(input) {
|
||||
// Copy the portion of the input string since the last
|
||||
// checkpoint into the buffer
|
||||
buf.WriteString(input[checkpoint:cursor])
|
||||
|
||||
// Attempt to read the variable name as defined by the
|
||||
// syntax from the input string
|
||||
read, isVar, advance := tryReadVariableName(input[cursor+1:])
|
||||
|
||||
if isVar {
|
||||
// We were able to read a variable name correctly;
|
||||
// apply the mapping to the variable name and copy the
|
||||
// bytes into the buffer
|
||||
buf.WriteString(mapping(read))
|
||||
} else {
|
||||
// Not a variable name; copy the read bytes into the buffer
|
||||
buf.WriteString(read)
|
||||
}
|
||||
|
||||
// Advance the cursor in the input string to account for
|
||||
// bytes consumed to read the variable name expression
|
||||
cursor += advance
|
||||
|
||||
// Advance the checkpoint in the input string
|
||||
checkpoint = cursor + 1
|
||||
}
|
||||
}
|
||||
|
||||
// Return the buffer and any remaining unwritten bytes in the
|
||||
// input string.
|
||||
return buf.String() + input[checkpoint:]
|
||||
}
|
||||
|
||||
// tryReadVariableName attempts to read a variable name from the input
|
||||
// string and returns the content read from the input, whether that content
|
||||
// represents a variable name to perform mapping on, and the number of bytes
|
||||
// consumed in the input string.
|
||||
//
|
||||
// The input string is assumed not to contain the initial operator.
|
||||
func tryReadVariableName(input string) (string, bool, int) {
|
||||
switch input[0] {
|
||||
case operator:
|
||||
// Escaped operator; return it.
|
||||
return input[0:1], false, 1
|
||||
case referenceOpener:
|
||||
// Scan to expression closer
|
||||
for i := 1; i < len(input); i++ {
|
||||
if input[i] == referenceCloser {
|
||||
return input[1:i], true, i + 1
|
||||
}
|
||||
}
|
||||
|
||||
// Incomplete reference; return it.
|
||||
return string(operator) + string(referenceOpener), false, 1
|
||||
default:
|
||||
// Not the beginning of an expression, ie, an operator
|
||||
// that doesn't begin an expression. Return the operator
|
||||
// and the first rune in the string.
|
||||
return string(operator) + string(input[0]), false, 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["factory.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/factory",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/factory",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resmap:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resource:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Package factory provides factories for kustomize.
|
||||
package factory
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
)
|
||||
|
||||
// KustFactory provides different factories for kustomize
|
||||
type KustFactory struct {
|
||||
ResmapF *resmap.Factory
|
||||
TransformerF transformer.Factory
|
||||
ValidatorF ifc.Validator
|
||||
UnstructF ifc.KunstructuredFactory
|
||||
}
|
||||
|
||||
// NewKustFactory creats a KustFactory instance
|
||||
func NewKustFactory(u ifc.KunstructuredFactory, v ifc.Validator, t transformer.Factory) *KustFactory {
|
||||
return &KustFactory{
|
||||
ResmapF: resmap.NewFactory(resource.NewFactory(u)),
|
||||
TransformerF: t,
|
||||
ValidatorF: v,
|
||||
UnstructF: u,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"confirmeddir.go",
|
||||
"fakefile.go",
|
||||
"fakefileinfo.go",
|
||||
"fakefs.go",
|
||||
"fs.go",
|
||||
"realfile.go",
|
||||
"realfs.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/fs",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/fs",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/sigs.k8s.io/kustomize/pkg/constants:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ConfirmedDir is a clean, absolute, delinkified path
|
||||
// that was confirmed to point to an existing directory.
|
||||
type ConfirmedDir string
|
||||
|
||||
// Return a temporary dir, else error.
|
||||
// The directory is cleaned, no symlinks, etc. so its
|
||||
// returned as a ConfirmedDir.
|
||||
func NewTmpConfirmedDir() (ConfirmedDir, error) {
|
||||
n, err := ioutil.TempDir("", "kustomize-")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ConfirmedDir(n), nil
|
||||
}
|
||||
|
||||
// HasPrefix returns true if the directory argument
|
||||
// is a prefix of self (d) from the point of view of
|
||||
// a file system.
|
||||
//
|
||||
// I.e., it's true if the argument equals or contains
|
||||
// self (d) in a file path sense.
|
||||
//
|
||||
// HasPrefix emulates the semantics of strings.HasPrefix
|
||||
// such that the following are true:
|
||||
//
|
||||
// strings.HasPrefix("foobar", "foobar")
|
||||
// strings.HasPrefix("foobar", "foo")
|
||||
// strings.HasPrefix("foobar", "")
|
||||
//
|
||||
// d := fSys.ConfirmDir("/foo/bar")
|
||||
// d.HasPrefix("/foo/bar")
|
||||
// d.HasPrefix("/foo")
|
||||
// d.HasPrefix("/")
|
||||
//
|
||||
// Not contacting a file system here to check for
|
||||
// actual path existence.
|
||||
//
|
||||
// This is tested on linux, but will have trouble
|
||||
// on other operating systems.
|
||||
// TODO(monopole) Refactor when #golang/go/18358 closes.
|
||||
// See also:
|
||||
// https://github.com/golang/go/issues/18358
|
||||
// https://github.com/golang/dep/issues/296
|
||||
// https://github.com/golang/dep/blob/master/internal/fs/fs.go#L33
|
||||
// https://codereview.appspot.com/5712045
|
||||
func (d ConfirmedDir) HasPrefix(path ConfirmedDir) bool {
|
||||
if path.String() == string(filepath.Separator) || path == d {
|
||||
return true
|
||||
}
|
||||
return strings.HasPrefix(
|
||||
string(d),
|
||||
string(path)+string(filepath.Separator))
|
||||
}
|
||||
|
||||
func (d ConfirmedDir) Join(path string) string {
|
||||
return filepath.Join(string(d), path)
|
||||
}
|
||||
|
||||
func (d ConfirmedDir) String() string {
|
||||
return string(d)
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
)
|
||||
|
||||
var _ File = &FakeFile{}
|
||||
|
||||
// FakeFile implements File in-memory for tests.
|
||||
type FakeFile struct {
|
||||
name string
|
||||
content []byte
|
||||
dir bool
|
||||
open bool
|
||||
}
|
||||
|
||||
// makeDir makes a fake directory.
|
||||
func makeDir(name string) *FakeFile {
|
||||
return &FakeFile{name: name, dir: true}
|
||||
}
|
||||
|
||||
// Close marks the fake file closed.
|
||||
func (f *FakeFile) Close() error {
|
||||
f.open = false
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read never fails, and doesn't mutate p.
|
||||
func (f *FakeFile) Read(p []byte) (n int, err error) {
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Write saves the contents of the argument to memory.
|
||||
func (f *FakeFile) Write(p []byte) (n int, err error) {
|
||||
f.content = p
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// ContentMatches returns true if v matches fake file's content.
|
||||
func (f *FakeFile) ContentMatches(v []byte) bool {
|
||||
return bytes.Equal(v, f.content)
|
||||
}
|
||||
|
||||
// GetContent the content of a fake file.
|
||||
func (f *FakeFile) GetContent() []byte {
|
||||
return f.content
|
||||
}
|
||||
|
||||
// Stat returns nil.
|
||||
func (f *FakeFile) Stat() (os.FileInfo, error) {
|
||||
return nil, nil
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ os.FileInfo = &Fakefileinfo{}
|
||||
|
||||
// Fakefileinfo implements Fakefileinfo using a fake in-memory filesystem.
|
||||
type Fakefileinfo struct {
|
||||
*FakeFile
|
||||
}
|
||||
|
||||
// Name returns the name of the file
|
||||
func (fi *Fakefileinfo) Name() string { return fi.name }
|
||||
|
||||
// Size returns the size of the file
|
||||
func (fi *Fakefileinfo) Size() int64 { return int64(len(fi.content)) }
|
||||
|
||||
// Mode returns the file mode
|
||||
func (fi *Fakefileinfo) Mode() os.FileMode { return 0777 }
|
||||
|
||||
// ModTime returns the modification time
|
||||
func (fi *Fakefileinfo) ModTime() time.Time { return time.Time{} }
|
||||
|
||||
// IsDir returns if it is a directory
|
||||
func (fi *Fakefileinfo) IsDir() bool { return fi.dir }
|
||||
|
||||
// Sys should return underlying data source, but it now returns nil
|
||||
func (fi *Fakefileinfo) Sys() interface{} { return nil }
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/constants"
|
||||
)
|
||||
|
||||
var _ FileSystem = &fakeFs{}
|
||||
|
||||
// fakeFs implements FileSystem using a fake in-memory filesystem.
|
||||
type fakeFs struct {
|
||||
m map[string]*FakeFile
|
||||
}
|
||||
|
||||
// MakeFakeFS returns an instance of fakeFs with no files in it.
|
||||
func MakeFakeFS() *fakeFs {
|
||||
result := &fakeFs{m: map[string]*FakeFile{}}
|
||||
result.Mkdir("/")
|
||||
return result
|
||||
}
|
||||
|
||||
// kustomizationContent is used in tests.
|
||||
const kustomizationContent = `apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namePrefix: some-prefix
|
||||
nameSuffix: some-suffix
|
||||
# Labels to add to all objects and selectors.
|
||||
# These labels would also be used to form the selector for apply --prune
|
||||
# Named differently than “labels” to avoid confusion with metadata for this object
|
||||
commonLabels:
|
||||
app: helloworld
|
||||
commonAnnotations:
|
||||
note: This is an example annotation
|
||||
resources: []
|
||||
#- service.yaml
|
||||
#- ../some-dir/
|
||||
# There could also be configmaps in Base, which would make these overlays
|
||||
configMapGenerator: []
|
||||
# There could be secrets in Base, if just using a fork/rebase workflow
|
||||
secretGenerator: []
|
||||
`
|
||||
|
||||
// Create assures a fake file appears in the in-memory file system.
|
||||
func (fs *fakeFs) Create(name string) (File, error) {
|
||||
f := &FakeFile{}
|
||||
f.open = true
|
||||
fs.m[name] = f
|
||||
return fs.m[name], nil
|
||||
}
|
||||
|
||||
// Mkdir assures a fake directory appears in the in-memory file system.
|
||||
func (fs *fakeFs) Mkdir(name string) error {
|
||||
fs.m[name] = makeDir(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MkdirAll delegates to Mkdir
|
||||
func (fs *fakeFs) MkdirAll(name string) error {
|
||||
return fs.Mkdir(name)
|
||||
}
|
||||
|
||||
// RemoveAll presumably does rm -r on a path.
|
||||
// There's no error.
|
||||
func (fs *fakeFs) RemoveAll(name string) error {
|
||||
var toRemove []string
|
||||
for k := range fs.m {
|
||||
if strings.HasPrefix(k, name) {
|
||||
toRemove = append(toRemove, k)
|
||||
}
|
||||
}
|
||||
for _, k := range toRemove {
|
||||
delete(fs.m, k)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Open returns a fake file in the open state.
|
||||
func (fs *fakeFs) Open(name string) (File, error) {
|
||||
if _, found := fs.m[name]; !found {
|
||||
return nil, fmt.Errorf("file %q cannot be opened", name)
|
||||
}
|
||||
return fs.m[name], nil
|
||||
}
|
||||
|
||||
// CleanedAbs cannot fail.
|
||||
func (fs *fakeFs) CleanedAbs(path string) (ConfirmedDir, string, error) {
|
||||
if fs.IsDir(path) {
|
||||
return ConfirmedDir(path), "", nil
|
||||
}
|
||||
d := filepath.Dir(path)
|
||||
if d == path {
|
||||
return ConfirmedDir(d), "", nil
|
||||
}
|
||||
return ConfirmedDir(d), filepath.Base(path), nil
|
||||
}
|
||||
|
||||
// Exists returns true if file is known.
|
||||
func (fs *fakeFs) Exists(name string) bool {
|
||||
_, found := fs.m[name]
|
||||
return found
|
||||
}
|
||||
|
||||
// Glob returns the list of matching files
|
||||
func (fs *fakeFs) Glob(pattern string) ([]string, error) {
|
||||
var result []string
|
||||
for p := range fs.m {
|
||||
if fs.pathMatch(p, pattern) {
|
||||
result = append(result, p)
|
||||
}
|
||||
}
|
||||
sort.Strings(result)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// IsDir returns true if the file exists and is a directory.
|
||||
func (fs *fakeFs) IsDir(name string) bool {
|
||||
f, found := fs.m[name]
|
||||
if found && f.dir {
|
||||
return true
|
||||
}
|
||||
if !strings.HasSuffix(name, "/") {
|
||||
name = name + "/"
|
||||
}
|
||||
for k := range fs.m {
|
||||
if strings.HasPrefix(k, name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ReadFile always returns an empty bytes and error depending on content of m.
|
||||
func (fs *fakeFs) ReadFile(name string) ([]byte, error) {
|
||||
if ff, found := fs.m[name]; found {
|
||||
return ff.content, nil
|
||||
}
|
||||
return nil, fmt.Errorf("cannot read file %q", name)
|
||||
}
|
||||
|
||||
func (fs *fakeFs) ReadTestKustomization() ([]byte, error) {
|
||||
return fs.ReadFile(constants.KustomizationFileNames[0])
|
||||
}
|
||||
|
||||
// WriteFile always succeeds and does nothing.
|
||||
func (fs *fakeFs) WriteFile(name string, c []byte) error {
|
||||
ff := &FakeFile{}
|
||||
ff.Write(c)
|
||||
fs.m[name] = ff
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteTestKustomization writes a standard test file.
|
||||
func (fs *fakeFs) WriteTestKustomization() {
|
||||
fs.WriteTestKustomizationWith([]byte(kustomizationContent))
|
||||
}
|
||||
|
||||
// WriteTestKustomizationWith writes a standard test file.
|
||||
func (fs *fakeFs) WriteTestKustomizationWith(bytes []byte) {
|
||||
fs.WriteFile(constants.KustomizationFileNames[0], bytes)
|
||||
}
|
||||
|
||||
func (fs *fakeFs) pathMatch(path, pattern string) bool {
|
||||
match, _ := filepath.Match(pattern, path)
|
||||
return match
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package fs provides a file system abstraction layer.
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// FileSystem groups basic os filesystem methods.
|
||||
type FileSystem interface {
|
||||
Create(name string) (File, error)
|
||||
Mkdir(name string) error
|
||||
MkdirAll(name string) error
|
||||
RemoveAll(name string) error
|
||||
Open(name string) (File, error)
|
||||
IsDir(name string) bool
|
||||
CleanedAbs(path string) (ConfirmedDir, string, error)
|
||||
Exists(name string) bool
|
||||
Glob(pattern string) ([]string, error)
|
||||
ReadFile(name string) ([]byte, error)
|
||||
WriteFile(name string, data []byte) error
|
||||
}
|
||||
|
||||
// File groups the basic os.File methods.
|
||||
type File interface {
|
||||
io.ReadWriteCloser
|
||||
Stat() (os.FileInfo, error)
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var _ File = &realFile{}
|
||||
|
||||
// realFile implements File using the local filesystem.
|
||||
type realFile struct {
|
||||
file *os.File
|
||||
}
|
||||
|
||||
// Close closes a file.
|
||||
func (f *realFile) Close() error { return f.file.Close() }
|
||||
|
||||
// Read reads a file's content.
|
||||
func (f *realFile) Read(p []byte) (n int, err error) { return f.file.Read(p) }
|
||||
|
||||
// Write writes bytes to a file
|
||||
func (f *realFile) Write(p []byte) (n int, err error) { return f.file.Write(p) }
|
||||
|
||||
// Stat returns an interface which has all the information regarding the file.
|
||||
func (f *realFile) Stat() (os.FileInfo, error) { return f.file.Stat() }
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var _ FileSystem = realFS{}
|
||||
|
||||
// realFS implements FileSystem using the local filesystem.
|
||||
type realFS struct{}
|
||||
|
||||
// MakeRealFS makes an instance of realFS.
|
||||
func MakeRealFS() FileSystem {
|
||||
return realFS{}
|
||||
}
|
||||
|
||||
// Create delegates to os.Create.
|
||||
func (realFS) Create(name string) (File, error) { return os.Create(name) }
|
||||
|
||||
// Mkdir delegates to os.Mkdir.
|
||||
func (realFS) Mkdir(name string) error {
|
||||
return os.Mkdir(name, 0777|os.ModeDir)
|
||||
}
|
||||
|
||||
// MkdirAll delegates to os.MkdirAll.
|
||||
func (realFS) MkdirAll(name string) error {
|
||||
return os.MkdirAll(name, 0777|os.ModeDir)
|
||||
}
|
||||
|
||||
// RemoveAll delegates to os.RemoveAll.
|
||||
func (realFS) RemoveAll(name string) error {
|
||||
return os.RemoveAll(name)
|
||||
}
|
||||
|
||||
// Open delegates to os.Open.
|
||||
func (realFS) Open(name string) (File, error) { return os.Open(name) }
|
||||
|
||||
// CleanedAbs returns a cleaned, absolute path
|
||||
// with no symbolic links split into directory
|
||||
// and file components. If the entire path is
|
||||
// a directory, the file component is an empty
|
||||
// string.
|
||||
func (x realFS) CleanedAbs(
|
||||
path string) (ConfirmedDir, string, error) {
|
||||
absRoot, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf(
|
||||
"abs path error on '%s' : %v", path, err)
|
||||
}
|
||||
deLinked, err := filepath.EvalSymlinks(absRoot)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf(
|
||||
"evalsymlink failure on '%s' : %v", path, err)
|
||||
}
|
||||
if x.IsDir(deLinked) {
|
||||
return ConfirmedDir(deLinked), "", nil
|
||||
}
|
||||
d := filepath.Dir(deLinked)
|
||||
if !x.IsDir(d) {
|
||||
// Programmer/assumption error.
|
||||
log.Fatalf("first part of '%s' not a directory", deLinked)
|
||||
}
|
||||
if d == deLinked {
|
||||
// Programmer/assumption error.
|
||||
log.Fatalf("d '%s' should be a subset of deLinked", d)
|
||||
}
|
||||
f := filepath.Base(deLinked)
|
||||
if filepath.Join(d, f) != deLinked {
|
||||
// Programmer/assumption error.
|
||||
log.Fatalf("these should be equal: '%s', '%s'",
|
||||
filepath.Join(d, f), deLinked)
|
||||
}
|
||||
return ConfirmedDir(d), f, nil
|
||||
}
|
||||
|
||||
// Exists returns true if os.Stat succeeds.
|
||||
func (realFS) Exists(name string) bool {
|
||||
_, err := os.Stat(name)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Glob returns the list of matching files
|
||||
func (realFS) Glob(pattern string) ([]string, error) {
|
||||
return filepath.Glob(pattern)
|
||||
}
|
||||
|
||||
// IsDir delegates to os.Stat and FileInfo.IsDir
|
||||
func (realFS) IsDir(name string) bool {
|
||||
info, err := os.Stat(name)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return info.IsDir()
|
||||
}
|
||||
|
||||
// ReadFile delegates to ioutil.ReadFile.
|
||||
func (realFS) ReadFile(name string) ([]byte, error) { return ioutil.ReadFile(name) }
|
||||
|
||||
// WriteFile delegates to ioutil.WriteFile with read/write permissions.
|
||||
func (realFS) WriteFile(name string, c []byte) error {
|
||||
return ioutil.WriteFile(name, c, 0666)
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cloner.go",
|
||||
"repospec.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/git",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/git",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os/exec"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
)
|
||||
|
||||
// Cloner is a function that can clone a git repo.
|
||||
type Cloner func(repoSpec *RepoSpec) error
|
||||
|
||||
// ClonerUsingGitExec uses a local git install, as opposed
|
||||
// to say, some remote API, to obtain a local clone of
|
||||
// a remote repo.
|
||||
func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
gitProgram, err := exec.LookPath("git")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "no 'git' program on path")
|
||||
}
|
||||
repoSpec.cloneDir, err = fs.NewTmpConfirmedDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command(
|
||||
gitProgram,
|
||||
"clone",
|
||||
repoSpec.CloneSpec(),
|
||||
repoSpec.cloneDir.String())
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "trouble cloning %s", repoSpec.raw)
|
||||
}
|
||||
if repoSpec.ref == "" {
|
||||
return nil
|
||||
}
|
||||
cmd = exec.Command(gitProgram, "checkout", repoSpec.ref)
|
||||
cmd.Dir = repoSpec.cloneDir.String()
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return errors.Wrapf(
|
||||
err, "trouble checking out href %s", repoSpec.ref)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DoNothingCloner returns a cloner that only sets
|
||||
// cloneDir field in the repoSpec. It's assumed that
|
||||
// the cloneDir is associated with some fake filesystem
|
||||
// used in a test.
|
||||
func DoNothingCloner(dir fs.ConfirmedDir) Cloner {
|
||||
return func(rs *RepoSpec) error {
|
||||
rs.cloneDir = dir
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
)
|
||||
|
||||
// RepoSpec specifies a git repository and a branch and path therein.
|
||||
type RepoSpec struct {
|
||||
// Raw, original spec, used to look for cycles.
|
||||
// TODO(monopole): Drop raw, use processed fields instead.
|
||||
raw string
|
||||
|
||||
// Host, e.g. github.com
|
||||
host string
|
||||
|
||||
// orgRepo name (organization/repoName),
|
||||
// e.g. kubernetes-sigs/kustomize
|
||||
orgRepo string
|
||||
|
||||
// ConfirmedDir where the orgRepo is cloned to.
|
||||
cloneDir fs.ConfirmedDir
|
||||
|
||||
// Relative path in the repository, and in the cloneDir,
|
||||
// to a Kustomization.
|
||||
path string
|
||||
|
||||
// Branch or tag reference.
|
||||
ref string
|
||||
}
|
||||
|
||||
// CloneSpec returns a string suitable for "git clone {spec}".
|
||||
func (x *RepoSpec) CloneSpec() string {
|
||||
if isAzureHost(x.host) || isAWSHost(x.host) {
|
||||
return x.host + x.orgRepo
|
||||
}
|
||||
return x.host + x.orgRepo + gitSuffix
|
||||
}
|
||||
|
||||
func (x *RepoSpec) CloneDir() fs.ConfirmedDir {
|
||||
return x.cloneDir
|
||||
}
|
||||
|
||||
func (x *RepoSpec) Raw() string {
|
||||
return x.raw
|
||||
}
|
||||
|
||||
func (x *RepoSpec) AbsPath() string {
|
||||
return x.cloneDir.Join(x.path)
|
||||
}
|
||||
|
||||
func (x *RepoSpec) Cleaner(fSys fs.FileSystem) func() error {
|
||||
return func() error { return fSys.RemoveAll(x.cloneDir.String()) }
|
||||
}
|
||||
|
||||
// From strings like git@github.com:someOrg/someRepo.git or
|
||||
// https://github.com/someOrg/someRepo?ref=someHash, extract
|
||||
// the parts.
|
||||
func NewRepoSpecFromUrl(n string) (*RepoSpec, error) {
|
||||
if filepath.IsAbs(n) {
|
||||
return nil, fmt.Errorf("uri looks like abs path: %s", n)
|
||||
}
|
||||
host, orgRepo, path, gitRef := parseGithubUrl(n)
|
||||
if orgRepo == "" {
|
||||
return nil, fmt.Errorf("url lacks orgRepo: %s", n)
|
||||
}
|
||||
if host == "" {
|
||||
return nil, fmt.Errorf("url lacks host: %s", n)
|
||||
}
|
||||
return &RepoSpec{
|
||||
raw: n, host: host, orgRepo: orgRepo,
|
||||
path: path, ref: gitRef}, nil
|
||||
}
|
||||
|
||||
const (
|
||||
refQuery = "?ref="
|
||||
gitSuffix = ".git"
|
||||
)
|
||||
|
||||
// From strings like git@github.com:someOrg/someRepo.git or
|
||||
// https://github.com/someOrg/someRepo?ref=someHash, extract
|
||||
// the parts.
|
||||
func parseGithubUrl(n string) (
|
||||
host string, orgRepo string, path string, gitRef string) {
|
||||
host, n = parseHostSpec(n)
|
||||
|
||||
if strings.Contains(n, gitSuffix) {
|
||||
index := strings.Index(n, gitSuffix)
|
||||
orgRepo = n[0:index]
|
||||
n = n[index+len(gitSuffix):]
|
||||
path, gitRef = peelQuery(n)
|
||||
return
|
||||
}
|
||||
|
||||
i := strings.Index(n, "/")
|
||||
if i < 1 {
|
||||
return "", "", "", ""
|
||||
}
|
||||
j := strings.Index(n[i+1:], "/")
|
||||
if j >= 0 {
|
||||
j += i + 1
|
||||
orgRepo = n[:j]
|
||||
path, gitRef = peelQuery(n[j+1:])
|
||||
} else {
|
||||
path = ""
|
||||
orgRepo, gitRef = peelQuery(n)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func peelQuery(arg string) (string, string) {
|
||||
j := strings.Index(arg, refQuery)
|
||||
if j >= 0 {
|
||||
return arg[:j], arg[j+len(refQuery):]
|
||||
}
|
||||
return arg, ""
|
||||
}
|
||||
|
||||
func parseHostSpec(n string) (string, string) {
|
||||
var host string
|
||||
// Start accumulating the host part.
|
||||
for _, p := range []string{
|
||||
// Order matters here.
|
||||
"git::", "gh:", "ssh://", "https://", "http://",
|
||||
"git@", "github.com:", "github.com/"} {
|
||||
if len(p) < len(n) && strings.ToLower(n[:len(p)]) == p {
|
||||
n = n[len(p):]
|
||||
host += p
|
||||
}
|
||||
}
|
||||
if host == "git@" {
|
||||
i := strings.Index(n, "/")
|
||||
if i > -1 {
|
||||
host += n[:i+1]
|
||||
n = n[i+1:]
|
||||
} else {
|
||||
i = strings.Index(n, ":")
|
||||
if i > -1 {
|
||||
host += n[:i+1]
|
||||
n = n[i+1:]
|
||||
}
|
||||
}
|
||||
return host, n
|
||||
}
|
||||
|
||||
// If host is a http(s) or ssh URL, grab the domain part.
|
||||
for _, p := range []string{
|
||||
"ssh://", "https://", "http://"} {
|
||||
if strings.HasSuffix(host, p) {
|
||||
i := strings.Index(n, "/")
|
||||
if i > -1 {
|
||||
host = host + n[0:i+1]
|
||||
n = n[i+1:]
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return normalizeGitHostSpec(host), n
|
||||
}
|
||||
|
||||
func normalizeGitHostSpec(host string) string {
|
||||
s := strings.ToLower(host)
|
||||
if strings.Contains(s, "github.com") {
|
||||
if strings.Contains(s, "git@") || strings.Contains(s, "ssh:") {
|
||||
host = "git@github.com:"
|
||||
} else {
|
||||
host = "https://github.com/"
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(s, "git::") {
|
||||
host = strings.TrimLeft(s, "git::")
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
// The format of Azure repo URL is documented
|
||||
// https://docs.microsoft.com/en-us/azure/devops/repos/git/clone?view=vsts&tabs=visual-studio#clone_url
|
||||
func isAzureHost(host string) bool {
|
||||
return strings.Contains(host, "dev.azure.com") ||
|
||||
strings.Contains(host, "visualstudio.com")
|
||||
}
|
||||
|
||||
// The format of AWS repo URL is documented
|
||||
// https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html
|
||||
func isAWSHost(host string) bool {
|
||||
return strings.Contains(host, "amazonaws.com")
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gvk.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/gvk",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/gvk",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gvk
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Gvk identifies a Kubernetes API type.
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
||||
type Gvk struct {
|
||||
Group string `json:"group,omitempty" yaml:"group,omitempty"`
|
||||
Version string `json:"version,omitempty" yaml:"version,omitempty"`
|
||||
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
|
||||
}
|
||||
|
||||
// FromKind makes a Gvk with only the kind specified.
|
||||
func FromKind(k string) Gvk {
|
||||
return Gvk{
|
||||
Kind: k,
|
||||
}
|
||||
}
|
||||
|
||||
// Values that are brief but meaningful in logs.
|
||||
const (
|
||||
noGroup = "~G"
|
||||
noVersion = "~V"
|
||||
noKind = "~K"
|
||||
separator = "_"
|
||||
)
|
||||
|
||||
// String returns a string representation of the GVK.
|
||||
func (x Gvk) String() string {
|
||||
g := x.Group
|
||||
if g == "" {
|
||||
g = noGroup
|
||||
}
|
||||
v := x.Version
|
||||
if v == "" {
|
||||
v = noVersion
|
||||
}
|
||||
k := x.Kind
|
||||
if k == "" {
|
||||
k = noKind
|
||||
}
|
||||
return strings.Join([]string{g, v, k}, separator)
|
||||
}
|
||||
|
||||
// Equals returns true if the Gvk's have equal fields.
|
||||
func (x Gvk) Equals(o Gvk) bool {
|
||||
return x.Group == o.Group && x.Version == o.Version && x.Kind == o.Kind
|
||||
}
|
||||
|
||||
// An attempt to order things to help k8s, e.g.
|
||||
// a Service should come before things that refer to it.
|
||||
// Namespace should be first.
|
||||
// In some cases order just specified to provide determinism.
|
||||
var order = []string{
|
||||
"Namespace",
|
||||
"StorageClass",
|
||||
"CustomResourceDefinition",
|
||||
"ServiceAccount",
|
||||
"Role",
|
||||
"ClusterRole",
|
||||
"RoleBinding",
|
||||
"ClusterRoleBinding",
|
||||
"ConfigMap",
|
||||
"Secret",
|
||||
"Service",
|
||||
"Deployment",
|
||||
"StatefulSet",
|
||||
"CronJob",
|
||||
"PodDisruptionBudget",
|
||||
}
|
||||
var typeOrders = func() map[string]int {
|
||||
m := map[string]int{}
|
||||
for i, n := range order {
|
||||
m[n] = i
|
||||
}
|
||||
return m
|
||||
}()
|
||||
|
||||
// IsLessThan returns true if self is less than the argument.
|
||||
func (x Gvk) IsLessThan(o Gvk) bool {
|
||||
indexI, foundI := typeOrders[x.Kind]
|
||||
indexJ, foundJ := typeOrders[o.Kind]
|
||||
if foundI && foundJ {
|
||||
if indexI != indexJ {
|
||||
return indexI < indexJ
|
||||
}
|
||||
}
|
||||
if foundI && !foundJ {
|
||||
return true
|
||||
}
|
||||
if !foundI && foundJ {
|
||||
return false
|
||||
}
|
||||
return x.String() < o.String()
|
||||
}
|
||||
|
||||
// IsSelected returns true if `selector` selects `x`; otherwise, false.
|
||||
// If `selector` and `x` are the same, return true.
|
||||
// If `selector` is nil, it is considered a wildcard match, returning true.
|
||||
// If selector fields are empty, they are considered wildcards matching
|
||||
// anything in the corresponding fields, e.g.
|
||||
//
|
||||
// this item:
|
||||
// <Group: "extensions", Version: "v1beta1", Kind: "Deployment">
|
||||
//
|
||||
// is selected by
|
||||
// <Group: "", Version: "", Kind: "Deployment">
|
||||
//
|
||||
// but rejected by
|
||||
// <Group: "apps", Version: "", Kind: "Deployment">
|
||||
//
|
||||
func (x Gvk) IsSelected(selector *Gvk) bool {
|
||||
if selector == nil {
|
||||
return true
|
||||
}
|
||||
if len(selector.Group) > 0 {
|
||||
if x.Group != selector.Group {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(selector.Version) > 0 {
|
||||
if x.Version != selector.Version {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(selector.Kind) > 0 {
|
||||
if x.Kind != selector.Kind {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var clusterLevelKinds = []string{
|
||||
"APIService",
|
||||
"ClusterRoleBinding",
|
||||
"ClusterRole",
|
||||
"CustomResourceDefinition",
|
||||
"Namespace",
|
||||
"PersistentVolume",
|
||||
}
|
||||
|
||||
// IsClusterKind returns true if x is a cluster-level Gvk
|
||||
func (x Gvk) IsClusterKind() bool {
|
||||
for _, k := range clusterLevelKinds {
|
||||
if k == x.Kind {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ClusterLevelGvks returns a slice of cluster-level Gvks
|
||||
func ClusterLevelGvks() []Gvk {
|
||||
var result []Gvk
|
||||
for _, k := range clusterLevelKinds {
|
||||
result = append(result, Gvk{Kind: k})
|
||||
}
|
||||
return result
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["ifc.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/ifc",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/ifc",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/gvk:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package ifc holds miscellaneous interfaces used by kustomize.
|
||||
package ifc
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// Validator provides functions to validate annotations and labels
|
||||
type Validator interface {
|
||||
MakeAnnotationValidator() func(map[string]string) error
|
||||
MakeLabelValidator() func(map[string]string) error
|
||||
ValidateNamespace(string) []string
|
||||
}
|
||||
|
||||
// Loader interface exposes methods to read bytes.
|
||||
type Loader interface {
|
||||
// Root returns the root location for this Loader.
|
||||
Root() string
|
||||
// New returns Loader located at newRoot.
|
||||
New(newRoot string) (Loader, error)
|
||||
// Load returns the bytes read from the location or an error.
|
||||
Load(location string) ([]byte, error)
|
||||
// Cleanup cleans the loader
|
||||
Cleanup() error
|
||||
}
|
||||
|
||||
// Kunstructured allows manipulation of k8s objects
|
||||
// that do not have Golang structs.
|
||||
type Kunstructured interface {
|
||||
Map() map[string]interface{}
|
||||
SetMap(map[string]interface{})
|
||||
Copy() Kunstructured
|
||||
GetFieldValue(string) (string, error)
|
||||
MarshalJSON() ([]byte, error)
|
||||
UnmarshalJSON([]byte) error
|
||||
GetGvk() gvk.Gvk
|
||||
GetKind() string
|
||||
GetName() string
|
||||
SetName(string)
|
||||
GetLabels() map[string]string
|
||||
SetLabels(map[string]string)
|
||||
GetAnnotations() map[string]string
|
||||
SetAnnotations(map[string]string)
|
||||
}
|
||||
|
||||
// KunstructuredFactory makes instances of Kunstructured.
|
||||
type KunstructuredFactory interface {
|
||||
SliceFromBytes([]byte) ([]Kunstructured, error)
|
||||
FromMap(m map[string]interface{}) Kunstructured
|
||||
MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (Kunstructured, error)
|
||||
MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (Kunstructured, error)
|
||||
Set(ldr Loader)
|
||||
}
|
||||
|
||||
// See core.v1.SecretTypeOpaque
|
||||
const SecretTypeOpaque = "Opaque"
|
|
@ -0,0 +1,27 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["factory.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resource:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package patch holds miscellaneous interfaces used by kustomize.
|
||||
package transformer
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
)
|
||||
|
||||
// Factory makes transformers
|
||||
type Factory interface {
|
||||
MakePatchTransformer(slice []*resource.Resource, rf *resource.Factory) (transformers.Transformer, error)
|
||||
MakeHashTransformer() transformers.Transformer
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"deprecatedimage.go",
|
||||
"image.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/image",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/image",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
// DeprecatedImage contains an image and a new tag,
|
||||
// which will replace the original tag.
|
||||
// Deprecated, instead use Image.
|
||||
type DeprecatedImage struct {
|
||||
// Name is a tag-less image name.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
|
||||
// NewTag is the value to use in replacing the original tag.
|
||||
NewTag string `json:"newTag,omitempty" yaml:"newTag,omitempty"`
|
||||
|
||||
// Digest is the value used to replace the original image tag.
|
||||
// If digest is present NewTag value is ignored.
|
||||
Digest string `json:"digest,omitempty" yaml:"digest,omitempty"`
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package image provides struct definitions and libraries
|
||||
// for image overwriting of names, tags and digest.
|
||||
package image
|
||||
|
||||
// Image contains an image name, a new name, a new tag or digest,
|
||||
// which will replace the original name and tag.
|
||||
type Image struct {
|
||||
// Name is a tag-less image name.
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
|
||||
// NewName is the value used to replace the original name.
|
||||
NewName string `json:"newName,omitempty" yaml:"newName,omitempty"`
|
||||
|
||||
// NewTag is the value used to replace the original tag.
|
||||
NewTag string `json:"newTag,omitempty" yaml:"newTag,omitempty"`
|
||||
|
||||
// Digest is the value used to replace the original image tag.
|
||||
// If digest is present NewTag value is ignored.
|
||||
Digest string `json:"digest,omitempty" yaml:"digest,omitempty"`
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"configmaperror.go",
|
||||
"kustomizationerror.go",
|
||||
"patcherror.go",
|
||||
"resourceerror.go",
|
||||
"secreterror.go",
|
||||
"yamlformaterror.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/internal/error",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/internal/error",
|
||||
visibility = ["//vendor/sigs.k8s.io/kustomize/pkg:__subpackages__"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package error has contextual error types.
|
||||
package error
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ConfigmapError represents error with a configmap.
|
||||
type ConfigmapError struct {
|
||||
Path string
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
func (e ConfigmapError) Error() string {
|
||||
return fmt.Sprintf("Kustomization file [%s] encounters a configmap error: %s\n", e.Path, e.ErrorMsg)
|
||||
}
|
61
vendor/sigs.k8s.io/kustomize/pkg/internal/error/kustomizationerror.go
generated
vendored
Normal file
61
vendor/sigs.k8s.io/kustomize/pkg/internal/error/kustomizationerror.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// KustomizationError represents an error with a kustomization.
|
||||
type KustomizationError struct {
|
||||
KustomizationPath string
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
func (ke KustomizationError) Error() string {
|
||||
return fmt.Sprintf("Kustomization File [%s]: %s\n", ke.KustomizationPath, ke.ErrorMsg)
|
||||
}
|
||||
|
||||
// KustomizationErrors collects all errors.
|
||||
type KustomizationErrors struct {
|
||||
kErrors []error
|
||||
}
|
||||
|
||||
func (ke *KustomizationErrors) Error() string {
|
||||
errormsg := ""
|
||||
for _, e := range ke.kErrors {
|
||||
errormsg += e.Error() + "\n"
|
||||
}
|
||||
return errormsg
|
||||
}
|
||||
|
||||
// Append adds error to a collection of errors.
|
||||
func (ke *KustomizationErrors) Append(e error) {
|
||||
ke.kErrors = append(ke.kErrors, e)
|
||||
}
|
||||
|
||||
// Get returns all collected errors.
|
||||
func (ke *KustomizationErrors) Get() []error {
|
||||
return ke.kErrors
|
||||
}
|
||||
|
||||
// BatchAppend adds all errors from another KustomizationErrors
|
||||
func (ke *KustomizationErrors) BatchAppend(e KustomizationErrors) {
|
||||
for _, err := range e.Get() {
|
||||
ke.kErrors = append(ke.kErrors, err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// PatchError represents error during Patch.
|
||||
type PatchError struct {
|
||||
KustomizationPath string
|
||||
PatchFilepath string
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
func (e PatchError) Error() string {
|
||||
return fmt.Sprintf("Kustomization file [%s] encounters a patch error for [%s]: %s\n", e.KustomizationPath, e.PatchFilepath, e.ErrorMsg)
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ResourceError represents error in a resource.
|
||||
type ResourceError struct {
|
||||
KustomizationPath string
|
||||
ResourceFilepath string
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
func (e ResourceError) Error() string {
|
||||
return fmt.Sprintf("Kustomization file [%s] encounters a resource error for [%s]: %s\n", e.KustomizationPath, e.ResourceFilepath, e.ErrorMsg)
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package error
|
||||
|
||||
import "fmt"
|
||||
|
||||
// SecretError represents error with a secret.
|
||||
type SecretError struct {
|
||||
KustomizationPath string
|
||||
// ErrorMsg is an error message
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
func (e SecretError) Error() string {
|
||||
return fmt.Sprintf("Kustomization file [%s] encounters a secret error: %s\n", e.KustomizationPath, e.ErrorMsg)
|
||||
}
|
48
vendor/sigs.k8s.io/kustomize/pkg/internal/error/yamlformaterror.go
generated
vendored
Normal file
48
vendor/sigs.k8s.io/kustomize/pkg/internal/error/yamlformaterror.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package error has contextual error types.
|
||||
package error
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// YamlFormatError represents error with yaml file name where json/yaml format error happens.
|
||||
type YamlFormatError struct {
|
||||
Path string
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
func (e YamlFormatError) Error() string {
|
||||
return fmt.Sprintf("YAML file [%s] encounters a format error.\n%s\n", e.Path, e.ErrorMsg)
|
||||
}
|
||||
|
||||
// Handler handles YamlFormatError
|
||||
func Handler(e error, path string) error {
|
||||
if isYAMLSyntaxError(e) {
|
||||
return YamlFormatError{
|
||||
Path: path,
|
||||
ErrorMsg: e.Error(),
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func isYAMLSyntaxError(e error) bool {
|
||||
return strings.Contains(e.Error(), "error converting YAML to JSON") || strings.Contains(e.Error(), "error unmarshaling JSON")
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"fileloader.go",
|
||||
"loader.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/loader",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/loader",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/git:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/git"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
// fileLoader is a kustomization's interface to files.
|
||||
//
|
||||
// The directory in which a kustomization file sits
|
||||
// is referred to below as the kustomization's root.
|
||||
//
|
||||
// An instance of fileLoader has an immutable root,
|
||||
// and offers a `New` method returning a new loader
|
||||
// with a new root.
|
||||
//
|
||||
// A kustomization file refers to two kinds of files:
|
||||
//
|
||||
// * supplemental data paths
|
||||
//
|
||||
// `Load` is used to visit these paths.
|
||||
//
|
||||
// They must terminate in or below the root.
|
||||
//
|
||||
// They hold things like resources, patches,
|
||||
// data for ConfigMaps, etc.
|
||||
//
|
||||
// * bases; other kustomizations
|
||||
//
|
||||
// `New` is used to load bases.
|
||||
//
|
||||
// A base can be either a remote git repo URL, or
|
||||
// a directory specified relative to the current
|
||||
// root. In the former case, the repo is locally
|
||||
// cloned, and the new loader is rooted on a path
|
||||
// in that clone.
|
||||
//
|
||||
// As loaders create new loaders, a root history
|
||||
// is established, and used to disallow:
|
||||
//
|
||||
// - A base that is a repository that, in turn,
|
||||
// specifies a base repository seen previously
|
||||
// in the loading stack (a cycle).
|
||||
//
|
||||
// - An overlay depending on a base positioned at
|
||||
// or above it. I.e. '../foo' is OK, but '.',
|
||||
// '..', '../..', etc. are disallowed. Allowing
|
||||
// such a base has no advantages and encourages
|
||||
// cycles, particularly if some future change
|
||||
// were to introduce globbing to file
|
||||
// specifications in the kustomization file.
|
||||
//
|
||||
// These restrictions assure that kustomizations
|
||||
// are self-contained and relocatable, and impose
|
||||
// some safety when relying on remote kustomizations,
|
||||
// e.g. a ConfigMap generator specified to read
|
||||
// from /etc/passwd will fail.
|
||||
//
|
||||
type fileLoader struct {
|
||||
// Loader that spawned this loader.
|
||||
// Used to avoid cycles.
|
||||
referrer *fileLoader
|
||||
// An absolute, cleaned path to a directory.
|
||||
// The Load function reads from this directory,
|
||||
// or directories below it.
|
||||
root fs.ConfirmedDir
|
||||
// If this is non-nil, the files were
|
||||
// obtained from the given repository.
|
||||
repoSpec *git.RepoSpec
|
||||
// File system utilities.
|
||||
fSys fs.FileSystem
|
||||
// Used to clone repositories.
|
||||
cloner git.Cloner
|
||||
// Used to clean up, as needed.
|
||||
cleaner func() error
|
||||
}
|
||||
|
||||
// NewFileLoaderAtCwd returns a loader that loads from ".".
|
||||
func NewFileLoaderAtCwd(fSys fs.FileSystem) *fileLoader {
|
||||
return newLoaderOrDie(fSys, ".")
|
||||
}
|
||||
|
||||
// NewFileLoaderAtRoot returns a loader that loads from "/".
|
||||
func NewFileLoaderAtRoot(fSys fs.FileSystem) *fileLoader {
|
||||
return newLoaderOrDie(fSys, string(filepath.Separator))
|
||||
}
|
||||
|
||||
// Root returns the absolute path that is prepended to any
|
||||
// relative paths used in Load.
|
||||
func (l *fileLoader) Root() string {
|
||||
return l.root.String()
|
||||
}
|
||||
|
||||
func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader {
|
||||
root, err := demandDirectoryRoot(fSys, path)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to make loader at '%s'; %v", path, err)
|
||||
}
|
||||
return newLoaderAtConfirmedDir(
|
||||
root, fSys, nil, git.ClonerUsingGitExec)
|
||||
}
|
||||
|
||||
// newLoaderAtConfirmedDir returns a new fileLoader with given root.
|
||||
func newLoaderAtConfirmedDir(
|
||||
root fs.ConfirmedDir, fSys fs.FileSystem,
|
||||
referrer *fileLoader, cloner git.Cloner) *fileLoader {
|
||||
return &fileLoader{
|
||||
root: root,
|
||||
referrer: referrer,
|
||||
fSys: fSys,
|
||||
cloner: cloner,
|
||||
cleaner: func() error { return nil },
|
||||
}
|
||||
}
|
||||
|
||||
// Assure that the given path is in fact a directory.
|
||||
func demandDirectoryRoot(
|
||||
fSys fs.FileSystem, path string) (fs.ConfirmedDir, error) {
|
||||
if path == "" {
|
||||
return "", fmt.Errorf(
|
||||
"loader root cannot be empty")
|
||||
}
|
||||
d, f, err := fSys.CleanedAbs(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf(
|
||||
"absolute path error in '%s' : %v", path, err)
|
||||
}
|
||||
if f != "" {
|
||||
return "", fmt.Errorf(
|
||||
"got file '%s', but '%s' must be a directory to be a root",
|
||||
f, path)
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// New returns a new Loader, rooted relative to current loader,
|
||||
// or rooted in a temp directory holding a git repo clone.
|
||||
func (l *fileLoader) New(path string) (ifc.Loader, error) {
|
||||
if path == "" {
|
||||
return nil, fmt.Errorf("new root cannot be empty")
|
||||
}
|
||||
repoSpec, err := git.NewRepoSpecFromUrl(path)
|
||||
if err == nil {
|
||||
// Treat this as git repo clone request.
|
||||
if err := l.errIfRepoCycle(repoSpec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newLoaderAtGitClone(repoSpec, l.fSys, l.referrer, l.cloner)
|
||||
}
|
||||
if filepath.IsAbs(path) {
|
||||
return nil, fmt.Errorf("new root '%s' cannot be absolute", path)
|
||||
}
|
||||
root, err := demandDirectoryRoot(l.fSys, l.root.Join(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := l.errIfGitContainmentViolation(root); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := l.errIfArgEqualOrHigher(root); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newLoaderAtConfirmedDir(
|
||||
root, l.fSys, l, l.cloner), nil
|
||||
}
|
||||
|
||||
// newLoaderAtGitClone returns a new Loader pinned to a temporary
|
||||
// directory holding a cloned git repo.
|
||||
func newLoaderAtGitClone(
|
||||
repoSpec *git.RepoSpec, fSys fs.FileSystem,
|
||||
referrer *fileLoader, cloner git.Cloner) (ifc.Loader, error) {
|
||||
err := cloner(repoSpec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root, f, err := fSys.CleanedAbs(repoSpec.AbsPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// We don't know that the path requested in repoSpec
|
||||
// is a directory until we actually clone it and look
|
||||
// inside. That just happened, hence the error check
|
||||
// is here.
|
||||
if f != "" {
|
||||
return nil, fmt.Errorf(
|
||||
"'%s' refers to file '%s'; expecting directory",
|
||||
repoSpec.AbsPath(), f)
|
||||
}
|
||||
return &fileLoader{
|
||||
root: root,
|
||||
referrer: referrer,
|
||||
repoSpec: repoSpec,
|
||||
fSys: fSys,
|
||||
cloner: cloner,
|
||||
cleaner: repoSpec.Cleaner(fSys),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *fileLoader) errIfGitContainmentViolation(
|
||||
base fs.ConfirmedDir) error {
|
||||
containingRepo := l.containingRepo()
|
||||
if containingRepo == nil {
|
||||
return nil
|
||||
}
|
||||
if !base.HasPrefix(containingRepo.CloneDir()) {
|
||||
return fmt.Errorf(
|
||||
"security; bases in kustomizations found in "+
|
||||
"cloned git repos must be within the repo, "+
|
||||
"but base '%s' is outside '%s'",
|
||||
base, containingRepo.CloneDir())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Looks back through referrers for a git repo, returning nil
|
||||
// if none found.
|
||||
func (l *fileLoader) containingRepo() *git.RepoSpec {
|
||||
if l.repoSpec != nil {
|
||||
return l.repoSpec
|
||||
}
|
||||
if l.referrer == nil {
|
||||
return nil
|
||||
}
|
||||
return l.referrer.containingRepo()
|
||||
}
|
||||
|
||||
// errIfArgEqualOrHigher tests whether the argument,
|
||||
// is equal to or above the root of any ancestor.
|
||||
func (l *fileLoader) errIfArgEqualOrHigher(
|
||||
candidateRoot fs.ConfirmedDir) error {
|
||||
if l.root.HasPrefix(candidateRoot) {
|
||||
return fmt.Errorf(
|
||||
"cycle detected: candidate root '%s' contains visited root '%s'",
|
||||
candidateRoot, l.root)
|
||||
}
|
||||
if l.referrer == nil {
|
||||
return nil
|
||||
}
|
||||
return l.referrer.errIfArgEqualOrHigher(candidateRoot)
|
||||
}
|
||||
|
||||
// TODO(monopole): Distinguish branches?
|
||||
// I.e. Allow a distinction between git URI with
|
||||
// path foo and tag bar and a git URI with the same
|
||||
// path but a different tag?
|
||||
func (l *fileLoader) errIfRepoCycle(newRepoSpec *git.RepoSpec) error {
|
||||
// TODO(monopole): Use parsed data instead of Raw().
|
||||
if l.repoSpec != nil &&
|
||||
strings.HasPrefix(l.repoSpec.Raw(), newRepoSpec.Raw()) {
|
||||
return fmt.Errorf(
|
||||
"cycle detected: URI '%s' referenced by previous URI '%s'",
|
||||
newRepoSpec.Raw(), l.repoSpec.Raw())
|
||||
}
|
||||
if l.referrer == nil {
|
||||
return nil
|
||||
}
|
||||
return l.referrer.errIfRepoCycle(newRepoSpec)
|
||||
}
|
||||
|
||||
// Load returns content of file at the given relative path,
|
||||
// else an error. The path must refer to a file in or
|
||||
// below the current root.
|
||||
func (l *fileLoader) Load(path string) ([]byte, error) {
|
||||
if filepath.IsAbs(path) {
|
||||
return nil, l.loadOutOfBounds(path)
|
||||
}
|
||||
d, f, err := l.fSys.CleanedAbs(l.root.Join(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if f == "" {
|
||||
return nil, fmt.Errorf(
|
||||
"'%s' must be a file (got d='%s')", path, d)
|
||||
}
|
||||
if !d.HasPrefix(l.root) {
|
||||
return nil, l.loadOutOfBounds(path)
|
||||
}
|
||||
return l.fSys.ReadFile(d.Join(f))
|
||||
}
|
||||
|
||||
func (l *fileLoader) loadOutOfBounds(path string) error {
|
||||
return fmt.Errorf(
|
||||
"security; file '%s' is not in or below '%s'",
|
||||
path, l.root)
|
||||
}
|
||||
|
||||
// Cleanup runs the cleaner.
|
||||
func (l *fileLoader) Cleanup() error {
|
||||
return l.cleaner()
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package loader has a data loading interface and various implementations.
|
||||
package loader
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/git"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
// NewLoader returns a Loader.
|
||||
func NewLoader(path string, fSys fs.FileSystem) (ifc.Loader, error) {
|
||||
repoSpec, err := git.NewRepoSpecFromUrl(path)
|
||||
if err == nil {
|
||||
return newLoaderAtGitClone(
|
||||
repoSpec, fSys, nil, git.ClonerUsingGitExec)
|
||||
}
|
||||
root, err := demandDirectoryRoot(fSys, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newLoaderAtConfirmedDir(
|
||||
root, fSys, nil, git.ClonerUsingGitExec), nil
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"json6902.go",
|
||||
"strategicmerge.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/patch",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/patch",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/sigs.k8s.io/kustomize/pkg/gvk:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/patch/transformer:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package patch
|
||||
|
||||
import "sigs.k8s.io/kustomize/pkg/gvk"
|
||||
|
||||
// Json6902 represents a json patch for an object
|
||||
// with format documented https://tools.ietf.org/html/rfc6902.
|
||||
type Json6902 struct {
|
||||
// Target refers to a Kubernetes object that the json patch will be
|
||||
// applied to. It must refer to a Kubernetes resource under the
|
||||
// purview of this kustomization. Target should use the
|
||||
// raw name of the object (the name specified in its YAML,
|
||||
// before addition of a namePrefix and a nameSuffix).
|
||||
Target *Target `json:"target" yaml:"target"`
|
||||
|
||||
// relative file path for a json patch file inside a kustomization
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
}
|
||||
|
||||
// Target represents the kubernetes object that the patch is applied to
|
||||
type Target struct {
|
||||
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
Name string `json:"name" yaml:"name"`
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package patch
|
||||
|
||||
// StrategicMerge represents a relative path to a
|
||||
// stategic merge patch with the format
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/strategic-merge-patch.md
|
||||
type StrategicMerge string
|
||||
|
||||
// Append appends a slice of patch paths to a StrategicMerge slice
|
||||
func Append(patches []StrategicMerge, paths ...string) []StrategicMerge {
|
||||
for _, p := range paths {
|
||||
patches = append(patches, StrategicMerge(p))
|
||||
}
|
||||
return patches
|
||||
}
|
||||
|
||||
// Exist determines if a patch path exists in a slice of StrategicMerge
|
||||
func Exist(patches []StrategicMerge, path string) bool {
|
||||
for _, p := range patches {
|
||||
if p == StrategicMerge(path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"factory.go",
|
||||
"patchjson6902json.go",
|
||||
"util.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/gvk:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/patch:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resid:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resmap:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resource:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/resid"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
"github.com/ghodss/yaml"
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/patch"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
)
|
||||
|
||||
// PatchJson6902Factory makes Json6902 transformers
|
||||
type PatchJson6902Factory struct {
|
||||
loader ifc.Loader
|
||||
}
|
||||
|
||||
// NewPatchJson6902Factory returns a new PatchJson6902Factory.
|
||||
func NewPatchJson6902Factory(l ifc.Loader) PatchJson6902Factory {
|
||||
return PatchJson6902Factory{loader: l}
|
||||
}
|
||||
|
||||
// MakePatchJson6902Transformer returns a transformer for applying Json6902 patch
|
||||
func (f PatchJson6902Factory) MakePatchJson6902Transformer(patches []patch.Json6902) (transformers.Transformer, error) {
|
||||
var ts []transformers.Transformer
|
||||
for _, p := range patches {
|
||||
t, err := f.makeOnePatchJson6902Transformer(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t != nil {
|
||||
ts = append(ts, t)
|
||||
}
|
||||
}
|
||||
return transformers.NewMultiTransformerWithConflictCheck(ts), nil
|
||||
}
|
||||
|
||||
func (f PatchJson6902Factory) makeOnePatchJson6902Transformer(p patch.Json6902) (transformers.Transformer, error) {
|
||||
if p.Target == nil {
|
||||
return nil, fmt.Errorf("must specify the target field in patchesJson6902")
|
||||
}
|
||||
if p.Path == "" {
|
||||
return nil, fmt.Errorf("must specify the path for a json patch file")
|
||||
}
|
||||
|
||||
targetId := resid.NewResIdWithPrefixNamespace(
|
||||
gvk.Gvk{
|
||||
Group: p.Target.Group,
|
||||
Version: p.Target.Version,
|
||||
Kind: p.Target.Kind,
|
||||
},
|
||||
p.Target.Name,
|
||||
"",
|
||||
p.Target.Namespace,
|
||||
)
|
||||
|
||||
rawOp, err := f.loader.Load(p.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isJsonFormat(rawOp) {
|
||||
// if it isn't JSON, try to parse it as YAML
|
||||
rawOp, err = yaml.YAMLToJSON(rawOp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
decodedPatch, err := jsonpatch.DecodePatch(rawOp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPatchJson6902JSONTransformer(targetId, decodedPatch)
|
||||
}
|
||||
|
||||
func isJsonFormat(data []byte) bool {
|
||||
return data[0] == '['
|
||||
}
|
61
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/patchjson6902json.go
generated
vendored
Normal file
61
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/patchjson6902json.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformer
|
||||
|
||||
import (
|
||||
"github.com/evanphx/json-patch"
|
||||
"sigs.k8s.io/kustomize/pkg/resid"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
)
|
||||
|
||||
// patchJson6902JSONTransformer applies patches.
|
||||
type patchJson6902JSONTransformer struct {
|
||||
target resid.ResId
|
||||
patch jsonpatch.Patch
|
||||
}
|
||||
|
||||
var _ transformers.Transformer = &patchJson6902JSONTransformer{}
|
||||
|
||||
// newPatchJson6902JSONTransformer constructs a PatchJson6902 transformer.
|
||||
func newPatchJson6902JSONTransformer(t resid.ResId, p jsonpatch.Patch) (transformers.Transformer, error) {
|
||||
if len(p) == 0 {
|
||||
return transformers.NewNoOpTransformer(), nil
|
||||
}
|
||||
return &patchJson6902JSONTransformer{target: t, patch: p}, nil
|
||||
}
|
||||
|
||||
// Transform apply the json patches on top of the base resources.
|
||||
func (t *patchJson6902JSONTransformer) Transform(baseResourceMap resmap.ResMap) error {
|
||||
obj, err := findTargetObj(baseResourceMap, t.target)
|
||||
if obj == nil {
|
||||
return err
|
||||
}
|
||||
rawObj, err := obj.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
modifiedObj, err := t.patch.Apply(rawObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = obj.UnmarshalJSON(modifiedObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/resid"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
)
|
||||
|
||||
func findTargetObj(m resmap.ResMap, targetId resid.ResId) (*resource.Resource, error) {
|
||||
matchedIds := m.FindByGVKN(targetId)
|
||||
if targetId.Namespace() != "" {
|
||||
var ids []resid.ResId
|
||||
for _, id := range matchedIds {
|
||||
if id.Namespace() == targetId.Namespace() {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
matchedIds = ids
|
||||
}
|
||||
|
||||
if len(matchedIds) == 0 {
|
||||
return nil, fmt.Errorf("couldn't find any object to apply the json patch %v", targetId)
|
||||
}
|
||||
if len(matchedIds) > 1 {
|
||||
return nil, fmt.Errorf("found multiple objects that the patch can apply %v", matchedIds)
|
||||
}
|
||||
return m[matchedIds[0]], nil
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["resid.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/resid",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/resid",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/sigs.k8s.io/kustomize/pkg/gvk:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resid
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
)
|
||||
|
||||
// ResId conflates GroupVersionKind with a textual name to uniquely identify a kubernetes resource (object).
|
||||
type ResId struct {
|
||||
// Gvk of the resource.
|
||||
gvKind gvk.Gvk
|
||||
// original name of the resource before transformation.
|
||||
name string
|
||||
// namePrefix of the resource
|
||||
// an untransformed resource has no prefix, fully transformed resource has an arbitrary number of prefixes
|
||||
// concatenated together.
|
||||
prefix string
|
||||
// nameSuffix of the resource
|
||||
// an untransformed resource has no suffix, fully transformed resource has an arbitrary number of suffixes
|
||||
// concatenated together.
|
||||
suffix string
|
||||
// namespace the resource belongs to
|
||||
// an untransformed resource has no namespace, fully transformed resource has the namespace from
|
||||
// the top most overlay
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewResIdWithPrefixSuffixNamespace creates new resource identifier with a prefix, suffix and a namespace
|
||||
func NewResIdWithPrefixSuffixNamespace(k gvk.Gvk, n, p, s, ns string) ResId {
|
||||
return ResId{gvKind: k, name: n, prefix: p, suffix: s, namespace: ns}
|
||||
}
|
||||
|
||||
// NewResIdWithPrefixNamespace creates new resource identifier with a prefix and a namespace
|
||||
func NewResIdWithPrefixNamespace(k gvk.Gvk, n, p, ns string) ResId {
|
||||
return ResId{gvKind: k, name: n, prefix: p, namespace: ns}
|
||||
}
|
||||
|
||||
// NewResIdWithSuffixNamespace creates new resource identifier with a suffix and a namespace
|
||||
func NewResIdWithSuffixNamespace(k gvk.Gvk, n, s, ns string) ResId {
|
||||
return ResId{gvKind: k, name: n, suffix: s, namespace: ns}
|
||||
}
|
||||
|
||||
// NewResIdWithPrefixSuffix creates new resource identifier with a prefix and suffix
|
||||
func NewResIdWithPrefixSuffix(k gvk.Gvk, n, p, s string) ResId {
|
||||
return ResId{gvKind: k, name: n, prefix: p, suffix: s}
|
||||
}
|
||||
|
||||
// NewResId creates new resource identifier
|
||||
func NewResId(k gvk.Gvk, n string) ResId {
|
||||
return ResId{gvKind: k, name: n}
|
||||
}
|
||||
|
||||
// NewResIdKindOnly creates new resource identifier
|
||||
func NewResIdKindOnly(k string, n string) ResId {
|
||||
return ResId{gvKind: gvk.FromKind(k), name: n}
|
||||
}
|
||||
|
||||
const (
|
||||
noNamespace = "~X"
|
||||
noPrefix = "~P"
|
||||
noName = "~N"
|
||||
noSuffix = "~S"
|
||||
separator = "|"
|
||||
)
|
||||
|
||||
// String of ResId based on GVK, name and prefix
|
||||
func (n ResId) String() string {
|
||||
ns := n.namespace
|
||||
if ns == "" {
|
||||
ns = noNamespace
|
||||
}
|
||||
p := n.prefix
|
||||
if p == "" {
|
||||
p = noPrefix
|
||||
}
|
||||
nm := n.name
|
||||
if nm == "" {
|
||||
nm = noName
|
||||
}
|
||||
s := n.suffix
|
||||
if s == "" {
|
||||
s = noSuffix
|
||||
}
|
||||
|
||||
return strings.Join(
|
||||
[]string{n.gvKind.String(), ns, p, nm, s}, separator)
|
||||
}
|
||||
|
||||
// GvknString of ResId based on GVK and name
|
||||
func (n ResId) GvknString() string {
|
||||
return n.gvKind.String() + separator + n.name
|
||||
}
|
||||
|
||||
// GvknEquals return if two ResId have the same Group/Version/Kind and name
|
||||
// The comparison excludes prefix and suffix
|
||||
func (n ResId) GvknEquals(id ResId) bool {
|
||||
return n.gvKind.Equals(id.gvKind) && n.name == id.name
|
||||
}
|
||||
|
||||
// Gvk returns Group/Version/Kind of the resource.
|
||||
func (n ResId) Gvk() gvk.Gvk {
|
||||
return n.gvKind
|
||||
}
|
||||
|
||||
// Name returns resource name.
|
||||
func (n ResId) Name() string {
|
||||
return n.name
|
||||
}
|
||||
|
||||
// Namespace returns resource namespace.
|
||||
func (n ResId) Namespace() string {
|
||||
return n.namespace
|
||||
}
|
||||
|
||||
// CopyWithNewPrefixSuffix make a new copy from current ResId
|
||||
// and append a new prefix and suffix
|
||||
func (n ResId) CopyWithNewPrefixSuffix(p, s string) ResId {
|
||||
result := n
|
||||
if p != "" {
|
||||
result.prefix = n.concatPrefix(p)
|
||||
}
|
||||
if s != "" {
|
||||
result.suffix = n.concatSuffix(s)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// CopyWithNewNamespace make a new copy from current ResId and set a new namespace
|
||||
func (n ResId) CopyWithNewNamespace(ns string) ResId {
|
||||
result := n
|
||||
result.namespace = ns
|
||||
return result
|
||||
}
|
||||
|
||||
// HasSameLeftmostPrefix check if two ResIds have the same
|
||||
// left most prefix.
|
||||
func (n ResId) HasSameLeftmostPrefix(id ResId) bool {
|
||||
prefixes1 := n.prefixList()
|
||||
prefixes2 := id.prefixList()
|
||||
return prefixes1[0] == prefixes2[0]
|
||||
}
|
||||
|
||||
// HasSameRightmostSuffix check if two ResIds have the same
|
||||
// right most suffix.
|
||||
func (n ResId) HasSameRightmostSuffix(id ResId) bool {
|
||||
suffixes1 := n.suffixList()
|
||||
suffixes2 := id.suffixList()
|
||||
return suffixes1[len(suffixes1)-1] == suffixes2[len(suffixes2)-1]
|
||||
}
|
||||
|
||||
func (n ResId) concatPrefix(p string) string {
|
||||
if p == "" {
|
||||
return n.prefix
|
||||
}
|
||||
if n.prefix == "" {
|
||||
return p
|
||||
}
|
||||
return p + ":" + n.prefix
|
||||
}
|
||||
|
||||
func (n ResId) concatSuffix(s string) string {
|
||||
if s == "" {
|
||||
return n.suffix
|
||||
}
|
||||
if n.suffix == "" {
|
||||
return s
|
||||
}
|
||||
return n.suffix + ":" + s
|
||||
}
|
||||
|
||||
func (n ResId) prefixList() []string {
|
||||
return strings.Split(n.prefix, ":")
|
||||
}
|
||||
|
||||
func (n ResId) suffixList() []string {
|
||||
return strings.Split(n.suffix, ":")
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"factory.go",
|
||||
"idslice.go",
|
||||
"resmap.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/resmap",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/resmap",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/internal/error:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resid:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resource:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resmap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
internal "sigs.k8s.io/kustomize/pkg/internal/error"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// Factory makes instances of ResMap.
|
||||
type Factory struct {
|
||||
resF *resource.Factory
|
||||
}
|
||||
|
||||
// NewFactory returns a new resmap.Factory.
|
||||
func NewFactory(rf *resource.Factory) *Factory {
|
||||
return &Factory{resF: rf}
|
||||
}
|
||||
|
||||
// RF returns a resource.Factory.
|
||||
func (rmF *Factory) RF() *resource.Factory {
|
||||
return rmF.resF
|
||||
}
|
||||
|
||||
// FromFiles returns a ResMap given a resource path slice.
|
||||
func (rmF *Factory) FromFiles(
|
||||
loader ifc.Loader, paths []string) (ResMap, error) {
|
||||
var result []ResMap
|
||||
for _, path := range paths {
|
||||
content, err := loader.Load(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Load from path "+path+" failed")
|
||||
}
|
||||
res, err := rmF.newResMapFromBytes(content)
|
||||
if err != nil {
|
||||
return nil, internal.Handler(err, path)
|
||||
}
|
||||
result = append(result, res)
|
||||
}
|
||||
return MergeWithErrorOnIdCollision(result...)
|
||||
}
|
||||
|
||||
// newResMapFromBytes decodes a list of objects in byte array format.
|
||||
func (rmF *Factory) newResMapFromBytes(b []byte) (ResMap, error) {
|
||||
resources, err := rmF.resF.SliceFromBytes(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := ResMap{}
|
||||
for _, res := range resources {
|
||||
id := res.Id()
|
||||
if _, found := result[id]; found {
|
||||
return result, fmt.Errorf("GroupVersionKindName: %#v already exists b the map", id)
|
||||
}
|
||||
result[id] = res
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewResMapFromConfigMapArgs returns a Resource slice given
|
||||
// a configmap metadata slice from kustomization file.
|
||||
func (rmF *Factory) NewResMapFromConfigMapArgs(argList []types.ConfigMapArgs, options *types.GeneratorOptions) (ResMap, error) {
|
||||
var resources []*resource.Resource
|
||||
for _, args := range argList {
|
||||
res, err := rmF.resF.MakeConfigMap(&args, options)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewResMapFromConfigMapArgs")
|
||||
}
|
||||
resources = append(resources, res)
|
||||
}
|
||||
return newResMapFromResourceSlice(resources)
|
||||
}
|
||||
|
||||
// NewResMapFromSecretArgs takes a SecretArgs slice, generates
|
||||
// secrets from each entry, and accumulates them in a ResMap.
|
||||
func (rmF *Factory) NewResMapFromSecretArgs(argsList []types.SecretArgs, options *types.GeneratorOptions) (ResMap, error) {
|
||||
var resources []*resource.Resource
|
||||
for _, args := range argsList {
|
||||
res, err := rmF.resF.MakeSecret(&args, options)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewResMapFromSecretArgs")
|
||||
}
|
||||
resources = append(resources, res)
|
||||
}
|
||||
return newResMapFromResourceSlice(resources)
|
||||
}
|
||||
|
||||
// Set sets the loader for the underlying factory
|
||||
func (rmF *Factory) Set(ldr ifc.Loader) {
|
||||
rmF.resF.Set(ldr)
|
||||
}
|
||||
|
||||
func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) {
|
||||
result := ResMap{}
|
||||
for _, res := range resources {
|
||||
id := res.Id()
|
||||
if _, found := result[id]; found {
|
||||
return nil, fmt.Errorf("duplicated %#v is not allowed", id)
|
||||
}
|
||||
result[id] = res
|
||||
}
|
||||
return result, nil
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resmap
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/resid"
|
||||
)
|
||||
|
||||
// IdSlice implements the sort interface.
|
||||
type IdSlice []resid.ResId
|
||||
|
||||
var _ sort.Interface = IdSlice{}
|
||||
|
||||
func (a IdSlice) Len() int { return len(a) }
|
||||
func (a IdSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a IdSlice) Less(i, j int) bool {
|
||||
if !a[i].Gvk().Equals(a[j].Gvk()) {
|
||||
return a[i].Gvk().IsLessThan(a[j].Gvk())
|
||||
}
|
||||
return a[i].String() < a[j].String()
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package resmap implements a map from ResId to Resource that tracks all resources in a kustomization.
|
||||
package resmap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"sigs.k8s.io/kustomize/pkg/resid"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// ResMap is a map from ResId to Resource.
|
||||
type ResMap map[resid.ResId]*resource.Resource
|
||||
|
||||
// FindByGVKN find the matched ResIds by Group/Version/Kind and Name
|
||||
func (m ResMap) FindByGVKN(inputId resid.ResId) []resid.ResId {
|
||||
var result []resid.ResId
|
||||
for id := range m {
|
||||
if id.GvknEquals(inputId) {
|
||||
result = append(result, id)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// DemandOneMatchForId find the matched resource by Group/Version/Kind and Name
|
||||
func (m ResMap) DemandOneMatchForId(inputId resid.ResId) (*resource.Resource, bool) {
|
||||
result := m.FindByGVKN(inputId)
|
||||
if len(result) == 1 {
|
||||
return m[result[0]], true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// EncodeAsYaml encodes a ResMap to YAML; encoded objects separated by `---`.
|
||||
func (m ResMap) EncodeAsYaml() ([]byte, error) {
|
||||
var ids []resid.ResId
|
||||
for id := range m {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
sort.Sort(IdSlice(ids))
|
||||
|
||||
firstObj := true
|
||||
var b []byte
|
||||
buf := bytes.NewBuffer(b)
|
||||
for _, id := range ids {
|
||||
obj := m[id]
|
||||
out, err := yaml.Marshal(obj.Map())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if firstObj {
|
||||
firstObj = false
|
||||
} else {
|
||||
_, err = buf.WriteString("---\n")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
_, err = buf.Write(out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// ErrorIfNotEqual returns error if maps are not equal.
|
||||
func (m ResMap) ErrorIfNotEqual(m2 ResMap) error {
|
||||
if len(m) != len(m2) {
|
||||
var keySet1 []resid.ResId
|
||||
var keySet2 []resid.ResId
|
||||
for id := range m {
|
||||
keySet1 = append(keySet1, id)
|
||||
}
|
||||
for id := range m2 {
|
||||
keySet2 = append(keySet2, id)
|
||||
}
|
||||
return fmt.Errorf("maps has different number of entries: %#v doesn't equals %#v", keySet1, keySet2)
|
||||
}
|
||||
for id, obj1 := range m {
|
||||
obj2, found := m2[id]
|
||||
if !found {
|
||||
return fmt.Errorf("%#v doesn't exist in %#v", id, m2)
|
||||
}
|
||||
if !reflect.DeepEqual(obj1, obj2) {
|
||||
return fmt.Errorf("%#v doesn't deep equal %#v", obj1, obj2)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy clone the resmap into a new one
|
||||
func (m ResMap) DeepCopy(rf *resource.Factory) ResMap {
|
||||
mcopy := make(ResMap)
|
||||
for id, obj := range m {
|
||||
mcopy[id] = obj.DeepCopy()
|
||||
}
|
||||
return mcopy
|
||||
}
|
||||
|
||||
// FilterBy returns a subset ResMap containing ResIds with
|
||||
// the same namespace and leftmost name prefix and rightmost name
|
||||
// as the inputId. If inputId is a cluster level resource, this
|
||||
// returns the original ResMap.
|
||||
func (m ResMap) FilterBy(inputId resid.ResId) ResMap {
|
||||
if inputId.Gvk().IsClusterKind() {
|
||||
return m
|
||||
}
|
||||
result := ResMap{}
|
||||
for id, res := range m {
|
||||
if id.Gvk().IsClusterKind() || id.Namespace() == inputId.Namespace() &&
|
||||
id.HasSameLeftmostPrefix(inputId) &&
|
||||
id.HasSameRightmostSuffix(inputId) {
|
||||
result[id] = res
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// MergeWithErrorOnIdCollision combines multiple ResMap instances, failing on
|
||||
// key collision and skipping nil maps.
|
||||
// If all of the maps are nil, an empty ResMap is returned.
|
||||
func MergeWithErrorOnIdCollision(maps ...ResMap) (ResMap, error) {
|
||||
result := ResMap{}
|
||||
for _, m := range maps {
|
||||
if m == nil {
|
||||
continue
|
||||
}
|
||||
for id, res := range m {
|
||||
if _, found := result[id]; found {
|
||||
return nil, fmt.Errorf("id '%q' already used", id)
|
||||
}
|
||||
result[id] = res
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// MergeWithOverride combines multiple ResMap instances, allowing and sometimes
|
||||
// demanding certain collisions and skipping nil maps.
|
||||
// A collision would be demanded, say, when a generated ConfigMap has the
|
||||
// "replace" option in its generation instructions, meaning it is supposed
|
||||
// to replace something from the raw resources list.
|
||||
// If all of the maps are nil, an empty ResMap is returned.
|
||||
// When looping over the instances to combine them, if a resource id for
|
||||
// resource X is found to be already in the combined map, then the behavior
|
||||
// field for X must be BehaviorMerge or BehaviorReplace. If X is not in the
|
||||
// map, then it's behavior cannot be merge or replace.
|
||||
func MergeWithOverride(maps ...ResMap) (ResMap, error) {
|
||||
result := maps[0]
|
||||
if result == nil {
|
||||
result = ResMap{}
|
||||
}
|
||||
for _, m := range maps[1:] {
|
||||
if m == nil {
|
||||
continue
|
||||
}
|
||||
for id, r := range m {
|
||||
matchedId := result.FindByGVKN(id)
|
||||
if len(matchedId) == 1 {
|
||||
id = matchedId[0]
|
||||
switch r.Behavior() {
|
||||
case types.BehaviorReplace:
|
||||
r.Replace(result[id])
|
||||
result[id] = r
|
||||
case types.BehaviorMerge:
|
||||
r.Merge(result[id])
|
||||
result[id] = r
|
||||
default:
|
||||
return nil, fmt.Errorf("id %#v exists; must merge or replace", id)
|
||||
}
|
||||
} else if len(matchedId) == 0 {
|
||||
switch r.Behavior() {
|
||||
case types.BehaviorMerge, types.BehaviorReplace:
|
||||
return nil, fmt.Errorf("id %#v does not exist; cannot merge or replace", id)
|
||||
default:
|
||||
result[id] = r
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("merge conflict, found multiple objects %v the Resmap %v can merge into", matchedId, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"factory.go",
|
||||
"resource.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/resource",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/resource",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/internal/error:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/patch:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resid:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
internal "sigs.k8s.io/kustomize/pkg/internal/error"
|
||||
"sigs.k8s.io/kustomize/pkg/patch"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// Factory makes instances of Resource.
|
||||
type Factory struct {
|
||||
kf ifc.KunstructuredFactory
|
||||
}
|
||||
|
||||
// NewFactory makes an instance of Factory.
|
||||
func NewFactory(kf ifc.KunstructuredFactory) *Factory {
|
||||
return &Factory{kf: kf}
|
||||
}
|
||||
|
||||
// FromMap returns a new instance of Resource.
|
||||
func (rf *Factory) FromMap(m map[string]interface{}) *Resource {
|
||||
return &Resource{
|
||||
Kunstructured: rf.kf.FromMap(m),
|
||||
options: types.NewGenArgs(nil, nil),
|
||||
}
|
||||
}
|
||||
|
||||
// FromMapAndOption returns a new instance of Resource with given options.
|
||||
func (rf *Factory) FromMapAndOption(m map[string]interface{}, args *types.GeneratorArgs, option *types.GeneratorOptions) *Resource {
|
||||
return &Resource{
|
||||
Kunstructured: rf.kf.FromMap(m),
|
||||
options: types.NewGenArgs(args, option),
|
||||
}
|
||||
}
|
||||
|
||||
// FromKunstructured returns a new instance of Resource.
|
||||
func (rf *Factory) FromKunstructured(
|
||||
u ifc.Kunstructured) *Resource {
|
||||
if u == nil {
|
||||
log.Fatal("unstruct ifc must not be null")
|
||||
}
|
||||
return &Resource{
|
||||
Kunstructured: u,
|
||||
options: types.NewGenArgs(nil, nil),
|
||||
}
|
||||
}
|
||||
|
||||
// SliceFromPatches returns a slice of resources given a patch path
|
||||
// slice from a kustomization file.
|
||||
func (rf *Factory) SliceFromPatches(
|
||||
ldr ifc.Loader, paths []patch.StrategicMerge) ([]*Resource, error) {
|
||||
var result []*Resource
|
||||
for _, path := range paths {
|
||||
content, err := ldr.Load(string(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := rf.SliceFromBytes(content)
|
||||
if err != nil {
|
||||
return nil, internal.Handler(err, string(path))
|
||||
}
|
||||
result = append(result, res...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SliceFromBytes unmarshalls bytes into a Resource slice.
|
||||
func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) {
|
||||
kunStructs, err := rf.kf.SliceFromBytes(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result []*Resource
|
||||
for len(kunStructs) > 0 {
|
||||
u := kunStructs[0]
|
||||
kunStructs = kunStructs[1:]
|
||||
if u.GetKind() == "List" {
|
||||
items := u.Map()["items"]
|
||||
itemsSlice, ok := items.([]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("items in List is type %T, expected array", items)
|
||||
}
|
||||
for _, item := range itemsSlice {
|
||||
itemJSON, err := json.Marshal(item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
innerU, err := rf.kf.SliceFromBytes(itemJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// append innerU to kunStructs so nested Lists can be handled
|
||||
kunStructs = append(kunStructs, innerU...)
|
||||
}
|
||||
} else {
|
||||
result = append(result, rf.FromKunstructured(u))
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Set sets the loader for the underlying factory
|
||||
func (rf *Factory) Set(ldr ifc.Loader) {
|
||||
rf.kf.Set(ldr)
|
||||
}
|
||||
|
||||
// MakeConfigMap makes an instance of Resource for ConfigMap
|
||||
func (rf *Factory) MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (*Resource, error) {
|
||||
u, err := rf.kf.MakeConfigMap(args, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Resource{Kunstructured: u, options: types.NewGenArgs(&types.GeneratorArgs{Behavior: args.Behavior}, options)}, nil
|
||||
}
|
||||
|
||||
// MakeSecret makes an instance of Resource for Secret
|
||||
func (rf *Factory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*Resource, error) {
|
||||
u, err := rf.kf.MakeSecret(args, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Resource{Kunstructured: u, options: types.NewGenArgs(&types.GeneratorArgs{Behavior: args.Behavior}, options)}, nil
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package resource implements representations of k8s API resources as "unstructured" objects.
|
||||
package resource
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/resid"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// Resource is map representation of a Kubernetes API resource object
|
||||
// paired with a GenerationBehavior.
|
||||
type Resource struct {
|
||||
ifc.Kunstructured
|
||||
options *types.GenArgs
|
||||
}
|
||||
|
||||
// String returns resource as JSON.
|
||||
func (r *Resource) String() string {
|
||||
bs, err := r.MarshalJSON()
|
||||
if err != nil {
|
||||
return "<" + err.Error() + ">"
|
||||
}
|
||||
return strings.TrimSpace(string(bs))
|
||||
}
|
||||
|
||||
// DeepCopy returns a new copy of resource
|
||||
func (r *Resource) DeepCopy() *Resource {
|
||||
return &Resource{
|
||||
Kunstructured: r.Kunstructured.Copy(),
|
||||
options: r.options,
|
||||
}
|
||||
}
|
||||
|
||||
// Behavior returns the behavior for the resource.
|
||||
func (r *Resource) Behavior() types.GenerationBehavior {
|
||||
return r.options.Behavior()
|
||||
}
|
||||
|
||||
// NeedAppendHash checks if the resource need a hash suffix
|
||||
func (r *Resource) NeedHashSuffix() bool {
|
||||
return r.options != nil && r.options.NeedsHashSuffix()
|
||||
}
|
||||
|
||||
// Id returns the ResId for the resource.
|
||||
func (r *Resource) Id() resid.ResId {
|
||||
namespace, _ := r.GetFieldValue("metadata.namespace")
|
||||
return resid.NewResIdWithPrefixNamespace(r.GetGvk(), r.GetName(), "", namespace)
|
||||
}
|
||||
|
||||
// Merge performs merge with other resource.
|
||||
func (r *Resource) Merge(other *Resource) {
|
||||
r.Replace(other)
|
||||
mergeConfigmap(r.Map(), other.Map(), r.Map())
|
||||
}
|
||||
|
||||
// Replace performs replace with other resource.
|
||||
func (r *Resource) Replace(other *Resource) {
|
||||
r.SetLabels(mergeStringMaps(other.GetLabels(), r.GetLabels()))
|
||||
r.SetAnnotations(
|
||||
mergeStringMaps(other.GetAnnotations(), r.GetAnnotations()))
|
||||
r.SetName(other.GetName())
|
||||
r.options = other.options
|
||||
}
|
||||
|
||||
// TODO: Add BinaryData once we sync to new k8s.io/api
|
||||
func mergeConfigmap(
|
||||
mergedTo map[string]interface{},
|
||||
maps ...map[string]interface{}) {
|
||||
mergedMap := map[string]interface{}{}
|
||||
for _, m := range maps {
|
||||
datamap, ok := m["data"].(map[string]interface{})
|
||||
if ok {
|
||||
for key, value := range datamap {
|
||||
mergedMap[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
mergedTo["data"] = mergedMap
|
||||
}
|
||||
|
||||
func mergeStringMaps(maps ...map[string]string) map[string]string {
|
||||
result := map[string]string{}
|
||||
for _, m := range maps {
|
||||
for key, value := range m {
|
||||
result[key] = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"kusttarget.go",
|
||||
"resaccumulator.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/target",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/target",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/constants:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/internal/error:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/patch/transformer:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resid:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resmap:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resource:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers/config:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package target implements state for the set of all resources to customize.
|
||||
package target
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/kustomize/pkg/constants"
|
||||
"sigs.k8s.io/kustomize/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc/transformer"
|
||||
interror "sigs.k8s.io/kustomize/pkg/internal/error"
|
||||
patchtransformer "sigs.k8s.io/kustomize/pkg/patch/transformer"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// KustTarget encapsulates the entirety of a kustomization build.
|
||||
type KustTarget struct {
|
||||
kustomization *types.Kustomization
|
||||
ldr ifc.Loader
|
||||
fSys fs.FileSystem
|
||||
rFactory *resmap.Factory
|
||||
tFactory transformer.Factory
|
||||
}
|
||||
|
||||
// NewKustTarget returns a new instance of KustTarget primed with a Loader.
|
||||
func NewKustTarget(
|
||||
ldr ifc.Loader,
|
||||
fSys fs.FileSystem,
|
||||
rFactory *resmap.Factory,
|
||||
tFactory transformer.Factory) (*KustTarget, error) {
|
||||
content, err := loadKustFile(ldr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content = types.DealWithDeprecatedFields(content)
|
||||
var k types.Kustomization
|
||||
err = unmarshal(content, &k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
errs := k.EnforceFields()
|
||||
if len(errs) > 0 {
|
||||
return nil, fmt.Errorf("Failed to read kustomization file under %s:\n"+strings.Join(errs, "\n"), ldr.Root())
|
||||
}
|
||||
return &KustTarget{
|
||||
kustomization: &k,
|
||||
ldr: ldr,
|
||||
fSys: fSys,
|
||||
rFactory: rFactory,
|
||||
tFactory: tFactory,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func loadKustFile(ldr ifc.Loader) ([]byte, error) {
|
||||
var content []byte
|
||||
match := 0
|
||||
for _, kf := range constants.KustomizationFileNames {
|
||||
c, err := ldr.Load(kf)
|
||||
if err == nil {
|
||||
match += 1
|
||||
content = c
|
||||
}
|
||||
}
|
||||
switch match {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("No kustomization file found in %s. Kustomize supports the following kustomization files: %s",
|
||||
ldr.Root(), strings.Join(constants.KustomizationFileNames, ", "))
|
||||
case 1:
|
||||
return content, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Found multiple kustomization files under: %s\n", ldr.Root())
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshal(y []byte, o interface{}) error {
|
||||
j, err := yaml.YAMLToJSON(y)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dec := json.NewDecoder(bytes.NewReader(j))
|
||||
dec.DisallowUnknownFields()
|
||||
return dec.Decode(o)
|
||||
}
|
||||
|
||||
// MakeCustomizedResMap creates a ResMap per kustomization instructions.
|
||||
// The Resources in the returned ResMap are fully customized.
|
||||
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
|
||||
ra, err := kt.accumulateTarget()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = ra.Transform(kt.tFactory.MakeHashTransformer())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Given that names have changed (prefixs/suffixes added),
|
||||
// fix all the back references to those names.
|
||||
err = ra.FixBackReferences()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// With all the back references fixed, it's OK to resolve Vars.
|
||||
err = ra.ResolveVars()
|
||||
return ra.ResMap(), err
|
||||
}
|
||||
|
||||
func (kt *KustTarget) shouldAddHashSuffixesToGeneratedResources() bool {
|
||||
return kt.kustomization.GeneratorOptions == nil ||
|
||||
!kt.kustomization.GeneratorOptions.DisableNameSuffixHash
|
||||
}
|
||||
|
||||
// accumulateTarget returns a new ResAccumulator,
|
||||
// holding customized resources and the data/rules used
|
||||
// to do so. The name back references and vars are
|
||||
// not yet fixed.
|
||||
func (kt *KustTarget) accumulateTarget() (
|
||||
ra *ResAccumulator, err error) {
|
||||
// TODO(monopole): Get rid of the KustomizationErrors accumulator.
|
||||
// It's not consistently used, and complicates tests.
|
||||
errs := &interror.KustomizationErrors{}
|
||||
ra, errs = kt.accumulateBases()
|
||||
resources, err := kt.rFactory.FromFiles(
|
||||
kt.ldr, kt.kustomization.Resources)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "rawResources failed to read Resources"))
|
||||
}
|
||||
if len(errs.Get()) > 0 {
|
||||
return ra, errs
|
||||
}
|
||||
err = ra.MergeResourcesWithErrorOnIdCollision(resources)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "MergeResourcesWithErrorOnIdCollision"))
|
||||
}
|
||||
tConfig, err := config.MakeTransformerConfig(
|
||||
kt.ldr, kt.kustomization.Configurations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = ra.MergeConfig(tConfig)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "MergeConfig"))
|
||||
}
|
||||
err = ra.MergeVars(kt.kustomization.Vars)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "MergeVars"))
|
||||
}
|
||||
crdTc, err := config.LoadConfigFromCRDs(kt.ldr, kt.kustomization.Crds)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "LoadCRDs"))
|
||||
}
|
||||
err = ra.MergeConfig(crdTc)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "merge CRDs"))
|
||||
}
|
||||
resMap, err := kt.generateConfigMapsAndSecrets(errs)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "generateConfigMapsAndSecrets"))
|
||||
}
|
||||
err = ra.MergeResourcesWithOverride(resMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patches, err := kt.rFactory.RF().SliceFromPatches(
|
||||
kt.ldr, kt.kustomization.PatchesStrategicMerge)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "SliceFromPatches"))
|
||||
}
|
||||
if len(errs.Get()) > 0 {
|
||||
return nil, errs
|
||||
}
|
||||
t, err := kt.newTransformer(patches, ra.tConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = ra.Transform(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ra, nil
|
||||
}
|
||||
|
||||
func (kt *KustTarget) generateConfigMapsAndSecrets(
|
||||
errs *interror.KustomizationErrors) (resmap.ResMap, error) {
|
||||
kt.rFactory.Set(kt.ldr)
|
||||
cms, err := kt.rFactory.NewResMapFromConfigMapArgs(
|
||||
kt.kustomization.ConfigMapGenerator, kt.kustomization.GeneratorOptions)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "NewResMapFromConfigMapArgs"))
|
||||
}
|
||||
secrets, err := kt.rFactory.NewResMapFromSecretArgs(
|
||||
kt.kustomization.SecretGenerator, kt.kustomization.GeneratorOptions)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "NewResMapFromSecretArgs"))
|
||||
}
|
||||
return resmap.MergeWithErrorOnIdCollision(cms, secrets)
|
||||
}
|
||||
|
||||
// accumulateBases returns a new ResAccumulator
|
||||
// holding customized resources and the data/rules
|
||||
// used to customized them from only the _bases_
|
||||
// of this KustTarget.
|
||||
func (kt *KustTarget) accumulateBases() (
|
||||
ra *ResAccumulator, errs *interror.KustomizationErrors) {
|
||||
errs = &interror.KustomizationErrors{}
|
||||
ra = MakeEmptyAccumulator()
|
||||
|
||||
for _, path := range kt.kustomization.Bases {
|
||||
ldr, err := kt.ldr.New(path)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "couldn't make loader for "+path))
|
||||
continue
|
||||
}
|
||||
subKt, err := NewKustTarget(
|
||||
ldr, kt.fSys, kt.rFactory, kt.tFactory)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "couldn't make target for "+path))
|
||||
ldr.Cleanup()
|
||||
continue
|
||||
}
|
||||
subRa, err := subKt.accumulateTarget()
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "accumulateTarget"))
|
||||
ldr.Cleanup()
|
||||
continue
|
||||
}
|
||||
err = ra.MergeAccumulator(subRa)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, path))
|
||||
}
|
||||
ldr.Cleanup()
|
||||
}
|
||||
return ra, errs
|
||||
}
|
||||
|
||||
// newTransformer makes a Transformer that does a collection
|
||||
// of object transformations.
|
||||
func (kt *KustTarget) newTransformer(
|
||||
patches []*resource.Resource, tConfig *config.TransformerConfig) (
|
||||
transformers.Transformer, error) {
|
||||
var r []transformers.Transformer
|
||||
t, err := kt.tFactory.MakePatchTransformer(patches, kt.rFactory.RF())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r = append(r, t)
|
||||
r = append(r, transformers.NewNamespaceTransformer(
|
||||
string(kt.kustomization.Namespace), tConfig.NameSpace))
|
||||
t, err = transformers.NewNamePrefixSuffixTransformer(
|
||||
string(kt.kustomization.NamePrefix),
|
||||
string(kt.kustomization.NameSuffix),
|
||||
tConfig.NamePrefix,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r = append(r, t)
|
||||
t, err = transformers.NewLabelsMapTransformer(
|
||||
kt.kustomization.CommonLabels, tConfig.CommonLabels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r = append(r, t)
|
||||
t, err = transformers.NewAnnotationsMapTransformer(
|
||||
kt.kustomization.CommonAnnotations, tConfig.CommonAnnotations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r = append(r, t)
|
||||
t, err = patchtransformer.NewPatchJson6902Factory(kt.ldr).
|
||||
MakePatchJson6902Transformer(kt.kustomization.PatchesJson6902)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r = append(r, t)
|
||||
t, err = transformers.NewImageTransformer(kt.kustomization.Images)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r = append(r, t)
|
||||
return transformers.NewMultiTransformer(r), nil
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package target
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sigs.k8s.io/kustomize/pkg/resid"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
)
|
||||
|
||||
// ResAccumulator accumulates resources and the rules
|
||||
// used to customize those resources.
|
||||
// TODO(monopole): Move to "accumulator" package and make members private.
|
||||
// This will make a better separation between KustTarget, which should
|
||||
// be mainly concerned with data loading, and this class, which could
|
||||
// become the home of all transformation data and logic.
|
||||
type ResAccumulator struct {
|
||||
resMap resmap.ResMap
|
||||
tConfig *config.TransformerConfig
|
||||
varSet types.VarSet
|
||||
}
|
||||
|
||||
func MakeEmptyAccumulator() *ResAccumulator {
|
||||
ra := &ResAccumulator{}
|
||||
ra.resMap = make(resmap.ResMap)
|
||||
ra.tConfig = &config.TransformerConfig{}
|
||||
ra.varSet = types.VarSet{}
|
||||
return ra
|
||||
}
|
||||
|
||||
// ResMap returns a copy of the internal resMap.
|
||||
func (ra *ResAccumulator) ResMap() resmap.ResMap {
|
||||
result := make(resmap.ResMap)
|
||||
for k, v := range ra.resMap {
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) MergeResourcesWithErrorOnIdCollision(
|
||||
resources resmap.ResMap) (err error) {
|
||||
ra.resMap, err = resmap.MergeWithErrorOnIdCollision(
|
||||
resources, ra.resMap)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) MergeResourcesWithOverride(
|
||||
resources resmap.ResMap) (err error) {
|
||||
ra.resMap, err = resmap.MergeWithOverride(
|
||||
ra.resMap, resources)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) MergeConfig(
|
||||
tConfig *config.TransformerConfig) (err error) {
|
||||
ra.tConfig, err = ra.tConfig.Merge(tConfig)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) MergeVars(incoming []types.Var) error {
|
||||
return ra.varSet.MergeSlice(incoming)
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) MergeAccumulator(other *ResAccumulator) (err error) {
|
||||
err = ra.MergeResourcesWithErrorOnIdCollision(other.resMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ra.MergeConfig(other.tConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ra.varSet.MergeSet(&other.varSet)
|
||||
}
|
||||
|
||||
// makeVarReplacementMap returns a map of Var names to
|
||||
// their final values. The values are strings intended
|
||||
// for substitution wherever the $(var.Name) occurs.
|
||||
func (ra *ResAccumulator) makeVarReplacementMap() (map[string]string, error) {
|
||||
result := map[string]string{}
|
||||
for _, v := range ra.varSet.Set() {
|
||||
id := resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name)
|
||||
if r, found := ra.resMap.DemandOneMatchForId(id); found {
|
||||
s, err := r.GetFieldValue(v.FieldRef.FieldPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("field path err for var: %+v", v)
|
||||
}
|
||||
result[v.Name] = s
|
||||
} else {
|
||||
// Should this be an error?
|
||||
log.Printf("var %v defined but not used", v)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) Transform(t transformers.Transformer) error {
|
||||
return t.Transform(ra.resMap)
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) ResolveVars() error {
|
||||
replacementMap, err := ra.makeVarReplacementMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ra.Transform(transformers.NewRefVarTransformer(
|
||||
replacementMap, ra.tConfig.VarReference))
|
||||
}
|
||||
|
||||
func (ra *ResAccumulator) FixBackReferences() (err error) {
|
||||
if ra.tConfig.NameReference == nil {
|
||||
return nil
|
||||
}
|
||||
return ra.Transform(transformers.NewNameReferenceTransformer(
|
||||
ra.tConfig.NameReference))
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"image.go",
|
||||
"labelsandannotations.go",
|
||||
"multitransformer.go",
|
||||
"mutatefield.go",
|
||||
"namereference.go",
|
||||
"namespace.go",
|
||||
"nooptransformer.go",
|
||||
"prefixsuffixname.go",
|
||||
"refvars.go",
|
||||
"transformer.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/transformers",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/transformers",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/expansion:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/gvk:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/image:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resmap:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/resource:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers/config:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers/config:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,40 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"factory.go",
|
||||
"factorycrd.go",
|
||||
"fieldspec.go",
|
||||
"namebackreferences.go",
|
||||
"transformerconfig.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/common:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/gvk:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/ifc:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
31
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/BUILD
generated
vendored
Normal file
31
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/BUILD
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"commonannotations.go",
|
||||
"commonlabels.go",
|
||||
"defaultconfig.go",
|
||||
"nameprefix.go",
|
||||
"namereference.go",
|
||||
"namespace.go",
|
||||
"varreference.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
60
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/commonannotations.go
generated
vendored
Normal file
60
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/commonannotations.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const commonAnnotationFieldSpecs = `
|
||||
commonAnnotations:
|
||||
- path: metadata/annotations
|
||||
create: true
|
||||
|
||||
- path: spec/template/metadata/annotations
|
||||
create: true
|
||||
version: v1
|
||||
kind: ReplicationController
|
||||
|
||||
- path: spec/template/metadata/annotations
|
||||
create: true
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/metadata/annotations
|
||||
create: true
|
||||
kind: ReplicaSet
|
||||
|
||||
- path: spec/template/metadata/annotations
|
||||
create: true
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/metadata/annotations
|
||||
create: true
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/metadata/annotations
|
||||
create: true
|
||||
group: batch
|
||||
kind: Job
|
||||
|
||||
- path: spec/jobTemplate/metadata/annotations
|
||||
create: true
|
||||
group: batch
|
||||
kind: CronJob
|
||||
|
||||
- path: spec/jobTemplate/spec/template/metadata/annotations
|
||||
create: true
|
||||
group: batch
|
||||
kind: CronJob
|
||||
|
||||
`
|
162
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/commonlabels.go
generated
vendored
Normal file
162
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/commonlabels.go
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const commonLabelFieldSpecs = `
|
||||
commonLabels:
|
||||
- path: metadata/labels
|
||||
create: true
|
||||
|
||||
- path: spec/selector
|
||||
create: true
|
||||
version: v1
|
||||
kind: Service
|
||||
|
||||
- path: spec/selector
|
||||
create: true
|
||||
version: v1
|
||||
kind: ReplicationController
|
||||
|
||||
- path: spec/template/metadata/labels
|
||||
create: true
|
||||
version: v1
|
||||
kind: ReplicationController
|
||||
|
||||
- path: spec/selector/matchLabels
|
||||
create: true
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/metadata/labels
|
||||
create: true
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/affinity/podAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/affinity/podAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/affinity/podAntiAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/affinity/podAntiAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/selector/matchLabels
|
||||
create: true
|
||||
kind: ReplicaSet
|
||||
|
||||
- path: spec/template/metadata/labels
|
||||
create: true
|
||||
kind: ReplicaSet
|
||||
|
||||
- path: spec/selector/matchLabels
|
||||
create: true
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/metadata/labels
|
||||
create: true
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/selector/matchLabels
|
||||
create: true
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/metadata/labels
|
||||
create: true
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/affinity/podAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/affinity/podAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/affinity/podAntiAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/affinity/podAntiAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
|
||||
create: false
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/volumeClaimTemplates/metadata/labels
|
||||
create: true
|
||||
group: apps
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/selector/matchLabels
|
||||
create: false
|
||||
group: batch
|
||||
kind: Job
|
||||
|
||||
- path: spec/template/metadata/labels
|
||||
create: true
|
||||
group: batch
|
||||
kind: Job
|
||||
|
||||
- path: spec/jobTemplate/spec/selector/matchLabels
|
||||
create: false
|
||||
group: batch
|
||||
kind: CronJob
|
||||
|
||||
- path: spec/jobTemplate/metadata/labels
|
||||
create: true
|
||||
group: batch
|
||||
kind: CronJob
|
||||
|
||||
- path: spec/jobTemplate/spec/template/metadata/labels
|
||||
create: true
|
||||
group: batch
|
||||
kind: CronJob
|
||||
|
||||
- path: spec/selector/matchLabels
|
||||
create: false
|
||||
group: policy
|
||||
kind: PodDisruptionBudget
|
||||
|
||||
- path: spec/podSelector/matchLabels
|
||||
create: false
|
||||
group: networking.k8s.io
|
||||
kind: NetworkPolicy
|
||||
|
||||
- path: spec/ingress/from/podSelector/matchLabels
|
||||
create: false
|
||||
group: networking.k8s.io
|
||||
kind: NetworkPolicy
|
||||
|
||||
- path: spec/egress/to/podSelector/matchLabels
|
||||
create: false
|
||||
group: networking.k8s.io
|
||||
kind: NetworkPolicy
|
||||
`
|
49
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/defaultconfig.go
generated
vendored
Normal file
49
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/defaultconfig.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package defaultconfig provides the default
|
||||
// transformer configurations
|
||||
package defaultconfig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// GetDefaultFieldSpecs returns default fieldSpecs.
|
||||
func GetDefaultFieldSpecs() []byte {
|
||||
configData := [][]byte{
|
||||
[]byte(namePrefixFieldSpecs),
|
||||
[]byte(commonLabelFieldSpecs),
|
||||
[]byte(commonAnnotationFieldSpecs),
|
||||
[]byte(namespaceFieldSpecs),
|
||||
[]byte(varReferenceFieldSpecs),
|
||||
[]byte(nameReferenceFieldSpecs),
|
||||
}
|
||||
return bytes.Join(configData, []byte("\n"))
|
||||
}
|
||||
|
||||
// GetDefaultFieldSpecsAsMap returns default fieldSpecs
|
||||
// as a string->string map.
|
||||
func GetDefaultFieldSpecsAsMap() map[string]string {
|
||||
result := make(map[string]string)
|
||||
result["nameprefix"] = namePrefixFieldSpecs
|
||||
result["commonlabels"] = commonLabelFieldSpecs
|
||||
result["commonannotations"] = commonAnnotationFieldSpecs
|
||||
result["namespace"] = namespaceFieldSpecs
|
||||
result["varreference"] = varReferenceFieldSpecs
|
||||
result["namereference"] = nameReferenceFieldSpecs
|
||||
return result
|
||||
}
|
24
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/nameprefix.go
generated
vendored
Normal file
24
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/nameprefix.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
namePrefixFieldSpecs = `
|
||||
namePrefix:
|
||||
- path: metadata/name
|
||||
`
|
||||
)
|
317
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/namereference.go
generated
vendored
Normal file
317
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/namereference.go
generated
vendored
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
nameReferenceFieldSpecs = `
|
||||
nameReference:
|
||||
- kind: Deployment
|
||||
fieldSpecs:
|
||||
- path: spec/scaleTargetRef/name
|
||||
kind: HorizontalPodAutoscaler
|
||||
|
||||
- kind: ReplicationController
|
||||
fieldSpecs:
|
||||
- path: spec/scaleTargetRef/name
|
||||
kind: HorizontalPodAutoscaler
|
||||
|
||||
- kind: ReplicaSet
|
||||
fieldSpecs:
|
||||
- path: spec/scaleTargetRef/name
|
||||
kind: HorizontalPodAutoscaler
|
||||
|
||||
- kind: ConfigMap
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/configMap/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/containers/envFrom/configMapRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/initContainers/envFrom/configMapRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/template/spec/volumes/configMap/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/containers/envFrom/configMapRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/volumes/projected/sources/configMap/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/volumes/configMap/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/containers/envFrom/configMapRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/volumes/configMap/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/containers/envFrom/configMapRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/volumes/configMap/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/containers/envFrom/configMapRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/volumes/projected/sources/configMap/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/volumes/configMap/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/containers/envFrom/configMapRef/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
|
||||
kind: Job
|
||||
- path: spec/jobTemplate/spec/template/spec/volumes/configMap/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/containers/envFrom/configMapRef/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/initContainers/envFrom/configmapRef/name
|
||||
kind: CronJob
|
||||
|
||||
- kind: Secret
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/secret/secretName
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/containers/env/valueFrom/secretKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/containers/envFrom/secretRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/initContainers/envFrom/secretRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/imagePullSecrets/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/template/spec/volumes/secret/secretName
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/containers/envFrom/secretRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/initContainers/envFrom/secretRef/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/imagePullSecrets/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/volumes/projected/sources/secret/name
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/volumes/secret/secretName
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/containers/envFrom/secretRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/initContainers/envFrom/secretRef/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/imagePullSecrets/name
|
||||
kind: ReplicaSet
|
||||
- path: spec/template/spec/volumes/secret/secretName
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/containers/envFrom/secretRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/initContainers/envFrom/secretRef/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/imagePullSecrets/name
|
||||
kind: DaemonSet
|
||||
- path: spec/template/spec/volumes/secret/secretName
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/containers/envFrom/secretRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/initContainers/envFrom/secretRef/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/imagePullSecrets/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/volumes/projected/sources/secret/name
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/volumes/secret/secretName
|
||||
kind: Job
|
||||
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/containers/envFrom/secretRef/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/initContainers/envFrom/secretRef/name
|
||||
kind: Job
|
||||
- path: spec/template/spec/imagePullSecrets/name
|
||||
kind: Job
|
||||
- path: spec/jobTemplate/spec/template/spec/volumes/secret/secretName
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/containers/envFrom/secretRef/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/initContainers/envFrom/secretRef/name
|
||||
kind: CronJob
|
||||
- path: spec/jobTemplate/spec/template/spec/imagePullSecrets/name
|
||||
kind: CronJob
|
||||
- path: spec/tls/secretName
|
||||
kind: Ingress
|
||||
- path: metadata/annotations/ingress.kubernetes.io\/auth-secret
|
||||
kind: Ingress
|
||||
- path: metadata/annotations/nginx.ingress.kubernetes.io\/auth-secret
|
||||
kind: Ingress
|
||||
- path: imagePullSecrets/name
|
||||
kind: ServiceAccount
|
||||
- path: parameters/secretName
|
||||
kind: StorageClass
|
||||
- path: parameters/adminSecretName
|
||||
kind: StorageClass
|
||||
- path: parameters/userSecretName
|
||||
kind: StorageClass
|
||||
- path: parameters/secretRef
|
||||
kind: StorageClass
|
||||
- path: rules/resourceNames
|
||||
kind: Role
|
||||
- path: rules/resourceNames
|
||||
kind: ClusterRole
|
||||
|
||||
- kind: Service
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: spec/serviceName
|
||||
kind: StatefulSet
|
||||
group: apps
|
||||
- path: spec/rules/http/paths/backend/serviceName
|
||||
kind: Ingress
|
||||
- path: spec/backend/serviceName
|
||||
kind: Ingress
|
||||
- path: spec/service/name
|
||||
kind: APIService
|
||||
group: apiregistration.k8s.io
|
||||
|
||||
- kind: Role
|
||||
group: rbac.authorization.k8s.io
|
||||
fieldSpecs:
|
||||
- path: roleRef/name
|
||||
kind: RoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
|
||||
- kind: ClusterRole
|
||||
group: rbac.authorization.k8s.io
|
||||
fieldSpecs:
|
||||
- path: roleRef/name
|
||||
kind: RoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
- path: roleRef/name
|
||||
kind: ClusterRoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
|
||||
- kind: ServiceAccount
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: subjects/name
|
||||
kind: RoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
- path: subjects/name
|
||||
kind: ClusterRoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
- path: spec/serviceAccountName
|
||||
kind: Pod
|
||||
- path: spec/template/spec/serviceAccountName
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/serviceAccountName
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/serviceAccountName
|
||||
kind: ReplicationController
|
||||
- path: spec/jobTemplate/spec/template/spec/serviceAccountName
|
||||
kind: CronJob
|
||||
- path: spec/template/spec/serviceAccountName
|
||||
kind: job
|
||||
- path: spec/template/spec/serviceAccountName
|
||||
kind: DaemonSet
|
||||
|
||||
- kind: PersistentVolumeClaim
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: Pod
|
||||
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: StatefulSet
|
||||
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: Deployment
|
||||
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: ReplicationController
|
||||
- path: spec/jobTemplate/spec/template/spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: CronJob
|
||||
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: Job
|
||||
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: DaemonSet
|
||||
|
||||
- kind: PersistentVolume
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: spec/volumeName
|
||||
kind: PersistentVolumeClaim
|
||||
`
|
||||
)
|
25
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/namespace.go
generated
vendored
Normal file
25
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/namespace.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
namespaceFieldSpecs = `
|
||||
namespace:
|
||||
- path: metadata/namespace
|
||||
create: true
|
||||
`
|
||||
)
|
109
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/varreference.go
generated
vendored
Normal file
109
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/varreference.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
varReferenceFieldSpecs = `
|
||||
varReference:
|
||||
- path: spec/template/spec/initContainers/command
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/containers/command
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/initContainers/command
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/containers/command
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/initContainers/command
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/spec/containers/command
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/spec/containers/command
|
||||
kind: Job
|
||||
|
||||
- path: spec/jobTemplate/spec/template/spec/containers/command
|
||||
kind: CronJob
|
||||
|
||||
- path: spec/template/spec/initContainers/args
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/containers/args
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/initContainers/args
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/containers/args
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/initContainers/args
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/spec/containers/args
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/spec/containers/args
|
||||
kind: Job
|
||||
|
||||
- path: spec/jobTemplate/spec/template/spec/containers/args
|
||||
kind: CronJob
|
||||
|
||||
- path: spec/template/spec/initContainers/env/value
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/containers/env/value
|
||||
kind: StatefulSet
|
||||
|
||||
- path: spec/template/spec/initContainers/env/value
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/containers/env/value
|
||||
kind: Deployment
|
||||
|
||||
- path: spec/template/spec/initContainers/env/value
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/spec/containers/env/value
|
||||
kind: DaemonSet
|
||||
|
||||
- path: spec/template/spec/containers/env/value
|
||||
kind: Job
|
||||
|
||||
- path: spec/jobTemplate/spec/template/spec/containers/env/value
|
||||
kind: CronJob
|
||||
|
||||
- path: spec/containers/command
|
||||
kind: Pod
|
||||
|
||||
- path: spec/containers/args
|
||||
kind: Pod
|
||||
|
||||
- path: spec/containers/env/value
|
||||
kind: Pod
|
||||
|
||||
- path: spec/rules/host
|
||||
kind: Ingress
|
||||
|
||||
- path: spec/tls/hosts
|
||||
kind: Ingress
|
||||
`
|
||||
)
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
// Factory makes instances of TransformerConfig.
|
||||
type Factory struct {
|
||||
ldr ifc.Loader
|
||||
}
|
||||
|
||||
// MakeTransformerConfig returns a merger of custom config,
|
||||
// if any, with default config.
|
||||
func MakeTransformerConfig(
|
||||
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
|
||||
t1 := MakeDefaultConfig()
|
||||
if len(paths) == 0 {
|
||||
return t1, nil
|
||||
}
|
||||
t2, err := NewFactory(ldr).FromFiles(paths)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return t1.Merge(t2)
|
||||
}
|
||||
|
||||
func NewFactory(l ifc.Loader) *Factory {
|
||||
return &Factory{ldr: l}
|
||||
}
|
||||
|
||||
func (tf *Factory) loader() ifc.Loader {
|
||||
if tf.ldr.(ifc.Loader) == nil {
|
||||
log.Fatal("no loader")
|
||||
}
|
||||
return tf.ldr
|
||||
}
|
||||
|
||||
// FromFiles returns a TranformerConfig object from a list of files
|
||||
func (tf *Factory) FromFiles(
|
||||
paths []string) (*TransformerConfig, error) {
|
||||
result := &TransformerConfig{}
|
||||
for _, path := range paths {
|
||||
data, err := tf.loader().Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := makeTransformerConfigFromBytes(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err = result.Merge(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// makeTransformerConfigFromBytes returns a TransformerConfig object from bytes
|
||||
func makeTransformerConfigFromBytes(data []byte) (*TransformerConfig, error) {
|
||||
var t TransformerConfig
|
||||
err := yaml.Unmarshal(data, &t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.sortFields()
|
||||
return &t, nil
|
||||
}
|
200
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/factorycrd.go
generated
vendored
Normal file
200
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/factorycrd.go
generated
vendored
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/go-openapi/spec"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
)
|
||||
|
||||
type myProperties map[string]spec.Schema
|
||||
type nameToApiMap map[string]common.OpenAPIDefinition
|
||||
|
||||
// LoadConfigFromCRDs parse CRD schemas from paths into a TransformerConfig
|
||||
func LoadConfigFromCRDs(
|
||||
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
|
||||
tc := MakeEmptyConfig()
|
||||
for _, path := range paths {
|
||||
content, err := ldr.Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, err := makeNameToApiMap(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
otherTc, err := makeConfigFromApiMap(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tc, err = tc.Merge(otherTc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return tc, nil
|
||||
}
|
||||
|
||||
func makeNameToApiMap(content []byte) (result nameToApiMap, err error) {
|
||||
if content[0] == '{' {
|
||||
err = json.Unmarshal(content, &result)
|
||||
} else {
|
||||
err = yaml.Unmarshal(content, &result)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func makeConfigFromApiMap(m nameToApiMap) (*TransformerConfig, error) {
|
||||
result := MakeEmptyConfig()
|
||||
for name, api := range m {
|
||||
if !looksLikeAk8sType(api.Schema.SchemaProps.Properties) {
|
||||
continue
|
||||
}
|
||||
tc := MakeEmptyConfig()
|
||||
err := loadCrdIntoConfig(
|
||||
tc, makeGvkFromTypeName(name), m, name, []string{})
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result, err = result.Merge(tc)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// TODO: Get Group and Version for CRD from the
|
||||
// openAPI definition once
|
||||
// "x-kubernetes-group-version-kind" is available in CRD
|
||||
func makeGvkFromTypeName(n string) gvk.Gvk {
|
||||
names := strings.Split(n, ".")
|
||||
kind := names[len(names)-1]
|
||||
return gvk.Gvk{Kind: kind}
|
||||
}
|
||||
|
||||
func looksLikeAk8sType(properties myProperties) bool {
|
||||
_, ok := properties["kind"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_, ok = properties["apiVersion"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_, ok = properties["metadata"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
// "x-kubernetes-annotation": ""
|
||||
xAnnotation = "x-kubernetes-annotation"
|
||||
|
||||
// "x-kubernetes-label-selector": ""
|
||||
xLabelSelector = "x-kubernetes-label-selector"
|
||||
|
||||
// "x-kubernetes-identity": ""
|
||||
xIdentity = "x-kubernetes-identity"
|
||||
|
||||
// "x-kubernetes-object-ref-api-version": <apiVersion name>
|
||||
xVersion = "x-kubernetes-object-ref-api-version"
|
||||
|
||||
// "x-kubernetes-object-ref-kind": <kind name>
|
||||
xKind = "x-kubernetes-object-ref-kind"
|
||||
|
||||
// "x-kubernetes-object-ref-name-key": "name"
|
||||
// default is "name"
|
||||
xNameKey = "x-kubernetes-object-ref-name-key"
|
||||
)
|
||||
|
||||
// loadCrdIntoConfig loads a CRD spec into a TransformerConfig
|
||||
func loadCrdIntoConfig(
|
||||
theConfig *TransformerConfig, theGvk gvk.Gvk, theMap nameToApiMap,
|
||||
typeName string, path []string) (err error) {
|
||||
api, ok := theMap[typeName]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
for propName, property := range api.Schema.SchemaProps.Properties {
|
||||
_, annotate := property.Extensions.GetString(xAnnotation)
|
||||
if annotate {
|
||||
err = theConfig.AddAnnotationFieldSpec(
|
||||
makeFs(theGvk, append(path, propName)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
_, label := property.Extensions.GetString(xLabelSelector)
|
||||
if label {
|
||||
err = theConfig.AddLabelFieldSpec(
|
||||
makeFs(theGvk, append(path, propName)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
_, identity := property.Extensions.GetString(xIdentity)
|
||||
if identity {
|
||||
err = theConfig.AddPrefixFieldSpec(
|
||||
makeFs(theGvk, append(path, propName)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
version, ok := property.Extensions.GetString(xVersion)
|
||||
if ok {
|
||||
kind, ok := property.Extensions.GetString(xKind)
|
||||
if ok {
|
||||
nameKey, ok := property.Extensions.GetString(xNameKey)
|
||||
if !ok {
|
||||
nameKey = "name"
|
||||
}
|
||||
err = theConfig.AddNamereferenceFieldSpec(
|
||||
NameBackReferences{
|
||||
Gvk: gvk.Gvk{Kind: kind, Version: version},
|
||||
FieldSpecs: []FieldSpec{
|
||||
makeFs(theGvk, append(path, propName, nameKey))},
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if property.Ref.GetURL() != nil {
|
||||
loadCrdIntoConfig(
|
||||
theConfig, theGvk, theMap,
|
||||
property.Ref.String(), append(path, propName))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeFs(in gvk.Gvk, path []string) FieldSpec {
|
||||
return FieldSpec{
|
||||
CreateIfNotPresent: false,
|
||||
Gvk: in,
|
||||
Path: strings.Join(path, "/"),
|
||||
}
|
||||
}
|
139
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/fieldspec.go
generated
vendored
Normal file
139
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/fieldspec.go
generated
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
)
|
||||
|
||||
// FieldSpec completely specifies a kustomizable field in
|
||||
// an unstructured representation of a k8s API object.
|
||||
// It helps define the operands of transformations.
|
||||
//
|
||||
// For example, a directive to add a common label to objects
|
||||
// will need to know that a 'Deployment' object (in API group
|
||||
// 'apps', any version) can have labels at field path
|
||||
// 'spec/template/metadata/labels', and further that it is OK
|
||||
// (or not OK) to add that field path to the object if the
|
||||
// field path doesn't exist already.
|
||||
//
|
||||
// This would look like
|
||||
// {
|
||||
// group: apps
|
||||
// kind: Deployment
|
||||
// path: spec/template/metadata/labels
|
||||
// create: true
|
||||
// }
|
||||
type FieldSpec struct {
|
||||
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
CreateIfNotPresent bool `json:"create,omitempty" yaml:"create,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
escapedForwardSlash = "\\/"
|
||||
tempSlashReplacement = "???"
|
||||
)
|
||||
|
||||
func (fs FieldSpec) String() string {
|
||||
return fmt.Sprintf(
|
||||
"%s:%v:%s", fs.Gvk.String(), fs.CreateIfNotPresent, fs.Path)
|
||||
}
|
||||
|
||||
// If true, the primary key is the same, but other fields might not be.
|
||||
func (fs FieldSpec) effectivelyEquals(other FieldSpec) bool {
|
||||
return fs.IsSelected(&other.Gvk) && fs.Path == other.Path
|
||||
}
|
||||
|
||||
// PathSlice converts the path string to a slice of strings,
|
||||
// separated by a '/'. Forward slash can be contained in a
|
||||
// fieldname. such as ingress.kubernetes.io/auth-secret in
|
||||
// Ingress annotations. To deal with this special case, the
|
||||
// path to this field should be formatted as
|
||||
//
|
||||
// metadata/annotations/ingress.kubernetes.io\/auth-secret
|
||||
//
|
||||
// Then PathSlice will return
|
||||
//
|
||||
// []string{
|
||||
// "metadata",
|
||||
// "annotations",
|
||||
// "ingress.auth-secretkubernetes.io/auth-secret"
|
||||
// }
|
||||
func (fs FieldSpec) PathSlice() []string {
|
||||
if !strings.Contains(fs.Path, escapedForwardSlash) {
|
||||
return strings.Split(fs.Path, "/")
|
||||
}
|
||||
s := strings.Replace(fs.Path, escapedForwardSlash, tempSlashReplacement, -1)
|
||||
paths := strings.Split(s, "/")
|
||||
var result []string
|
||||
for _, path := range paths {
|
||||
result = append(result, strings.Replace(path, tempSlashReplacement, "/", -1))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
type fsSlice []FieldSpec
|
||||
|
||||
func (s fsSlice) Len() int { return len(s) }
|
||||
func (s fsSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s fsSlice) Less(i, j int) bool {
|
||||
return s[i].Gvk.IsLessThan(s[j].Gvk)
|
||||
}
|
||||
|
||||
// mergeAll merges the argument into this, returning the result.
|
||||
// Items already present are ignored.
|
||||
// Items that conflict (primary key matches, but remain data differs)
|
||||
// result in an error.
|
||||
func (s fsSlice) mergeAll(incoming fsSlice) (result fsSlice, err error) {
|
||||
result = s
|
||||
for _, x := range incoming {
|
||||
result, err = result.mergeOne(x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// mergeOne merges the argument into this, returning the result.
|
||||
// If the item's primary key is already present, and there are no
|
||||
// conflicts, it is ignored (we don't want duplicates).
|
||||
// If there is a conflict, the merge fails.
|
||||
func (s fsSlice) mergeOne(x FieldSpec) (fsSlice, error) {
|
||||
i := s.index(x)
|
||||
if i > -1 {
|
||||
// It's already there.
|
||||
if s[i].CreateIfNotPresent != x.CreateIfNotPresent {
|
||||
return nil, fmt.Errorf("conflicting fieldspecs")
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
return append(s, x), nil
|
||||
}
|
||||
|
||||
func (s fsSlice) index(fs FieldSpec) int {
|
||||
for i, x := range s {
|
||||
if x.effectivelyEquals(fs) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
105
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/namebackreferences.go
generated
vendored
Normal file
105
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/namebackreferences.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
)
|
||||
|
||||
// NameBackReferences is an association between a gvk.GVK and a list
|
||||
// of FieldSpec instances that could refer to it.
|
||||
//
|
||||
// It is used to handle name changes, and can be thought of as a
|
||||
// a contact list. If you change your own contact info (name,
|
||||
// phone number, etc.), you must tell your contacts or they won't
|
||||
// know about the change.
|
||||
//
|
||||
// For example, ConfigMaps can be used by Pods and everything that
|
||||
// contains a Pod; Deployment, Job, StatefulSet, etc. To change
|
||||
// the name of a ConfigMap instance from 'alice' to 'bob', one
|
||||
// must visit all objects that could refer to the ConfigMap, see if
|
||||
// they mention 'alice', and if so, change the reference to 'bob'.
|
||||
//
|
||||
// The NameBackReferences instance to aid in this could look like
|
||||
// {
|
||||
// kind: ConfigMap
|
||||
// version: v1
|
||||
// FieldSpecs:
|
||||
// - kind: Pod
|
||||
// version: v1
|
||||
// path: spec/volumes/configMap/name
|
||||
// - kind: Deployment
|
||||
// path: spec/template/spec/volumes/configMap/name
|
||||
// - kind: Job
|
||||
// path: spec/template/spec/volumes/configMap/name
|
||||
// (etc.)
|
||||
// }
|
||||
type NameBackReferences struct {
|
||||
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
FieldSpecs fsSlice `json:"FieldSpecs,omitempty" yaml:"FieldSpecs,omitempty"`
|
||||
}
|
||||
|
||||
func (n NameBackReferences) String() string {
|
||||
var r []string
|
||||
for _, f := range n.FieldSpecs {
|
||||
r = append(r, f.String())
|
||||
}
|
||||
return n.Gvk.String() + ": (\n" +
|
||||
strings.Join(r, "\n") + "\n)"
|
||||
}
|
||||
|
||||
type nbrSlice []NameBackReferences
|
||||
|
||||
func (s nbrSlice) Len() int { return len(s) }
|
||||
func (s nbrSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s nbrSlice) Less(i, j int) bool {
|
||||
return s[i].Gvk.IsLessThan(s[j].Gvk)
|
||||
}
|
||||
|
||||
func (s nbrSlice) mergeAll(o nbrSlice) (result nbrSlice, err error) {
|
||||
result = s
|
||||
for _, r := range o {
|
||||
result, err = result.mergeOne(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s nbrSlice) mergeOne(other NameBackReferences) (nbrSlice, error) {
|
||||
var result nbrSlice
|
||||
var err error
|
||||
found := false
|
||||
for _, c := range s {
|
||||
if c.Gvk.Equals(other.Gvk) {
|
||||
c.FieldSpecs, err = c.FieldSpecs.mergeAll(other.FieldSpecs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
found = true
|
||||
}
|
||||
result = append(result, c)
|
||||
}
|
||||
|
||||
if !found {
|
||||
result = append(result, other)
|
||||
}
|
||||
return result, nil
|
||||
}
|
134
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/transformerconfig.go
generated
vendored
Normal file
134
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/transformerconfig.go
generated
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package config provides the functions to load default or user provided configurations
|
||||
// for different transformers
|
||||
package config
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig"
|
||||
)
|
||||
|
||||
// TransformerConfig holds the data needed to perform transformations.
|
||||
type TransformerConfig struct {
|
||||
NamePrefix fsSlice `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
|
||||
NameSuffix fsSlice `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
|
||||
NameSpace fsSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
CommonLabels fsSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
|
||||
CommonAnnotations fsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
|
||||
NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
|
||||
VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
|
||||
}
|
||||
|
||||
// MakeEmptyConfig returns an empty TransformerConfig object
|
||||
func MakeEmptyConfig() *TransformerConfig {
|
||||
return &TransformerConfig{}
|
||||
}
|
||||
|
||||
// MakeDefaultConfig returns a default TransformerConfig.
|
||||
func MakeDefaultConfig() *TransformerConfig {
|
||||
c, err := makeTransformerConfigFromBytes(
|
||||
defaultconfig.GetDefaultFieldSpecs())
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to make default transformconfig: %v", err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// sortFields provides determinism in logging, tests, etc.
|
||||
func (t *TransformerConfig) sortFields() {
|
||||
sort.Sort(t.NamePrefix)
|
||||
sort.Sort(t.NameSpace)
|
||||
sort.Sort(t.CommonLabels)
|
||||
sort.Sort(t.CommonAnnotations)
|
||||
sort.Sort(t.NameReference)
|
||||
sort.Sort(t.VarReference)
|
||||
}
|
||||
|
||||
// AddPrefixFieldSpec adds a FieldSpec to NamePrefix
|
||||
func (t *TransformerConfig) AddPrefixFieldSpec(fs FieldSpec) (err error) {
|
||||
t.NamePrefix, err = t.NamePrefix.mergeOne(fs)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddSuffixFieldSpec adds a FieldSpec to NameSuffix
|
||||
func (t *TransformerConfig) AddSuffixFieldSpec(fs FieldSpec) (err error) {
|
||||
t.NameSuffix, err = t.NameSuffix.mergeOne(fs)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddLabelFieldSpec adds a FieldSpec to CommonLabels
|
||||
func (t *TransformerConfig) AddLabelFieldSpec(fs FieldSpec) (err error) {
|
||||
t.CommonLabels, err = t.CommonLabels.mergeOne(fs)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddAnnotationFieldSpec adds a FieldSpec to CommonAnnotations
|
||||
func (t *TransformerConfig) AddAnnotationFieldSpec(fs FieldSpec) (err error) {
|
||||
t.CommonAnnotations, err = t.CommonAnnotations.mergeOne(fs)
|
||||
return err
|
||||
}
|
||||
|
||||
// AddNamereferenceFieldSpec adds a NameBackReferences to NameReference
|
||||
func (t *TransformerConfig) AddNamereferenceFieldSpec(
|
||||
nbrs NameBackReferences) (err error) {
|
||||
t.NameReference, err = t.NameReference.mergeOne(nbrs)
|
||||
return err
|
||||
}
|
||||
|
||||
// Merge merges two TransformerConfigs objects into
|
||||
// a new TransformerConfig object
|
||||
func (t *TransformerConfig) Merge(input *TransformerConfig) (
|
||||
merged *TransformerConfig, err error) {
|
||||
if input == nil {
|
||||
return t, nil
|
||||
}
|
||||
merged = &TransformerConfig{}
|
||||
merged.NamePrefix, err = t.NamePrefix.mergeAll(input.NamePrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
merged.NameSuffix, err = t.NameSuffix.mergeAll(input.NameSuffix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
merged.NameSpace, err = t.NameSpace.mergeAll(input.NameSpace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
merged.CommonAnnotations, err = t.CommonAnnotations.mergeAll(
|
||||
input.CommonAnnotations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
merged.CommonLabels, err = t.CommonLabels.mergeAll(input.CommonLabels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
merged.VarReference, err = t.VarReference.mergeAll(input.VarReference)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
merged.NameReference, err = t.NameReference.mergeAll(input.NameReference)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
merged.sortFields()
|
||||
return merged, nil
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/image"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
)
|
||||
|
||||
// imageTransformer replace image names and tags
|
||||
type imageTransformer struct {
|
||||
images []image.Image
|
||||
}
|
||||
|
||||
var _ Transformer = &imageTransformer{}
|
||||
|
||||
// NewImageTransformer constructs an imageTransformer.
|
||||
func NewImageTransformer(slice []image.Image) (Transformer, error) {
|
||||
return &imageTransformer{slice}, nil
|
||||
}
|
||||
|
||||
// Transform finds the matching images and replaces name, tag and/or digest
|
||||
func (pt *imageTransformer) Transform(resources resmap.ResMap) error {
|
||||
if len(pt.images) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, res := range resources {
|
||||
err := pt.findAndReplaceImage(res.Map())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
findAndReplaceImage replaces the image name and tags inside one object
|
||||
It searches the object for container session
|
||||
then loops though all images inside containers session,
|
||||
finds matched ones and update the image name and tag name
|
||||
*/
|
||||
func (pt *imageTransformer) findAndReplaceImage(obj map[string]interface{}) error {
|
||||
paths := []string{"containers", "initContainers"}
|
||||
found := false
|
||||
for _, path := range paths {
|
||||
_, found = obj[path]
|
||||
if found {
|
||||
err := pt.updateContainers(obj, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return pt.findContainers(obj)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt *imageTransformer) updateContainers(obj map[string]interface{}, path string) error {
|
||||
containers := obj[path].([]interface{})
|
||||
for i := range containers {
|
||||
container := containers[i].(map[string]interface{})
|
||||
containerImage, found := container["image"]
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
imageName := containerImage.(string)
|
||||
for _, img := range pt.images {
|
||||
if isImageMatched(imageName, img.Name) {
|
||||
name, tag := split(imageName)
|
||||
if img.NewName != "" {
|
||||
name = img.NewName
|
||||
}
|
||||
if img.NewTag != "" {
|
||||
tag = ":" + img.NewTag
|
||||
}
|
||||
if img.Digest != "" {
|
||||
tag = "@" + img.Digest
|
||||
}
|
||||
container["image"] = name + tag
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt *imageTransformer) findContainers(obj map[string]interface{}) error {
|
||||
for key := range obj {
|
||||
switch typedV := obj[key].(type) {
|
||||
case map[string]interface{}:
|
||||
err := pt.findAndReplaceImage(typedV)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case []interface{}:
|
||||
for i := range typedV {
|
||||
item := typedV[i]
|
||||
typedItem, ok := item.(map[string]interface{})
|
||||
if ok {
|
||||
err := pt.findAndReplaceImage(typedItem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isImageMatched(s, t string) bool {
|
||||
// Tag values are limited to [a-zA-Z0-9_.-].
|
||||
pattern, _ := regexp.Compile("^" + t + "(:[a-zA-Z0-9_.-]*)?$")
|
||||
return pattern.MatchString(s)
|
||||
}
|
||||
|
||||
// split separates and returns the name and tag parts
|
||||
// from the image string using either colon `:` or at `@` separators.
|
||||
// Note that the returned tag keeps its separator.
|
||||
func split(imageName string) (name string, tag string) {
|
||||
ic := strings.LastIndex(imageName, ":")
|
||||
ia := strings.LastIndex(imageName, "@")
|
||||
if ic < 0 && ia < 0 {
|
||||
return imageName, ""
|
||||
}
|
||||
|
||||
i := ic
|
||||
if ic < 0 {
|
||||
i = ia
|
||||
}
|
||||
|
||||
name = imageName[:i]
|
||||
tag = imageName[i:]
|
||||
return
|
||||
}
|
86
vendor/sigs.k8s.io/kustomize/pkg/transformers/labelsandannotations.go
generated
vendored
Normal file
86
vendor/sigs.k8s.io/kustomize/pkg/transformers/labelsandannotations.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
// mapTransformer applies a string->string map to fieldSpecs.
|
||||
type mapTransformer struct {
|
||||
m map[string]string
|
||||
fieldSpecs []config.FieldSpec
|
||||
}
|
||||
|
||||
var _ Transformer = &mapTransformer{}
|
||||
|
||||
// NewLabelsMapTransformer constructs a mapTransformer.
|
||||
func NewLabelsMapTransformer(
|
||||
m map[string]string, fs []config.FieldSpec) (Transformer, error) {
|
||||
return NewMapTransformer(fs, m)
|
||||
}
|
||||
|
||||
// NewAnnotationsMapTransformer construct a mapTransformer.
|
||||
func NewAnnotationsMapTransformer(
|
||||
m map[string]string, fs []config.FieldSpec) (Transformer, error) {
|
||||
return NewMapTransformer(fs, m)
|
||||
}
|
||||
|
||||
// NewMapTransformer construct a mapTransformer.
|
||||
func NewMapTransformer(
|
||||
pc []config.FieldSpec, m map[string]string) (Transformer, error) {
|
||||
if m == nil {
|
||||
return NewNoOpTransformer(), nil
|
||||
}
|
||||
if pc == nil {
|
||||
return nil, errors.New("fieldSpecs is not expected to be nil")
|
||||
}
|
||||
return &mapTransformer{fieldSpecs: pc, m: m}, nil
|
||||
}
|
||||
|
||||
// Transform apply each <key, value> pair in the mapTransformer to the
|
||||
// fields specified in mapTransformer.
|
||||
func (o *mapTransformer) Transform(m resmap.ResMap) error {
|
||||
for id := range m {
|
||||
objMap := m[id].Map()
|
||||
for _, path := range o.fieldSpecs {
|
||||
if !id.Gvk().IsSelected(&path.Gvk) {
|
||||
continue
|
||||
}
|
||||
err := mutateField(objMap, path.PathSlice(), path.CreateIfNotPresent, o.addMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *mapTransformer) addMap(in interface{}) (interface{}, error) {
|
||||
m, ok := in.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%#v is expected to be %T", in, m)
|
||||
}
|
||||
for k, v := range o.m {
|
||||
m[k] = v
|
||||
}
|
||||
return m, nil
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sigs.k8s.io/kustomize/pkg/resource"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
)
|
||||
|
||||
// multiTransformer contains a list of transformers.
|
||||
type multiTransformer struct {
|
||||
transformers []Transformer
|
||||
checkConflictEnabled bool
|
||||
rf *resource.Factory
|
||||
}
|
||||
|
||||
var _ Transformer = &multiTransformer{}
|
||||
|
||||
// NewMultiTransformer constructs a multiTransformer.
|
||||
func NewMultiTransformer(t []Transformer) Transformer {
|
||||
r := &multiTransformer{
|
||||
transformers: make([]Transformer, len(t)),
|
||||
checkConflictEnabled: false}
|
||||
copy(r.transformers, t)
|
||||
return r
|
||||
}
|
||||
|
||||
// NewMultiTransformerWithConflictCheck constructs a multiTransformer with checking of conflicts.
|
||||
func NewMultiTransformerWithConflictCheck(t []Transformer) Transformer {
|
||||
r := &multiTransformer{
|
||||
transformers: make([]Transformer, len(t)),
|
||||
checkConflictEnabled: true}
|
||||
copy(r.transformers, t)
|
||||
return r
|
||||
}
|
||||
|
||||
// Transform prepends the name prefix.
|
||||
func (o *multiTransformer) Transform(m resmap.ResMap) error {
|
||||
if o.checkConflictEnabled {
|
||||
return o.transformWithCheckConflict(m)
|
||||
}
|
||||
return o.transform(m)
|
||||
}
|
||||
func (o *multiTransformer) transform(m resmap.ResMap) error {
|
||||
for _, t := range o.transformers {
|
||||
err := t.Transform(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Of the len(o.transformers)! possible transformer orderings, compare to a reversed order.
|
||||
// A spot check to perform when the transformations are supposed to be commutative.
|
||||
// Fail if there's a difference in the result.
|
||||
func (o *multiTransformer) transformWithCheckConflict(m resmap.ResMap) error {
|
||||
mcopy := m.DeepCopy(o.rf)
|
||||
err := o.transform(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.reverseTransformers()
|
||||
err = o.transform(mcopy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.ErrorIfNotEqual(mcopy)
|
||||
if err != nil {
|
||||
return fmt.Errorf("found conflict between different patches\n%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *multiTransformer) reverseTransformers() {
|
||||
for i, j := 0, len(o.transformers)-1; i < j; i, j = i+1, j-1 {
|
||||
o.transformers[i], o.transformers[j] = o.transformers[j], o.transformers[i]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type mutateFunc func(interface{}) (interface{}, error)
|
||||
|
||||
func mutateField(
|
||||
m map[string]interface{},
|
||||
pathToField []string,
|
||||
createIfNotPresent bool,
|
||||
fns ...mutateFunc) error {
|
||||
if len(pathToField) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, found := m[pathToField[0]]
|
||||
if !found {
|
||||
if !createIfNotPresent {
|
||||
return nil
|
||||
}
|
||||
m[pathToField[0]] = map[string]interface{}{}
|
||||
}
|
||||
|
||||
if len(pathToField) == 1 {
|
||||
var err error
|
||||
for _, fn := range fns {
|
||||
m[pathToField[0]], err = fn(m[pathToField[0]])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
v := m[pathToField[0]]
|
||||
newPathToField := pathToField[1:]
|
||||
switch typedV := v.(type) {
|
||||
case nil:
|
||||
log.Printf(
|
||||
"nil value at `%s` ignored in mutation attempt",
|
||||
strings.Join(pathToField, "."))
|
||||
return nil
|
||||
case map[string]interface{}:
|
||||
return mutateField(typedV, newPathToField, createIfNotPresent, fns...)
|
||||
case []interface{}:
|
||||
for i := range typedV {
|
||||
item := typedV[i]
|
||||
typedItem, ok := item.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("%#v is expected to be %T", item, typedItem)
|
||||
}
|
||||
err := mutateField(typedItem, newPathToField, createIfNotPresent, fns...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("%#v is not expected to be a primitive type", typedV)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
type nameReferenceTransformer struct {
|
||||
backRefs []config.NameBackReferences
|
||||
}
|
||||
|
||||
var _ Transformer = &nameReferenceTransformer{}
|
||||
|
||||
// NewNameReferenceTransformer constructs a nameReferenceTransformer
|
||||
// with a given slice of NameBackReferences.
|
||||
func NewNameReferenceTransformer(br []config.NameBackReferences) Transformer {
|
||||
if br == nil {
|
||||
log.Fatal("backrefs not expected to be nil")
|
||||
}
|
||||
return &nameReferenceTransformer{backRefs: br}
|
||||
}
|
||||
|
||||
// Transform updates name references in resource A that refer to resource B,
|
||||
// given that B's name may have changed.
|
||||
//
|
||||
// For example, a HorizontalPodAutoscaler (HPA) necessarily refers to a
|
||||
// Deployment (the thing that the HPA scales). The Deployment name might change
|
||||
// (e.g. prefix added), and the reference in the HPA has to be fixed.
|
||||
//
|
||||
// In the outer loop below, we encounter an HPA. In scanning backrefs, we
|
||||
// find that HPA refers to a Deployment. So we find all resources in the same
|
||||
// namespace as the HPA (and with the same prefix and suffix), and look through
|
||||
// them to find all the Deployments with a resId that has a Name matching the
|
||||
// field in HPA. For each match, we overwrite the HPA name field with the value
|
||||
// found in the Deployment's name field (the name in the raw object - the
|
||||
// modified name - not the unmodified name in the resId).
|
||||
//
|
||||
// This assumes that the name stored in a ResId (the ResMap key) isn't modified
|
||||
// by name transformers. Name transformers should only modify the name in the
|
||||
// body of the resource object (the value in the ResMap).
|
||||
func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error {
|
||||
// TODO: Too much looping.
|
||||
// Even more hidden loops in FilterBy,
|
||||
// updateNameReference and FindByGVKN.
|
||||
for id := range m {
|
||||
for _, backRef := range o.backRefs {
|
||||
for _, fSpec := range backRef.FieldSpecs {
|
||||
if id.Gvk().IsSelected(&fSpec.Gvk) {
|
||||
err := mutateField(
|
||||
m[id].Map(), fSpec.PathSlice(),
|
||||
fSpec.CreateIfNotPresent,
|
||||
o.updateNameReference(
|
||||
backRef.Gvk, m.FilterBy(id)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *nameReferenceTransformer) updateNameReference(
|
||||
backRef gvk.Gvk, m resmap.ResMap) func(in interface{}) (interface{}, error) {
|
||||
return func(in interface{}) (interface{}, error) {
|
||||
switch in.(type) {
|
||||
case string:
|
||||
s, _ := in.(string)
|
||||
for id, res := range m {
|
||||
if id.Gvk().IsSelected(&backRef) && id.Name() == s {
|
||||
matchedIds := m.FindByGVKN(id)
|
||||
// If there's more than one match, there's no way
|
||||
// to know which one to pick, so emit error.
|
||||
if len(matchedIds) > 1 {
|
||||
return nil, fmt.Errorf(
|
||||
"Multiple matches for name %s:\n %v", id, matchedIds)
|
||||
}
|
||||
// Return transformed name of the object,
|
||||
// complete with prefixes, hashes, etc.
|
||||
return res.GetName(), nil
|
||||
}
|
||||
}
|
||||
return in, nil
|
||||
case []interface{}:
|
||||
l, _ := in.([]interface{})
|
||||
var names []string
|
||||
for _, item := range l {
|
||||
name, ok := item.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%#v is expected to be %T", item, name)
|
||||
}
|
||||
names = append(names, name)
|
||||
}
|
||||
for id, res := range m {
|
||||
indexes := indexOf(id.Name(), names)
|
||||
if id.Gvk().IsSelected(&backRef) && len(indexes) > 0 {
|
||||
matchedIds := m.FindByGVKN(id)
|
||||
if len(matchedIds) > 1 {
|
||||
return nil, fmt.Errorf(
|
||||
"Multiple matches for name %s:\n %v", id, matchedIds)
|
||||
}
|
||||
for _, index := range indexes {
|
||||
l[index] = res.GetName()
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
}
|
||||
return in, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("%#v is expected to be either a string or a []interface{}", in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func indexOf(s string, slice []string) []int {
|
||||
var index []int
|
||||
for i, item := range slice {
|
||||
if item == s {
|
||||
index = append(index, i)
|
||||
}
|
||||
}
|
||||
return index
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
type namespaceTransformer struct {
|
||||
namespace string
|
||||
fieldSpecsToUse []config.FieldSpec
|
||||
fieldSpecsToSkip []config.FieldSpec
|
||||
}
|
||||
|
||||
var _ Transformer = &namespaceTransformer{}
|
||||
|
||||
// NewNamespaceTransformer construct a namespaceTransformer.
|
||||
func NewNamespaceTransformer(ns string, cf []config.FieldSpec) Transformer {
|
||||
if len(ns) == 0 {
|
||||
return NewNoOpTransformer()
|
||||
}
|
||||
var skip []config.FieldSpec
|
||||
for _, g := range gvk.ClusterLevelGvks() {
|
||||
skip = append(skip, config.FieldSpec{Gvk: g})
|
||||
}
|
||||
return &namespaceTransformer{
|
||||
namespace: ns,
|
||||
fieldSpecsToUse: cf,
|
||||
fieldSpecsToSkip: skip,
|
||||
}
|
||||
}
|
||||
|
||||
// Transform adds the namespace.
|
||||
func (o *namespaceTransformer) Transform(m resmap.ResMap) error {
|
||||
mf := resmap.ResMap{}
|
||||
|
||||
for id := range m {
|
||||
found := false
|
||||
for _, path := range o.fieldSpecsToSkip {
|
||||
if id.Gvk().IsSelected(&path.Gvk) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
mf[id] = m[id]
|
||||
delete(m, id)
|
||||
}
|
||||
}
|
||||
|
||||
for id := range mf {
|
||||
objMap := mf[id].Map()
|
||||
for _, path := range o.fieldSpecsToUse {
|
||||
if !id.Gvk().IsSelected(&path.Gvk) {
|
||||
continue
|
||||
}
|
||||
|
||||
err := mutateField(objMap, path.PathSlice(), path.CreateIfNotPresent, func(_ interface{}) (interface{}, error) {
|
||||
return o.namespace, nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newid := id.CopyWithNewNamespace(o.namespace)
|
||||
m[newid] = mf[id]
|
||||
}
|
||||
|
||||
}
|
||||
o.updateClusterRoleBinding(m)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *namespaceTransformer) updateClusterRoleBinding(m resmap.ResMap) {
|
||||
saMap := map[string]bool{}
|
||||
for id := range m {
|
||||
if id.Gvk().Equals(gvk.Gvk{Version: "v1", Kind: "ServiceAccount"}) {
|
||||
saMap[id.Name()] = true
|
||||
}
|
||||
}
|
||||
|
||||
for id := range m {
|
||||
if id.Gvk().Kind != "ClusterRoleBinding" && id.Gvk().Kind != "RoleBinding" {
|
||||
continue
|
||||
}
|
||||
objMap := m[id].Map()
|
||||
subjects := objMap["subjects"].([]interface{})
|
||||
for i := range subjects {
|
||||
subject := subjects[i].(map[string]interface{})
|
||||
kind, foundk := subject["kind"]
|
||||
name, foundn := subject["name"]
|
||||
if !foundk || !foundn || kind.(string) != "ServiceAccount" {
|
||||
continue
|
||||
}
|
||||
// a ServiceAccount named “default” exists in every active namespace
|
||||
if name.(string) == "default" || saMap[name.(string)] {
|
||||
subject := subjects[i].(map[string]interface{})
|
||||
mutateField(subject, []string{"namespace"}, true, func(_ interface{}) (interface{}, error) {
|
||||
return o.namespace, nil
|
||||
})
|
||||
subjects[i] = subject
|
||||
}
|
||||
}
|
||||
objMap["subjects"] = subjects
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import "sigs.k8s.io/kustomize/pkg/resmap"
|
||||
|
||||
// noOpTransformer contains a no-op transformer.
|
||||
type noOpTransformer struct{}
|
||||
|
||||
var _ Transformer = &noOpTransformer{}
|
||||
|
||||
// NewNoOpTransformer constructs a noOpTransformer.
|
||||
func NewNoOpTransformer() Transformer {
|
||||
return &noOpTransformer{}
|
||||
}
|
||||
|
||||
// Transform does nothing.
|
||||
func (o *noOpTransformer) Transform(_ resmap.ResMap) error {
|
||||
return nil
|
||||
}
|
109
vendor/sigs.k8s.io/kustomize/pkg/transformers/prefixsuffixname.go
generated
vendored
Normal file
109
vendor/sigs.k8s.io/kustomize/pkg/transformers/prefixsuffixname.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package transformers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
// namePrefixSuffixTransformer contains the prefix, suffix, and the FieldSpecs
|
||||
// for each field needing a name prefix and suffix.
|
||||
type namePrefixSuffixTransformer struct {
|
||||
prefix string
|
||||
suffix string
|
||||
fieldSpecsToUse []config.FieldSpec
|
||||
fieldSpecsToSkip []config.FieldSpec
|
||||
}
|
||||
|
||||
var _ Transformer = &namePrefixSuffixTransformer{}
|
||||
|
||||
var prefixSuffixFieldSpecsToSkip = []config.FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{Kind: "CustomResourceDefinition"},
|
||||
},
|
||||
}
|
||||
|
||||
// NewNamePrefixSuffixTransformer makes a namePrefixSuffixTransformer.
|
||||
func NewNamePrefixSuffixTransformer(
|
||||
np, ns string, fieldSpecs []config.FieldSpec) (Transformer, error) {
|
||||
if len(np) == 0 && len(ns) == 0 {
|
||||
return NewNoOpTransformer(), nil
|
||||
}
|
||||
if fieldSpecs == nil {
|
||||
return nil, errors.New("fieldSpecs is not expected to be nil")
|
||||
}
|
||||
return &namePrefixSuffixTransformer{
|
||||
prefix: np,
|
||||
suffix: ns,
|
||||
fieldSpecsToUse: fieldSpecs,
|
||||
fieldSpecsToSkip: prefixSuffixFieldSpecsToSkip}, nil
|
||||
}
|
||||
|
||||
// Transform prepends the name prefix and appends the name suffix.
|
||||
func (o *namePrefixSuffixTransformer) Transform(m resmap.ResMap) error {
|
||||
// Fill map "mf" with entries subject to name modification, and
|
||||
// delete these entries from "m", so that for now m retains only
|
||||
// the entries whose names will not be modified.
|
||||
mf := resmap.ResMap{}
|
||||
for id := range m {
|
||||
found := false
|
||||
for _, path := range o.fieldSpecsToSkip {
|
||||
if id.Gvk().IsSelected(&path.Gvk) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
mf[id] = m[id]
|
||||
delete(m, id)
|
||||
}
|
||||
}
|
||||
|
||||
for id := range mf {
|
||||
objMap := mf[id].Map()
|
||||
for _, path := range o.fieldSpecsToUse {
|
||||
if !id.Gvk().IsSelected(&path.Gvk) {
|
||||
continue
|
||||
}
|
||||
err := mutateField(
|
||||
objMap,
|
||||
path.PathSlice(),
|
||||
path.CreateIfNotPresent,
|
||||
o.addPrefixSuffix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newId := id.CopyWithNewPrefixSuffix(o.prefix, o.suffix)
|
||||
m[newId] = mf[id]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *namePrefixSuffixTransformer) addPrefixSuffix(
|
||||
in interface{}) (interface{}, error) {
|
||||
s, ok := in.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%#v is expected to be %T", in, s)
|
||||
}
|
||||
return fmt.Sprintf("%s%s%s", o.prefix, s, o.suffix), nil
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package transformers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/expansion"
|
||||
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
type refvarTransformer struct {
|
||||
fieldSpecs []config.FieldSpec
|
||||
mappingFunc func(string) string
|
||||
}
|
||||
|
||||
// NewRefVarTransformer returns a Transformer that replaces $(VAR) style
|
||||
// variables with values.
|
||||
// The fieldSpecs are the places to look for occurrences of $(VAR).
|
||||
func NewRefVarTransformer(
|
||||
varMap map[string]string, fs []config.FieldSpec) Transformer {
|
||||
if len(varMap) == 0 {
|
||||
return NewNoOpTransformer()
|
||||
}
|
||||
return &refvarTransformer{
|
||||
fieldSpecs: fs,
|
||||
mappingFunc: expansion.MappingFuncFor(varMap),
|
||||
}
|
||||
}
|
||||
|
||||
// replaceVars accepts as 'in' a string, or string array, which can have
|
||||
// embedded instances of $VAR style variables, e.g. a container command string.
|
||||
// The function returns the string with the variables expanded to their final
|
||||
// values.
|
||||
func (rv *refvarTransformer) replaceVars(in interface{}) (interface{}, error) {
|
||||
switch vt := in.(type) {
|
||||
case []interface{}:
|
||||
var xs []string
|
||||
for _, a := range in.([]interface{}) {
|
||||
xs = append(xs, expansion.Expand(a.(string), rv.mappingFunc))
|
||||
}
|
||||
return xs, nil
|
||||
case interface{}:
|
||||
s, ok := in.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%#v is expected to be %T", in, s)
|
||||
}
|
||||
return expansion.Expand(s, rv.mappingFunc), nil
|
||||
case nil:
|
||||
return nil, nil
|
||||
default:
|
||||
return "", fmt.Errorf("invalid type encountered %T", vt)
|
||||
}
|
||||
}
|
||||
|
||||
// Transform replaces $(VAR) style variables with values.
|
||||
func (rv *refvarTransformer) Transform(m resmap.ResMap) error {
|
||||
for id, res := range m {
|
||||
for _, fieldSpec := range rv.fieldSpecs {
|
||||
if id.Gvk().IsSelected(&fieldSpec.Gvk) {
|
||||
if err := mutateField(
|
||||
res.Map(), fieldSpec.PathSlice(),
|
||||
false, rv.replaceVars); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package transformers has implementations of resmap.ResMap transformers.
|
||||
package transformers
|
||||
|
||||
import "sigs.k8s.io/kustomize/pkg/resmap"
|
||||
|
||||
// A Transformer modifies an instance of resmap.ResMap.
|
||||
type Transformer interface {
|
||||
// Transform modifies data in the argument, e.g. adding labels to resources that can be labelled.
|
||||
Transform(m resmap.ResMap) error
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"genargs.go",
|
||||
"generationbehavior.go",
|
||||
"kustomization.go",
|
||||
"var.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize/pkg/types",
|
||||
importpath = "sigs.k8s.io/kustomize/pkg/types",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/gvk:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/image:go_default_library",
|
||||
"//vendor/sigs.k8s.io/kustomize/pkg/patch:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package types
|
||||
|
||||
// GenArgs contains both generator args and options
|
||||
type GenArgs struct {
|
||||
args *GeneratorArgs
|
||||
opts *GeneratorOptions
|
||||
}
|
||||
|
||||
// NewGenArgs returns a new object of GenArgs
|
||||
func NewGenArgs(args *GeneratorArgs, opts *GeneratorOptions) *GenArgs {
|
||||
return &GenArgs{
|
||||
args: args,
|
||||
opts: opts,
|
||||
}
|
||||
}
|
||||
|
||||
// NeedHashSuffix returns true if the hash suffix is needed.
|
||||
// It is needed when the two conditions are both met
|
||||
// 1) GenArgs is not nil
|
||||
// 2) DisableNameSuffixHash in GeneratorOptions is not set to true
|
||||
func (g *GenArgs) NeedsHashSuffix() bool {
|
||||
return g.args != nil && (g.opts == nil || g.opts.DisableNameSuffixHash == false)
|
||||
}
|
||||
|
||||
// Behavior returns Behavior field of GeneratorArgs
|
||||
func (g *GenArgs) Behavior() GenerationBehavior {
|
||||
if g.args == nil {
|
||||
return BehaviorUnspecified
|
||||
}
|
||||
return NewGenerationBehavior(g.args.Behavior)
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package types
|
||||
|
||||
// GenerationBehavior specifies generation behavior of configmaps, secrets and maybe other resources.
|
||||
type GenerationBehavior int
|
||||
|
||||
const (
|
||||
// BehaviorUnspecified is an Unspecified behavior; typically treated as a Create.
|
||||
BehaviorUnspecified GenerationBehavior = iota
|
||||
// BehaviorCreate makes a new resource.
|
||||
BehaviorCreate
|
||||
// BehaviorReplace replaces a resource.
|
||||
BehaviorReplace
|
||||
// BehaviorMerge attempts to merge a new resource with an existing resource.
|
||||
BehaviorMerge
|
||||
)
|
||||
|
||||
// String converts a GenerationBehavior to a string.
|
||||
func (b GenerationBehavior) String() string {
|
||||
switch b {
|
||||
case BehaviorReplace:
|
||||
return "replace"
|
||||
case BehaviorMerge:
|
||||
return "merge"
|
||||
case BehaviorCreate:
|
||||
return "create"
|
||||
default:
|
||||
return "unspecified"
|
||||
}
|
||||
}
|
||||
|
||||
// NewGenerationBehavior converts a string to a GenerationBehavior.
|
||||
func NewGenerationBehavior(s string) GenerationBehavior {
|
||||
switch s {
|
||||
case "replace":
|
||||
return BehaviorReplace
|
||||
case "merge":
|
||||
return BehaviorMerge
|
||||
case "create":
|
||||
return BehaviorCreate
|
||||
default:
|
||||
return BehaviorUnspecified
|
||||
}
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package types holds struct definitions that should find a better home.
|
||||
package types
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/image"
|
||||
"sigs.k8s.io/kustomize/pkg/patch"
|
||||
)
|
||||
|
||||
const (
|
||||
KustomizationVersion = "kustomize.config.k8s.io/v1beta1"
|
||||
KustomizationKind = "Kustomization"
|
||||
)
|
||||
|
||||
// TypeMeta copies apimachinery/pkg/apis/meta/v1.TypeMeta
|
||||
type TypeMeta struct {
|
||||
// Kind copies apimachinery/pkg/apis/meta/v1.Typemeta.Kind
|
||||
Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
|
||||
|
||||
// APIVersion copies apimachinery/pkg/apis/meta/v1.Typemeta.APIVersion
|
||||
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
|
||||
}
|
||||
|
||||
// Kustomization holds the information needed to generate customized k8s api resources.
|
||||
type Kustomization struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
|
||||
//
|
||||
// Operators - what kustomize can do.
|
||||
//
|
||||
|
||||
// NamePrefix will prefix the names of all resources mentioned in the kustomization
|
||||
// file including generated configmaps and secrets.
|
||||
NamePrefix string `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
|
||||
|
||||
// NameSuffix will suffix the names of all resources mentioned in the kustomization
|
||||
// file including generated configmaps and secrets.
|
||||
NameSuffix string `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
|
||||
|
||||
// Namespace to add to all objects.
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
|
||||
// CommonLabels to add to all objects and selectors.
|
||||
CommonLabels map[string]string `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
|
||||
|
||||
// CommonAnnotations to add to all objects.
|
||||
CommonAnnotations map[string]string `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
|
||||
|
||||
// PatchesStrategicMerge specifies the relative path to a file
|
||||
// containing a strategic merge patch. Format documented at
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/strategic-merge-patch.md
|
||||
// URLs and globs are not supported.
|
||||
PatchesStrategicMerge []patch.StrategicMerge `json:"patchesStrategicMerge,omitempty" yaml:"patchesStrategicMerge,omitempty"`
|
||||
|
||||
// JSONPatches is a list of JSONPatch for applying JSON patch.
|
||||
// Format documented at https://tools.ietf.org/html/rfc6902
|
||||
// and http://jsonpatch.com
|
||||
PatchesJson6902 []patch.Json6902 `json:"patchesJson6902,omitempty" yaml:"patchesJson6902,omitempty"`
|
||||
|
||||
// Images is a list of (image name, new name, new tag or digest)
|
||||
// for changing image names, tags or digests. This can also be achieved with a
|
||||
// patch, but this operator is simpler to specify.
|
||||
Images []image.Image `json:"images,omitempty" yaml:"images,omitempty"`
|
||||
|
||||
// Vars allow things modified by kustomize to be injected into a
|
||||
// container specification. A var is a name (e.g. FOO) associated
|
||||
// with a field in a specific resource instance. The field must
|
||||
// contain a value of type string, and defaults to the name field
|
||||
// of the instance. Any appearance of "$(FOO)" in the container
|
||||
// spec will be replaced at kustomize build time, after the final
|
||||
// value of the specified field has been determined.
|
||||
Vars []Var `json:"vars,omitempty" yaml:"vars,omitempty"`
|
||||
|
||||
//
|
||||
// Operands - what kustomize operates on.
|
||||
//
|
||||
|
||||
// Resources specifies relative paths to files holding YAML representations
|
||||
// of kubernetes API objects. URLs and globs not supported.
|
||||
Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
|
||||
// Crds specifies relative paths to Custom Resource Definition files.
|
||||
// This allows custom resources to be recognized as operands, making
|
||||
// it possible to add them to the Resources list.
|
||||
// CRDs themselves are not modified.
|
||||
Crds []string `json:"crds,omitempty" yaml:"crds,omitempty"`
|
||||
|
||||
// Bases are relative paths or github repository URLs specifying a
|
||||
// directory containing a kustomization.yaml file.
|
||||
// URL format: https://github.com/hashicorp/go-getter#url-format
|
||||
Bases []string `json:"bases,omitempty" yaml:"bases,omitempty"`
|
||||
|
||||
//
|
||||
// Generators (operators that create operands)
|
||||
//
|
||||
|
||||
// ConfigMapGenerator is a list of configmaps to generate from
|
||||
// local data (one configMap per list item).
|
||||
// The resulting resource is a normal operand, subject to
|
||||
// name prefixing, patching, etc. By default, the name of
|
||||
// the map will have a suffix hash generated from its contents.
|
||||
ConfigMapGenerator []ConfigMapArgs `json:"configMapGenerator,omitempty" yaml:"configMapGenerator,omitempty"`
|
||||
|
||||
// SecretGenerator is a list of secrets to generate from
|
||||
// local data (one secret per list item).
|
||||
// The resulting resource is a normal operand, subject to
|
||||
// name prefixing, patching, etc. By default, the name of
|
||||
// the map will have a suffix hash generated from its contents.
|
||||
SecretGenerator []SecretArgs `json:"secretGenerator,omitempty" yaml:"secretGenerator,omitempty"`
|
||||
|
||||
// GeneratorOptions modify behavior of all ConfigMap and Secret generators.
|
||||
GeneratorOptions *GeneratorOptions `json:"generatorOptions,omitempty" yaml:"generatorOptions,omitempty"`
|
||||
|
||||
// Configurations is a list of transformer configuration files
|
||||
Configurations []string `json:"configurations,omitempty" yaml:"configurations,omitempty"`
|
||||
}
|
||||
|
||||
// DealWithMissingFields fills the missing fields
|
||||
func (k *Kustomization) DealWithMissingFields() []string {
|
||||
var msgs []string
|
||||
if k.APIVersion == "" {
|
||||
k.APIVersion = KustomizationVersion
|
||||
msgs = append(msgs, "Fixed the missing field by adding apiVersion: "+KustomizationVersion)
|
||||
}
|
||||
if k.Kind == "" {
|
||||
k.Kind = KustomizationKind
|
||||
msgs = append(msgs, "Fixed the missing field by adding kind: "+KustomizationKind)
|
||||
}
|
||||
return msgs
|
||||
}
|
||||
|
||||
func (k *Kustomization) EnforceFields() []string {
|
||||
var errs []string
|
||||
if k.APIVersion != "" && k.APIVersion != KustomizationVersion {
|
||||
errs = append(errs, "apiVersion should be "+KustomizationVersion)
|
||||
}
|
||||
if k.Kind != "" && k.Kind != KustomizationKind {
|
||||
errs = append(errs, "kind should be "+KustomizationKind)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// DealWithDeprecatedFields should be called immediately after
|
||||
// loading from storage.
|
||||
func DealWithDeprecatedFields(data []byte) []byte {
|
||||
deprecateFieldsMap := map[string]string{
|
||||
"patches:": "patchesStrategicMerge:",
|
||||
"imageTags:": "images:",
|
||||
}
|
||||
for oldname, newname := range deprecateFieldsMap {
|
||||
pattern := regexp.MustCompile(oldname)
|
||||
data = pattern.ReplaceAll(data, []byte(newname))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// GeneratorArgs contains arguments common to generators.
|
||||
type GeneratorArgs struct {
|
||||
// Namespace for the configmap, optional
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
|
||||
// Name - actually the partial name - of the generated resource.
|
||||
// The full name ends up being something like
|
||||
// NamePrefix + this.Name + hash(content of generated resource).
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
|
||||
// Behavior of generated resource, must be one of:
|
||||
// 'create': create a new one
|
||||
// 'replace': replace the existing one
|
||||
// 'merge': merge with the existing one
|
||||
Behavior string `json:"behavior,omitempty" yaml:"behavior,omitempty"`
|
||||
|
||||
// DataSources for the generator.
|
||||
DataSources `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
}
|
||||
|
||||
// ConfigMapArgs contains the metadata of how to generate a configmap.
|
||||
type ConfigMapArgs struct {
|
||||
// GeneratorArgs for the configmap.
|
||||
GeneratorArgs `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
}
|
||||
|
||||
// SecretArgs contains the metadata of how to generate a secret.
|
||||
type SecretArgs struct {
|
||||
// GeneratorArgs for the secret.
|
||||
GeneratorArgs `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
|
||||
// Type of the secret.
|
||||
//
|
||||
// This is the same field as the secret type field in v1/Secret:
|
||||
// It can be "Opaque" (default), or "kubernetes.io/tls".
|
||||
//
|
||||
// If type is "kubernetes.io/tls", then "literals" or "files" must have exactly two
|
||||
// keys: "tls.key" and "tls.crt"
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
}
|
||||
|
||||
// DataSources contains some generic sources for configmaps.
|
||||
type DataSources struct {
|
||||
// LiteralSources is a list of literal sources.
|
||||
// Each literal source should be a key and literal value,
|
||||
// e.g. `somekey=somevalue`
|
||||
// It will be similar to kubectl create configmap|secret --from-literal
|
||||
LiteralSources []string `json:"literals,omitempty" yaml:"literals,omitempty"`
|
||||
|
||||
// FileSources is a list of file sources.
|
||||
// Each file source can be specified using its file path, in which case file
|
||||
// basename will be used as configmap key, or optionally with a key and file
|
||||
// path, in which case the given key will be used.
|
||||
// Specifying a directory will iterate each named file in the directory
|
||||
// whose basename is a valid configmap key.
|
||||
// It will be similar to kubectl create configmap|secret --from-file
|
||||
FileSources []string `json:"files,omitempty" yaml:"files,omitempty"`
|
||||
|
||||
// EnvSource format should be a path to a file to read lines of key=val
|
||||
// pairs to create a configmap.
|
||||
// i.e. a Docker .env file or a .ini file.
|
||||
EnvSource string `json:"env,omitempty" yaml:"env,omitempty"`
|
||||
}
|
||||
|
||||
// GeneratorOptions modify behavior of all ConfigMap and Secret generators.
|
||||
type GeneratorOptions struct {
|
||||
// Labels to add to all generated resources.
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
|
||||
// Annotations to add to all generated resources.
|
||||
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
|
||||
|
||||
// DisableNameSuffixHash if true disables the default behavior of adding a
|
||||
// suffix to the names of generated resources that is a hash of the
|
||||
// resource contents.
|
||||
DisableNameSuffixHash bool `json:"disableNameSuffixHash,omitempty" yaml:"disableNameSuffixHash,omitempty"`
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
)
|
||||
|
||||
const defaultFieldPath = "metadata.name"
|
||||
|
||||
// Var represents a variable whose value will be sourced
|
||||
// from a field in a Kubernetes object.
|
||||
type Var struct {
|
||||
// Value of identifier name e.g. FOO used in container args, annotations
|
||||
// Appears in pod template as $(FOO)
|
||||
Name string `json:"name" yaml:"name"`
|
||||
|
||||
// ObjRef must refer to a Kubernetes resource under the
|
||||
// purview of this kustomization. ObjRef should use the
|
||||
// raw name of the object (the name specified in its YAML,
|
||||
// before addition of a namePrefix and a nameSuffix).
|
||||
ObjRef Target `json:"objref" yaml:"objref"`
|
||||
|
||||
// FieldRef refers to the field of the object referred to by
|
||||
// ObjRef whose value will be extracted for use in
|
||||
// replacing $(FOO).
|
||||
// If unspecified, this defaults to fieldPath: $defaultFieldPath
|
||||
FieldRef FieldSelector `json:"fieldref,omitempty" yaml:"fieldref,omitempty"`
|
||||
}
|
||||
|
||||
// Target refers to a kubernetes object by Group, Version, Kind and Name
|
||||
// gvk.Gvk contains Group, Version and Kind
|
||||
// APIVersion is added to keep the backward compatibility of using ObjectReference
|
||||
// for Var.ObjRef
|
||||
type Target struct {
|
||||
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
|
||||
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
Name string `json:"name" yaml:"name"`
|
||||
}
|
||||
|
||||
// FieldSelector contains the fieldPath to an object field.
|
||||
// This struct is added to keep the backward compatibility of using ObjectFieldSelector
|
||||
// for Var.FieldRef
|
||||
type FieldSelector struct {
|
||||
FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"`
|
||||
}
|
||||
|
||||
// defaulting sets reference to field used by default.
|
||||
func (v *Var) defaulting() {
|
||||
if v.FieldRef.FieldPath == "" {
|
||||
v.FieldRef.FieldPath = defaultFieldPath
|
||||
}
|
||||
}
|
||||
|
||||
// VarSet is a slice of Vars where no var.Name is repeated.
|
||||
type VarSet struct {
|
||||
set []Var
|
||||
}
|
||||
|
||||
// Set returns the var set.
|
||||
func (vs *VarSet) Set() []Var {
|
||||
return vs.set
|
||||
}
|
||||
|
||||
// MergeSet absorbs other vars with error on name collision.
|
||||
func (vs *VarSet) MergeSet(incoming *VarSet) error {
|
||||
return vs.MergeSlice(incoming.set)
|
||||
}
|
||||
|
||||
// MergeSlice absorbs other vars with error on name collision.
|
||||
// Empty fields in incoming vars are defaulted.
|
||||
func (vs *VarSet) MergeSlice(incoming []Var) error {
|
||||
for _, v := range incoming {
|
||||
if vs.Contains(v) {
|
||||
return fmt.Errorf(
|
||||
"var %s already encountered", v.Name)
|
||||
}
|
||||
v.defaulting()
|
||||
vs.insert(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vs *VarSet) insert(v Var) {
|
||||
index := sort.Search(
|
||||
len(vs.set),
|
||||
func(i int) bool { return vs.set[i].Name > v.Name })
|
||||
// make room
|
||||
vs.set = append(vs.set, Var{})
|
||||
// shift right at index.
|
||||
// copy will not increase size of destination.
|
||||
copy(vs.set[index+1:], vs.set[index:])
|
||||
vs.set[index] = v
|
||||
}
|
||||
|
||||
// Contains is true if the set has the other var.
|
||||
func (vs *VarSet) Contains(other Var) bool {
|
||||
return vs.Get(other.Name) != nil
|
||||
}
|
||||
|
||||
// Get returns the var with the given name, else nil.
|
||||
func (vs *VarSet) Get(name string) *Var {
|
||||
for _, v := range vs.set {
|
||||
if v.Name == name {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GVK returns the Gvk object in Target
|
||||
func (t *Target) GVK() gvk.Gvk {
|
||||
if t.APIVersion == "" {
|
||||
return t.Gvk
|
||||
}
|
||||
versions := strings.Split(t.APIVersion, "/")
|
||||
if len(versions) == 2 {
|
||||
t.Group = versions[0]
|
||||
t.Version = versions[1]
|
||||
}
|
||||
if len(versions) == 1 {
|
||||
t.Version = versions[0]
|
||||
}
|
||||
return t.Gvk
|
||||
}
|
Loading…
Reference in New Issue