Merge pull request #70875 from Liujingfang1/enable-kustomize
Enable kustomize in kubectl
This commit is contained in:
100
Godeps/Godeps.json
generated
100
Godeps/Godeps.json
generated
@@ -4073,6 +4073,106 @@
|
|||||||
"ImportPath": "k8s.io/utils/pointer",
|
"ImportPath": "k8s.io/utils/pointer",
|
||||||
"Rev": "8e7ff06bf0e2d3289061230af203e430a15b6dcc"
|
"Rev": "8e7ff06bf0e2d3289061230af203e430a15b6dcc"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/commands/build",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/constants",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/expansion",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/factory",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/fs",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/gvk",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/internal/error",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/loader",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resid",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resmap",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resource",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/target",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/types",
|
||||||
|
"Comment": "v1.0.10-69-gef51cceff55b17",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "sigs.k8s.io/yaml",
|
"ImportPath": "sigs.k8s.io/yaml",
|
||||||
"Comment": "v1.1.0",
|
"Comment": "v1.1.0",
|
||||||
|
4180
Godeps/LICENSES
generated
4180
Godeps/LICENSES
generated
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@
|
|||||||
- k8s.io/api/core/v1
|
- k8s.io/api/core/v1
|
||||||
- k8s.io/cli-runtime/pkg/genericclioptions/printers
|
- k8s.io/cli-runtime/pkg/genericclioptions/printers
|
||||||
- k8s.io/cli-runtime/pkg/genericclioptions/resource
|
- k8s.io/cli-runtime/pkg/genericclioptions/resource
|
||||||
|
- k8s.io/cli-runtime/pkg/kustomize/k8sdeps
|
||||||
|
|
||||||
- baseImportPath: "./vendor/k8s.io/apimachinery/"
|
- baseImportPath: "./vendor/k8s.io/apimachinery/"
|
||||||
allowedImports:
|
allowedImports:
|
||||||
|
@@ -114,6 +114,7 @@ filegroup(
|
|||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook:all-srcs",
|
"//staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook:all-srcs",
|
||||||
"//staging/src/k8s.io/cli-runtime/artifacts:all-srcs",
|
"//staging/src/k8s.io/cli-runtime/artifacts:all-srcs",
|
||||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:all-srcs",
|
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:all-srcs",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps:all-srcs",
|
||||||
"//staging/src/k8s.io/client-go/deprecated-dynamic:all-srcs",
|
"//staging/src/k8s.io/client-go/deprecated-dynamic:all-srcs",
|
||||||
"//staging/src/k8s.io/client-go/discovery:all-srcs",
|
"//staging/src/k8s.io/client-go/discovery:all-srcs",
|
||||||
"//staging/src/k8s.io/client-go/dynamic:all-srcs",
|
"//staging/src/k8s.io/client-go/dynamic:all-srcs",
|
||||||
|
164
staging/src/k8s.io/cli-runtime/Godeps/Godeps.json
generated
164
staging/src/k8s.io/cli-runtime/Godeps/Godeps.json
generated
@@ -6,14 +6,50 @@
|
|||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
"Deps": [
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/PuerkitoBio/purell",
|
||||||
|
"Rev": "8a290539e2e8629dbc4e6bad948158f790ec31f4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||||
|
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||||
"Rev": "782f4967f2dc4564575ca782fe2d04090b5faca8"
|
"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",
|
"ImportPath": "github.com/evanphx/json-patch",
|
||||||
"Rev": "36442dbdb585210f8d5a1b45e67aa323c197d5c4"
|
"Rev": "36442dbdb585210f8d5a1b45e67aa323c197d5c4"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"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",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Rev": "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
"Rev": "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
||||||
@@ -82,6 +118,18 @@
|
|||||||
"ImportPath": "github.com/json-iterator/go",
|
"ImportPath": "github.com/json-iterator/go",
|
||||||
"Rev": "ab8a2e0c74be9d3be70b3184d9acc634935ded82"
|
"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",
|
"ImportPath": "github.com/modern-go/concurrent",
|
||||||
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||||
@@ -94,6 +142,10 @@
|
|||||||
"ImportPath": "github.com/peterbourgon/diskv",
|
"ImportPath": "github.com/peterbourgon/diskv",
|
||||||
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/pkg/errors",
|
||||||
|
"Rev": "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/pmezard/go-difflib/difflib",
|
"ImportPath": "github.com/pmezard/go-difflib/difflib",
|
||||||
"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
|
"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
|
||||||
@@ -190,6 +242,10 @@
|
|||||||
"ImportPath": "golang.org/x/text/unicode/norm",
|
"ImportPath": "golang.org/x/text/unicode/norm",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/width",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/time/rate",
|
"ImportPath": "golang.org/x/time/rate",
|
||||||
"Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
"Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
||||||
@@ -350,6 +406,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/api/validation",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -362,6 +422,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -442,6 +506,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -458,6 +526,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -478,6 +550,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -570,6 +646,14 @@
|
|||||||
"ImportPath": "k8s.io/klog",
|
"ImportPath": "k8s.io/klog",
|
||||||
"Rev": "8139d8cb77af419532b33dfa7dd09fbc5f1d344f"
|
"Rev": "8139d8cb77af419532b33dfa7dd09fbc5f1d344f"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/kube-openapi/pkg/common",
|
||||||
|
"Rev": "c59034cc13d587f5ef4e85ca0ade0c1866ae8e1d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
||||||
|
"Rev": "c59034cc13d587f5ef4e85ca0ade0c1866ae8e1d"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/client-go/discovery",
|
"ImportPath": "k8s.io/client-go/discovery",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -614,6 +698,86 @@
|
|||||||
"ImportPath": "k8s.io/client-go/util/testing",
|
"ImportPath": "k8s.io/client-go/util/testing",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/commands/build",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/constants",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/expansion",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/factory",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/fs",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/gvk",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/internal/error",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/loader",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resid",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resmap",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resource",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/target",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/types",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "sigs.k8s.io/yaml",
|
"ImportPath": "sigs.k8s.io/yaml",
|
||||||
"Rev": "fd68e9863619f6ec2fdd8625fe1f02e7c877e480"
|
"Rev": "fd68e9863619f6ec2fdd8625fe1f02e7c877e480"
|
||||||
|
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: the-map
|
||||||
|
data:
|
||||||
|
altGreeting: "Good Morning!"
|
||||||
|
enableRisky: "false"
|
@@ -0,0 +1,30 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: the-deployment
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
deployment: hello
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: the-container
|
||||||
|
image: monopole/hello:1
|
||||||
|
command: ["/hello",
|
||||||
|
"--port=8080",
|
||||||
|
"--enableRiskyFeature=$(ENABLE_RISKY)"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
env:
|
||||||
|
- name: ALT_GREETING
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: altGreeting
|
||||||
|
- name: ENABLE_RISKY
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: the-map
|
||||||
|
key: enableRisky
|
@@ -0,0 +1,5 @@
|
|||||||
|
nameprefix: test-
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- configMap.yaml
|
@@ -0,0 +1,13 @@
|
|||||||
|
kind: Service
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: the-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
deployment: hello
|
||||||
|
type: LoadBalancer
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8666
|
||||||
|
targetPort: 8080
|
||||||
|
|
@@ -35,12 +35,16 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/restmapper:go_default_library",
|
"//staging/src/k8s.io/client-go/restmapper:go_default_library",
|
||||||
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
||||||
"//vendor/golang.org/x/text/transform:go_default_library",
|
"//vendor/golang.org/x/text/transform:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/commands/build:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/constants:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -465,27 +465,48 @@ func TestPathBuilderWithMultipleInvalid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDirectoryBuilder(t *testing.T) {
|
func TestDirectoryBuilder(t *testing.T) {
|
||||||
b := newDefaultBuilder().
|
tests := []struct {
|
||||||
FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../artifacts/guestbook"}}).
|
directories []string
|
||||||
NamespaceParam("test").DefaultNamespace()
|
singleItem bool
|
||||||
|
number int
|
||||||
test := &testVisitor{}
|
expectedNames []string
|
||||||
singleItemImplied := false
|
}{
|
||||||
|
{[]string{"../../../artifacts/guestbook"}, false, 3, []string{"redis-master"}},
|
||||||
err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle)
|
{[]string{"../../../artifacts/kustomization"}, true, 3, []string{"test-the-deployment"}},
|
||||||
if err != nil || singleItemImplied || len(test.Infos) < 3 {
|
{[]string{"../../../artifacts/guestbook", "../../../artifacts/kustomization"}, false, 6, []string{"redis-master", "test-the-deployment"}},
|
||||||
t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
found := false
|
for _, tt := range tests {
|
||||||
for _, info := range test.Infos {
|
b := newDefaultBuilder().
|
||||||
if info.Name == "redis-master" && info.Namespace == "test" && info.Object != nil {
|
FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: tt.directories}).
|
||||||
found = true
|
NamespaceParam("test").DefaultNamespace()
|
||||||
break
|
|
||||||
|
test := &testVisitor{}
|
||||||
|
singleItemImplied := false
|
||||||
|
|
||||||
|
err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle)
|
||||||
|
if err != nil || singleItemImplied != tt.singleItem || len(test.Infos) < tt.number {
|
||||||
|
t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
contained := func(name string) bool {
|
||||||
|
for _, info := range test.Infos {
|
||||||
|
if info.Name == name && info.Namespace == "test" && info.Object != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
allFound := true
|
||||||
|
for _, name := range tt.expectedNames {
|
||||||
|
if !contained(name) {
|
||||||
|
allFound = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !allFound {
|
||||||
|
t.Errorf("unexpected responses: %#v", test.Infos)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
t.Errorf("unexpected responses: %#v", test.Infos)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@@ -38,6 +39,10 @@ import (
|
|||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/yaml"
|
"k8s.io/apimachinery/pkg/util/yaml"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/commands/build"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/constants"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -452,7 +457,10 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if isKustomizationDir(path) {
|
||||||
|
visitors = append(visitors, NewKustomizationVisitor(mapper, path, schema))
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
if path != paths && !recursive {
|
if path != paths && !recursive {
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
@@ -463,7 +471,10 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
|||||||
if path != paths && ignoreFile(path, extensions) {
|
if path != paths && ignoreFile(path, extensions) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if filepath.Base(path) == constants.KustomizationFileName {
|
||||||
|
visitors = append(visitors, NewKustomizationVisitor(mapper, filepath.Dir(path), schema))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
visitor := &FileVisitor{
|
visitor := &FileVisitor{
|
||||||
Path: path,
|
Path: path,
|
||||||
StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
|
StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
|
||||||
@@ -479,6 +490,13 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
|||||||
return visitors, nil
|
return visitors, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isKustomizationDir(path string) bool {
|
||||||
|
if _, err := os.Stat(filepath.Join(path, constants.KustomizationFileName)); err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// FileVisitor is wrapping around a StreamVisitor, to handle open/close files
|
// FileVisitor is wrapping around a StreamVisitor, to handle open/close files
|
||||||
type FileVisitor struct {
|
type FileVisitor struct {
|
||||||
Path string
|
Path string
|
||||||
@@ -507,6 +525,37 @@ func (v *FileVisitor) Visit(fn VisitorFunc) error {
|
|||||||
return v.StreamVisitor.Visit(fn)
|
return v.StreamVisitor.Visit(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KustomizationVisitor prorvides the output of kustomization build
|
||||||
|
type KustomizationVisitor struct {
|
||||||
|
Path string
|
||||||
|
*StreamVisitor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visit in a KustomizationVisitor build the kustomization output
|
||||||
|
func (v *KustomizationVisitor) Visit(fn VisitorFunc) error {
|
||||||
|
fSys := fs.MakeRealFS()
|
||||||
|
f := k8sdeps.NewFactory()
|
||||||
|
var out bytes.Buffer
|
||||||
|
cmd := build.NewCmdBuild(&out, fSys, f.ResmapF, f.TransformerF)
|
||||||
|
cmd.SetArgs([]string{v.Path})
|
||||||
|
// we want to silence usage, error output, and any future output from cobra
|
||||||
|
// we will get error output as a golang error from execute
|
||||||
|
cmd.SetOutput(ioutil.Discard)
|
||||||
|
_, err := cmd.ExecuteC()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.StreamVisitor.Reader = bytes.NewReader(out.Bytes())
|
||||||
|
return v.StreamVisitor.Visit(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKustomizationVisitor(mapper *mapper, path string, schema ContentValidator) *KustomizationVisitor {
|
||||||
|
return &KustomizationVisitor{
|
||||||
|
Path: path,
|
||||||
|
StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// StreamVisitor reads objects from an io.Reader and walks them. A stream visitor can only be
|
// StreamVisitor reads objects from an io.Reader and walks them. A stream visitor can only be
|
||||||
// visited once.
|
// visited once.
|
||||||
// TODO: depends on objects being in JSON format before being passed to decode - need to implement
|
// TODO: depends on objects being in JSON format before being passed to decode - need to implement
|
||||||
|
38
staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/BUILD
Normal file
38
staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/BUILD
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"doc.go",
|
||||||
|
"factory.go",
|
||||||
|
],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps",
|
||||||
|
importpath = "k8s.io/cli-runtime/pkg/kustomize/k8sdeps",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct:go_default_library",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer:go_default_library",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/factory:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [
|
||||||
|
":package-srcs",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret:all-srcs",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct:all-srcs",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer:all-srcs",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator:all-srcs",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
@@ -0,0 +1,51 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"configmapfactory.go",
|
||||||
|
"kv.go",
|
||||||
|
"secretfactory.go",
|
||||||
|
],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret",
|
||||||
|
importpath = "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||||
|
"//vendor/github.com/pkg/errors: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/types:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = [
|
||||||
|
"configmapfactory_test.go",
|
||||||
|
"kv_test.go",
|
||||||
|
],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/loader: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,190 @@
|
|||||||
|
/*
|
||||||
|
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 configmapandsecret generates configmaps and secrets per generator rules.
|
||||||
|
package configmapandsecret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConfigMapFactory makes ConfigMaps.
|
||||||
|
type ConfigMapFactory struct {
|
||||||
|
fSys fs.FileSystem
|
||||||
|
ldr ifc.Loader
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConfigMapFactory returns a new ConfigMapFactory.
|
||||||
|
func NewConfigMapFactory(
|
||||||
|
fSys fs.FileSystem, l ifc.Loader) *ConfigMapFactory {
|
||||||
|
return &ConfigMapFactory{fSys: fSys, ldr: l}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ConfigMapFactory) makeFreshConfigMap(
|
||||||
|
args *types.ConfigMapArgs) *corev1.ConfigMap {
|
||||||
|
cm := &corev1.ConfigMap{}
|
||||||
|
cm.APIVersion = "v1"
|
||||||
|
cm.Kind = "ConfigMap"
|
||||||
|
cm.Name = args.Name
|
||||||
|
cm.Data = map[string]string{}
|
||||||
|
return cm
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeConfigMap returns a new ConfigMap, or nil and an error.
|
||||||
|
func (f *ConfigMapFactory) MakeConfigMap(
|
||||||
|
args *types.ConfigMapArgs, options *types.GeneratorOptions) (*corev1.ConfigMap, error) {
|
||||||
|
var all []kvPair
|
||||||
|
var err error
|
||||||
|
cm := f.makeFreshConfigMap(args)
|
||||||
|
|
||||||
|
pairs, err := keyValuesFromEnvFile(f.ldr, args.EnvSource)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||||
|
"env source file: %s",
|
||||||
|
args.EnvSource))
|
||||||
|
}
|
||||||
|
all = append(all, pairs...)
|
||||||
|
|
||||||
|
pairs, err = keyValuesFromLiteralSources(args.LiteralSources)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||||
|
"literal sources %v", args.LiteralSources))
|
||||||
|
}
|
||||||
|
all = append(all, pairs...)
|
||||||
|
|
||||||
|
pairs, err = keyValuesFromFileSources(f.ldr, args.FileSources)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||||
|
"file sources: %v", args.FileSources))
|
||||||
|
}
|
||||||
|
all = append(all, pairs...)
|
||||||
|
|
||||||
|
for _, kv := range all {
|
||||||
|
err = addKvToConfigMap(cm, kv.key, kv.value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if options != nil {
|
||||||
|
cm.SetLabels(options.Labels)
|
||||||
|
cm.SetAnnotations(options.Annotations)
|
||||||
|
}
|
||||||
|
return cm, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyValuesFromLiteralSources(sources []string) ([]kvPair, error) {
|
||||||
|
var kvs []kvPair
|
||||||
|
for _, s := range sources {
|
||||||
|
k, v, err := parseLiteralSource(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kvs = append(kvs, kvPair{key: k, value: v})
|
||||||
|
}
|
||||||
|
return kvs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyValuesFromFileSources(ldr ifc.Loader, sources []string) ([]kvPair, error) {
|
||||||
|
var kvs []kvPair
|
||||||
|
for _, s := range sources {
|
||||||
|
k, fPath, err := parseFileSource(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
content, err := ldr.Load(fPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kvs = append(kvs, kvPair{key: k, value: string(content)})
|
||||||
|
}
|
||||||
|
return kvs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyValuesFromEnvFile(l ifc.Loader, path string) ([]kvPair, error) {
|
||||||
|
if path == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
content, err := l.Load(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return keyValuesFromLines(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// addKvToConfigMap adds the given key and data to the given config map.
|
||||||
|
// Error if key invalid, or already exists.
|
||||||
|
func addKvToConfigMap(configMap *v1.ConfigMap, keyName, data string) error {
|
||||||
|
// Note, the rules for ConfigMap keys are the exact same as the ones for SecretKeys.
|
||||||
|
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
|
||||||
|
return fmt.Errorf("%q is not a valid key name for a ConfigMap: %s", keyName, strings.Join(errs, ";"))
|
||||||
|
}
|
||||||
|
if _, entryExists := configMap.Data[keyName]; entryExists {
|
||||||
|
return fmt.Errorf("cannot add key %s, another key by that name already exists: %v", keyName, configMap.Data)
|
||||||
|
}
|
||||||
|
configMap.Data[keyName] = data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseFileSource parses the source given.
|
||||||
|
//
|
||||||
|
// Acceptable formats include:
|
||||||
|
// 1. source-path: the basename will become the key name
|
||||||
|
// 2. source-name=source-path: the source-name will become the key name and
|
||||||
|
// source-path is the path to the key file.
|
||||||
|
//
|
||||||
|
// Key names cannot include '='.
|
||||||
|
func parseFileSource(source string) (keyName, filePath string, err error) {
|
||||||
|
numSeparators := strings.Count(source, "=")
|
||||||
|
switch {
|
||||||
|
case numSeparators == 0:
|
||||||
|
return path.Base(source), source, nil
|
||||||
|
case numSeparators == 1 && strings.HasPrefix(source, "="):
|
||||||
|
return "", "", fmt.Errorf("key name for file path %v missing", strings.TrimPrefix(source, "="))
|
||||||
|
case numSeparators == 1 && strings.HasSuffix(source, "="):
|
||||||
|
return "", "", fmt.Errorf("file path for key name %v missing", strings.TrimSuffix(source, "="))
|
||||||
|
case numSeparators > 1:
|
||||||
|
return "", "", errors.New("key names or file paths cannot contain '='")
|
||||||
|
default:
|
||||||
|
components := strings.Split(source, "=")
|
||||||
|
return components[0], components[1], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseLiteralSource parses the source key=val pair into its component pieces.
|
||||||
|
// This functionality is distinguished from strings.SplitN(source, "=", 2) since
|
||||||
|
// it returns an error in the case of empty keys, values, or a missing equals sign.
|
||||||
|
func parseLiteralSource(source string) (keyName, value string, err error) {
|
||||||
|
// leading equal is invalid
|
||||||
|
if strings.Index(source, "=") == 0 {
|
||||||
|
return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source)
|
||||||
|
}
|
||||||
|
// split after the first equal (so values can have the = character)
|
||||||
|
items := strings.SplitN(source, "=", 2)
|
||||||
|
if len(items) != 2 {
|
||||||
|
return "", "", fmt.Errorf("invalid literal source %v, expected key=value", source)
|
||||||
|
}
|
||||||
|
return items[0], strings.Trim(items[1], "\"'"), nil
|
||||||
|
}
|
@@ -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 configmapandsecret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/loader"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeEnvConfigMap(name string) *corev1.ConfigMap {
|
||||||
|
return &corev1.ConfigMap{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: "ConfigMap",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"DB_USERNAME": "admin",
|
||||||
|
"DB_PASSWORD": "somepw",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeFileConfigMap(name string) *corev1.ConfigMap {
|
||||||
|
return &corev1.ConfigMap{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: "ConfigMap",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"app-init.ini": `FOO=bar
|
||||||
|
BAR=baz
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeLiteralConfigMap(name string) *corev1.ConfigMap {
|
||||||
|
cm := &corev1.ConfigMap{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: "ConfigMap",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"a": "x",
|
||||||
|
"b": "y",
|
||||||
|
"c": "Hello World",
|
||||||
|
"d": "true",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cm.SetLabels(map[string]string{"foo": "bar"})
|
||||||
|
return cm
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConstructConfigMap(t *testing.T) {
|
||||||
|
type testCase struct {
|
||||||
|
description string
|
||||||
|
input types.ConfigMapArgs
|
||||||
|
options *types.GeneratorOptions
|
||||||
|
expected *corev1.ConfigMap
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []testCase{
|
||||||
|
{
|
||||||
|
description: "construct config map from env",
|
||||||
|
input: types.ConfigMapArgs{
|
||||||
|
Name: "envConfigMap",
|
||||||
|
DataSources: types.DataSources{
|
||||||
|
EnvSource: "configmap/app.env",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: nil,
|
||||||
|
expected: makeEnvConfigMap("envConfigMap"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "construct config map from file",
|
||||||
|
input: types.ConfigMapArgs{
|
||||||
|
Name: "fileConfigMap",
|
||||||
|
DataSources: types.DataSources{
|
||||||
|
FileSources: []string{"configmap/app-init.ini"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: nil,
|
||||||
|
expected: makeFileConfigMap("fileConfigMap"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "construct config map from literal",
|
||||||
|
input: types.ConfigMapArgs{
|
||||||
|
Name: "literalConfigMap",
|
||||||
|
DataSources: types.DataSources{
|
||||||
|
LiteralSources: []string{"a=x", "b=y", "c=\"Hello World\"", "d='true'"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: &types.GeneratorOptions{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: makeLiteralConfigMap("literalConfigMap"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fSys := fs.MakeFakeFS()
|
||||||
|
fSys.WriteFile("/configmap/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n"))
|
||||||
|
fSys.WriteFile("/configmap/app-init.ini", []byte("FOO=bar\nBAR=baz\n"))
|
||||||
|
f := NewConfigMapFactory(fSys, loader.NewFileLoaderAtRoot(fSys))
|
||||||
|
for _, tc := range testCases {
|
||||||
|
cm, err := f.MakeConfigMap(&tc.input, tc.options)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(*cm, *tc.expected) {
|
||||||
|
t.Fatalf("in testcase: %q updated:\n%#v\ndoesn't match expected:\n%#v\n", tc.description, *cm, tc.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
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 configmapandsecret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// kvPair represents a key value pair.
|
||||||
|
type kvPair struct {
|
||||||
|
key string
|
||||||
|
value string
|
||||||
|
}
|
||||||
|
|
||||||
|
var utf8bom = []byte{0xEF, 0xBB, 0xBF}
|
||||||
|
|
||||||
|
// keyValuesFromLines parses given content in to a list of key-value pairs.
|
||||||
|
func keyValuesFromLines(content []byte) ([]kvPair, error) {
|
||||||
|
var kvs []kvPair
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(bytes.NewReader(content))
|
||||||
|
currentLine := 0
|
||||||
|
for scanner.Scan() {
|
||||||
|
// Process the current line, retrieving a key/value pair if
|
||||||
|
// possible.
|
||||||
|
scannedBytes := scanner.Bytes()
|
||||||
|
kv, err := kvFromLine(scannedBytes, currentLine)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
currentLine++
|
||||||
|
|
||||||
|
if len(kv.key) == 0 {
|
||||||
|
// no key means line was empty or a comment
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
kvs = append(kvs, kv)
|
||||||
|
}
|
||||||
|
return kvs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// kvFromLine returns a kv with blank key if the line is empty or a comment.
|
||||||
|
// The value will be retrieved from the environment if necessary.
|
||||||
|
func kvFromLine(line []byte, currentLine int) (kvPair, error) {
|
||||||
|
kv := kvPair{}
|
||||||
|
|
||||||
|
if !utf8.Valid(line) {
|
||||||
|
return kv, fmt.Errorf("line %d has invalid utf8 bytes : %v", line, string(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We trim UTF8 BOM from the first line of the file but no others
|
||||||
|
if currentLine == 0 {
|
||||||
|
line = bytes.TrimPrefix(line, utf8bom)
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim the line from all leading whitespace first
|
||||||
|
line = bytes.TrimLeftFunc(line, unicode.IsSpace)
|
||||||
|
|
||||||
|
// If the line is empty or a comment, we return a blank key/value pair.
|
||||||
|
if len(line) == 0 || line[0] == '#' {
|
||||||
|
return kv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
data := strings.SplitN(string(line), "=", 2)
|
||||||
|
key := data[0]
|
||||||
|
if errs := validation.IsEnvVarName(key); len(errs) != 0 {
|
||||||
|
return kv, fmt.Errorf("%q is not a valid key name: %s", key, strings.Join(errs, ";"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) == 2 {
|
||||||
|
kv.value = data[1]
|
||||||
|
} else {
|
||||||
|
// No value (no `=` in the line) is a signal to obtain the value
|
||||||
|
// from the environment.
|
||||||
|
kv.value = os.Getenv(key)
|
||||||
|
}
|
||||||
|
kv.key = key
|
||||||
|
return kv, nil
|
||||||
|
}
|
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
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 configmapandsecret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKeyValuesFromLines(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
desc string
|
||||||
|
content string
|
||||||
|
expectedPairs []kvPair
|
||||||
|
expectedErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "valid kv content parse",
|
||||||
|
content: `
|
||||||
|
k1=v1
|
||||||
|
k2=v2
|
||||||
|
`,
|
||||||
|
expectedPairs: []kvPair{
|
||||||
|
{key: "k1", value: "v1"},
|
||||||
|
{key: "k2", value: "v2"},
|
||||||
|
},
|
||||||
|
expectedErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "content with comments",
|
||||||
|
content: `
|
||||||
|
k1=v1
|
||||||
|
#k2=v2
|
||||||
|
`,
|
||||||
|
expectedPairs: []kvPair{
|
||||||
|
{key: "k1", value: "v1"},
|
||||||
|
},
|
||||||
|
expectedErr: false,
|
||||||
|
},
|
||||||
|
// TODO: add negative testcases
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
pairs, err := keyValuesFromLines([]byte(test.content))
|
||||||
|
if test.expectedErr && err == nil {
|
||||||
|
t.Fatalf("%s should not return error", test.desc)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(pairs, test.expectedPairs) {
|
||||||
|
t.Errorf("%s should succeed, got:%v exptected:%v", test.desc, pairs, test.expectedPairs)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -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 configmapandsecret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultCommandTimeout = 5 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
// SecretFactory makes Secrets.
|
||||||
|
type SecretFactory struct {
|
||||||
|
fSys fs.FileSystem
|
||||||
|
wd string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSecretFactory returns a new SecretFactory.
|
||||||
|
func NewSecretFactory(fSys fs.FileSystem, wd string) *SecretFactory {
|
||||||
|
return &SecretFactory{fSys: fSys, wd: wd}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *SecretFactory) makeFreshSecret(args *types.SecretArgs) *corev1.Secret {
|
||||||
|
s := &corev1.Secret{}
|
||||||
|
s.APIVersion = "v1"
|
||||||
|
s.Kind = "Secret"
|
||||||
|
s.Name = args.Name
|
||||||
|
s.Type = corev1.SecretType(args.Type)
|
||||||
|
if s.Type == "" {
|
||||||
|
s.Type = corev1.SecretTypeOpaque
|
||||||
|
}
|
||||||
|
s.Data = map[string][]byte{}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeSecret returns a new secret.
|
||||||
|
func (f *SecretFactory) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (*corev1.Secret, error) {
|
||||||
|
var all []kvPair
|
||||||
|
var err error
|
||||||
|
s := f.makeFreshSecret(args)
|
||||||
|
|
||||||
|
timeout := defaultCommandTimeout
|
||||||
|
if args.TimeoutSeconds != nil {
|
||||||
|
log.Println("SecretArgs.TimeoutSeconds will be deprected in next release. Please use GeneratorOptions.TimeoutSeconds instread.")
|
||||||
|
timeout = time.Duration(*args.TimeoutSeconds) * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
|
pairs, err := f.keyValuesFromEnvFileCommand(args.EnvCommand, timeout, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||||
|
"env source file: %s",
|
||||||
|
args.EnvCommand))
|
||||||
|
}
|
||||||
|
all = append(all, pairs...)
|
||||||
|
|
||||||
|
pairs, err = f.keyValuesFromCommands(args.Commands, timeout, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, fmt.Sprintf(
|
||||||
|
"commands %v", args.Commands))
|
||||||
|
}
|
||||||
|
all = append(all, pairs...)
|
||||||
|
|
||||||
|
for _, kv := range all {
|
||||||
|
err = addKvToSecret(s, kv.key, kv.value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if options != nil {
|
||||||
|
s.SetLabels(options.Labels)
|
||||||
|
s.SetAnnotations(options.Annotations)
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addKvToSecret(secret *corev1.Secret, keyName, data string) error {
|
||||||
|
// Note, the rules for SecretKeys keys are the exact same as the ones for ConfigMap.
|
||||||
|
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
|
||||||
|
return fmt.Errorf("%q is not a valid key name for a Secret: %s", keyName, strings.Join(errs, ";"))
|
||||||
|
}
|
||||||
|
if _, entryExists := secret.Data[keyName]; entryExists {
|
||||||
|
return fmt.Errorf("cannot add key %s, another key by that name already exists", keyName)
|
||||||
|
}
|
||||||
|
secret.Data[keyName] = []byte(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *SecretFactory) keyValuesFromEnvFileCommand(cmd string, timeout time.Duration, options *types.GeneratorOptions) ([]kvPair, error) {
|
||||||
|
content, err := f.createSecretKey(cmd, timeout, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return keyValuesFromLines(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *SecretFactory) keyValuesFromCommands(sources map[string]string, timeout time.Duration, options *types.GeneratorOptions) ([]kvPair, error) {
|
||||||
|
var kvs []kvPair
|
||||||
|
for k, cmd := range sources {
|
||||||
|
content, err := f.createSecretKey(cmd, timeout, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kvs = append(kvs, kvPair{key: k, value: string(content)})
|
||||||
|
}
|
||||||
|
return kvs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run a command, return its output as the secret.
|
||||||
|
func (f *SecretFactory) createSecretKey(command string, timeout time.Duration, options *types.GeneratorOptions) ([]byte, error) {
|
||||||
|
if !f.fSys.IsDir(f.wd) {
|
||||||
|
f.wd = filepath.Dir(f.wd)
|
||||||
|
if !f.fSys.IsDir(f.wd) {
|
||||||
|
return nil, errors.New("not a directory: " + f.wd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if options != nil && options.TimeoutSeconds != nil {
|
||||||
|
t := time.Duration(*options.TimeoutSeconds) * time.Second
|
||||||
|
if t > timeout {
|
||||||
|
timeout = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var commands []string
|
||||||
|
if options == nil || len(options.Shell) == 0 {
|
||||||
|
commands = []string{"sh", "-c", command}
|
||||||
|
} else {
|
||||||
|
commands = append(options.Shell, command)
|
||||||
|
}
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.CommandContext(ctx, commands[0], commands[1:]...)
|
||||||
|
cmd.Dir = f.wd
|
||||||
|
return cmd.Output()
|
||||||
|
}
|
76
staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/doc.go
Normal file
76
staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/doc.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// It's possible that kustomize's features will be vendored into
|
||||||
|
// the kubernetes/kubernetes repo and made available to kubectl
|
||||||
|
// commands, while at the same time the kustomize program will
|
||||||
|
// continue to exist as an independent CLI. Vendoring snapshots
|
||||||
|
// would be taken just before a kubectl release.
|
||||||
|
//
|
||||||
|
// This creates a problem in that freestanding-kustomize depends on
|
||||||
|
// (for example):
|
||||||
|
//
|
||||||
|
// https://github.com/kubernetes/apimachinery/
|
||||||
|
// tree/master/pkg/util/yaml
|
||||||
|
//
|
||||||
|
// It vendors that package into
|
||||||
|
// sigs.k8s.io/kustomize/vendor/k8s.io/apimachinery/
|
||||||
|
//
|
||||||
|
// Whereas kubectl-kustomize would have to depend on the "staging"
|
||||||
|
// version of this code, located at
|
||||||
|
//
|
||||||
|
// https://github.com/kubernetes/kubernetes/
|
||||||
|
// blob/master/staging/src/k8s.io/apimachinery/pkg/util/yaml
|
||||||
|
//
|
||||||
|
// which is "vendored" via symlinks:
|
||||||
|
// k8s.io/kubernetes/vendor/k8s.io/apimachinery
|
||||||
|
// is a symlink to
|
||||||
|
// ../../staging/src/k8s.io/apimachinery
|
||||||
|
//
|
||||||
|
// The staging version is the canonical, under-development
|
||||||
|
// version of the code that kubectl depends on, whereas the packages
|
||||||
|
// at kubernetes/apimachinery are periodic snapshots of staging made
|
||||||
|
// for outside tools to depend on.
|
||||||
|
//
|
||||||
|
// apimachinery isn't the only package that poses this problem, just
|
||||||
|
// using it as a specific example.
|
||||||
|
//
|
||||||
|
// The kubectl binary cannot vendor in kustomize code that in
|
||||||
|
// turn vendors in the non-staging packages.
|
||||||
|
//
|
||||||
|
// One way to fix some of this would be to copy code - a hard fork.
|
||||||
|
// This has all the problems associated with a hard forking.
|
||||||
|
//
|
||||||
|
// Another way would be to break the kustomize repo into three:
|
||||||
|
//
|
||||||
|
// (1) kustomize - repo with the main() function,
|
||||||
|
// vendoring (2) and (3).
|
||||||
|
//
|
||||||
|
// (2) kustomize-libs - packages used by (1) with no
|
||||||
|
// apimachinery dependence.
|
||||||
|
//
|
||||||
|
// (3) kustomize-k8sdeps - A thin code layer that depends
|
||||||
|
// on (vendors) apimachinery to provide thin implementations
|
||||||
|
// to interfaces used in (2).
|
||||||
|
//
|
||||||
|
// The kubectl repo would then vendor from (2) only, and have
|
||||||
|
// a local implementation of (3). With that in mind, it's clear
|
||||||
|
// that (3) doesn't have to be a repo; the kustomize version of
|
||||||
|
// the thin layer can live directly in (1).
|
||||||
|
//
|
||||||
|
// This package is the code in (3), meant for kustomize.
|
||||||
|
|
||||||
|
package k8sdeps
|
@@ -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 k8sdeps provides kustomize factory with k8s dependencies
|
||||||
|
package k8sdeps
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct"
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer"
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/factory"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewFactory creates an instance of KustFactory using k8sdeps factories
|
||||||
|
func NewFactory() *factory.KustFactory {
|
||||||
|
return factory.NewKustFactory(
|
||||||
|
kunstruct.NewKunstructuredFactoryImpl(),
|
||||||
|
validator.NewKustValidator(),
|
||||||
|
transformer.NewFactoryImpl(),
|
||||||
|
)
|
||||||
|
}
|
@@ -0,0 +1,48 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"factory.go",
|
||||||
|
"helper.go",
|
||||||
|
"kunstruct.go",
|
||||||
|
],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct",
|
||||||
|
importpath = "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/fs: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/types:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = [
|
||||||
|
"factory_test.go",
|
||||||
|
"kunstruct_test.go",
|
||||||
|
],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = ["//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,112 @@
|
|||||||
|
/*
|
||||||
|
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 kunstruct
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
"k8s.io/apimachinery/pkg/util/yaml"
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KunstructuredFactoryImpl hides construction using apimachinery types.
|
||||||
|
type KunstructuredFactoryImpl struct {
|
||||||
|
cmFactory *configmapandsecret.ConfigMapFactory
|
||||||
|
secretFactory *configmapandsecret.SecretFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ifc.KunstructuredFactory = &KunstructuredFactoryImpl{}
|
||||||
|
|
||||||
|
// NewKunstructuredFactoryImpl returns a factory.
|
||||||
|
func NewKunstructuredFactoryImpl() ifc.KunstructuredFactory {
|
||||||
|
return &KunstructuredFactoryImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SliceFromBytes returns a slice of Kunstructured.
|
||||||
|
func (kf *KunstructuredFactoryImpl) SliceFromBytes(
|
||||||
|
in []byte) ([]ifc.Kunstructured, error) {
|
||||||
|
decoder := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(in), 1024)
|
||||||
|
var result []ifc.Kunstructured
|
||||||
|
var err error
|
||||||
|
for err == nil || isEmptyYamlError(err) {
|
||||||
|
var out unstructured.Unstructured
|
||||||
|
err = decoder.Decode(&out)
|
||||||
|
if err == nil {
|
||||||
|
err = kf.validate(out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result = append(result, &UnstructAdapter{Unstructured: out})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != io.EOF {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEmptyYamlError(err error) bool {
|
||||||
|
return strings.Contains(err.Error(), "is missing in 'null'")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromMap returns an instance of Kunstructured.
|
||||||
|
func (kf *KunstructuredFactoryImpl) FromMap(
|
||||||
|
m map[string]interface{}) ifc.Kunstructured {
|
||||||
|
return &UnstructAdapter{Unstructured: unstructured.Unstructured{Object: m}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeConfigMap returns an instance of Kunstructured for ConfigMap
|
||||||
|
func (kf *KunstructuredFactoryImpl) MakeConfigMap(args *types.ConfigMapArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) {
|
||||||
|
cm, err := kf.cmFactory.MakeConfigMap(args, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewKunstructuredFromObject(cm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeSecret returns an instance of Kunstructured for Secret
|
||||||
|
func (kf *KunstructuredFactoryImpl) MakeSecret(args *types.SecretArgs, options *types.GeneratorOptions) (ifc.Kunstructured, error) {
|
||||||
|
sec, err := kf.secretFactory.MakeSecret(args, options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewKunstructuredFromObject(sec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets loader, filesystem and workdirectory
|
||||||
|
func (kf *KunstructuredFactoryImpl) Set(fs fs.FileSystem, ldr ifc.Loader) {
|
||||||
|
kf.cmFactory = configmapandsecret.NewConfigMapFactory(fs, ldr)
|
||||||
|
kf.secretFactory = configmapandsecret.NewSecretFactory(fs, ldr.Root())
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate validates that u has kind and name
|
||||||
|
func (kf *KunstructuredFactoryImpl) validate(u unstructured.Unstructured) error {
|
||||||
|
if u.GetName() == "" {
|
||||||
|
return fmt.Errorf("Missing metadata.name in object %v", u)
|
||||||
|
}
|
||||||
|
if u.GetKind() == "" {
|
||||||
|
return fmt.Errorf("Missing kind in object %v", u)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
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 kunstruct
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSliceFromBytes(t *testing.T) {
|
||||||
|
factory := NewKunstructuredFactoryImpl()
|
||||||
|
testConfigMap := factory.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "ConfigMap",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "winnie",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input []byte
|
||||||
|
expectedOut []ifc.Kunstructured
|
||||||
|
expectedErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "garbage",
|
||||||
|
input: []byte("garbageIn: garbageOut"),
|
||||||
|
expectedOut: []ifc.Kunstructured{},
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "noBytes",
|
||||||
|
input: []byte{},
|
||||||
|
expectedOut: []ifc.Kunstructured{},
|
||||||
|
expectedErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "goodJson",
|
||||||
|
input: []byte(`
|
||||||
|
{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie"}}
|
||||||
|
`),
|
||||||
|
expectedOut: []ifc.Kunstructured{testConfigMap},
|
||||||
|
expectedErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "goodYaml1",
|
||||||
|
input: []byte(`
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: winnie
|
||||||
|
`),
|
||||||
|
expectedOut: []ifc.Kunstructured{testConfigMap},
|
||||||
|
expectedErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "goodYaml2",
|
||||||
|
input: []byte(`
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: winnie
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: winnie
|
||||||
|
`),
|
||||||
|
expectedOut: []ifc.Kunstructured{testConfigMap, testConfigMap},
|
||||||
|
expectedErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "garbageInOneOfTwoObjects",
|
||||||
|
input: []byte(`
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: winnie
|
||||||
|
---
|
||||||
|
WOOOOOOOOOOOOOOOOOOOOOOOOT: woot
|
||||||
|
`),
|
||||||
|
expectedOut: []ifc.Kunstructured{},
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Missing .metadata.name in object",
|
||||||
|
input: []byte(`
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
foo: bar
|
||||||
|
`),
|
||||||
|
expectedOut: nil,
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
rs, err := factory.SliceFromBytes(test.input)
|
||||||
|
if test.expectedErr && err == nil {
|
||||||
|
t.Fatalf("%v: should return error", test.name)
|
||||||
|
}
|
||||||
|
if !test.expectedErr && err != nil {
|
||||||
|
t.Fatalf("%v: unexpected error: %s", test.name, err)
|
||||||
|
}
|
||||||
|
if len(rs) != len(test.expectedOut) {
|
||||||
|
t.Fatalf("%s: length mismatch %d != %d",
|
||||||
|
test.name, len(rs), len(test.expectedOut))
|
||||||
|
}
|
||||||
|
for i := range rs {
|
||||||
|
if !reflect.DeepEqual(test.expectedOut[i], rs[i]) {
|
||||||
|
t.Fatalf("%s: Got: %v\nexpected:%v",
|
||||||
|
test.name, test.expectedOut[i], rs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
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 kunstruct provides unstructured from api machinery and factory for creating unstructured
|
||||||
|
package kunstruct
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseFields(path string) ([]string, error) {
|
||||||
|
if !strings.Contains(path, "[") {
|
||||||
|
return strings.Split(path, "."), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var fields []string
|
||||||
|
start := 0
|
||||||
|
insideParentheses := false
|
||||||
|
for i := range path {
|
||||||
|
switch path[i] {
|
||||||
|
case '.':
|
||||||
|
if !insideParentheses {
|
||||||
|
fields = append(fields, path[start:i])
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
case '[':
|
||||||
|
if !insideParentheses {
|
||||||
|
if i == start {
|
||||||
|
start = i + 1
|
||||||
|
} else {
|
||||||
|
fields = append(fields, path[start:i])
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
insideParentheses = true
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("nested parentheses are not allowed: %s", path)
|
||||||
|
}
|
||||||
|
case ']':
|
||||||
|
if insideParentheses {
|
||||||
|
fields = append(fields, path[start:i])
|
||||||
|
start = i + 1
|
||||||
|
insideParentheses = false
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("Invalid field path %s", path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if start < len(path)-1 {
|
||||||
|
fields = append(fields, path[start:])
|
||||||
|
}
|
||||||
|
for i, f := range fields {
|
||||||
|
if strings.HasPrefix(f, "\"") || strings.HasPrefix(f, "'") {
|
||||||
|
fields[i] = strings.Trim(f, "\"'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields, nil
|
||||||
|
}
|
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
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 kunstruct provides unstructured from api machinery and factory for creating unstructured
|
||||||
|
package kunstruct
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ ifc.Kunstructured = &UnstructAdapter{}
|
||||||
|
|
||||||
|
// UnstructAdapter wraps unstructured.Unstructured from
|
||||||
|
// https://github.com/kubernetes/apimachinery/blob/master/
|
||||||
|
// pkg/apis/meta/v1/unstructured/unstructured.go
|
||||||
|
// to isolate dependence on apimachinery.
|
||||||
|
type UnstructAdapter struct {
|
||||||
|
unstructured.Unstructured
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKunstructuredFromObject returns a new instance of Kunstructured.
|
||||||
|
func NewKunstructuredFromObject(obj runtime.Object) (ifc.Kunstructured, error) {
|
||||||
|
// Convert obj to a byte stream, then convert that to JSON (Unstructured).
|
||||||
|
marshaled, err := json.Marshal(obj)
|
||||||
|
if err != nil {
|
||||||
|
return &UnstructAdapter{}, err
|
||||||
|
}
|
||||||
|
var u unstructured.Unstructured
|
||||||
|
err = u.UnmarshalJSON(marshaled)
|
||||||
|
// creationTimestamp always 'null', remove it
|
||||||
|
u.SetCreationTimestamp(metav1.Time{})
|
||||||
|
return &UnstructAdapter{Unstructured: u}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGvk returns the Gvk name of the object.
|
||||||
|
func (fs *UnstructAdapter) GetGvk() gvk.Gvk {
|
||||||
|
x := fs.GroupVersionKind()
|
||||||
|
return gvk.Gvk{
|
||||||
|
Group: x.Group,
|
||||||
|
Version: x.Version,
|
||||||
|
Kind: x.Kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy provides a copy behind an interface.
|
||||||
|
func (fs *UnstructAdapter) Copy() ifc.Kunstructured {
|
||||||
|
return &UnstructAdapter{*fs.DeepCopy()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map returns the unstructured content map.
|
||||||
|
func (fs *UnstructAdapter) Map() map[string]interface{} {
|
||||||
|
return fs.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMap overrides the unstructured content map.
|
||||||
|
func (fs *UnstructAdapter) SetMap(m map[string]interface{}) {
|
||||||
|
fs.Object = m
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFieldValue returns value at the given fieldpath.
|
||||||
|
func (fs *UnstructAdapter) GetFieldValue(path string) (string, error) {
|
||||||
|
fields, err := parseFields(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
s, found, err := unstructured.NestedString(
|
||||||
|
fs.UnstructuredContent(), fields...)
|
||||||
|
if found || err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("no field named '%s'", path)
|
||||||
|
}
|
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
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 kunstruct
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetFieldValue(t *testing.T) {
|
||||||
|
factory := NewKunstructuredFactoryImpl()
|
||||||
|
kunstructured := factory.FromMap(map[string]interface{}{
|
||||||
|
"Kind": "Service",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]string{
|
||||||
|
"app": "application-name",
|
||||||
|
},
|
||||||
|
"name": "service-name",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"ports": map[string]interface{}{
|
||||||
|
"port": "80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"this": map[string]interface{}{
|
||||||
|
"is": map[string]interface{}{
|
||||||
|
"aNumber": 1000,
|
||||||
|
"aNilValue": nil,
|
||||||
|
"anEmptyMap": map[string]interface{}{},
|
||||||
|
"unrecognizable": testing.InternalExample{
|
||||||
|
Name: "fooBar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
pathToField string
|
||||||
|
expectedValue string
|
||||||
|
errorExpected bool
|
||||||
|
errorMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "oneField",
|
||||||
|
pathToField: "Kind",
|
||||||
|
expectedValue: "Service",
|
||||||
|
errorExpected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "twoFields",
|
||||||
|
pathToField: "metadata.name",
|
||||||
|
expectedValue: "service-name",
|
||||||
|
errorExpected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "threeFields",
|
||||||
|
pathToField: "spec.ports.port",
|
||||||
|
expectedValue: "80",
|
||||||
|
errorExpected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
pathToField: "",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: "no field named ''",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "emptyDotEmpty",
|
||||||
|
pathToField: ".",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: "no field named '.'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "twoFieldsOneMissing",
|
||||||
|
pathToField: "metadata.banana",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: "no field named 'metadata.banana'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deeperMissingField",
|
||||||
|
pathToField: "this.is.aDeep.field.that.does.not.exist",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: "no field named 'this.is.aDeep.field.that.does.not.exist'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "emptyMap",
|
||||||
|
pathToField: "this.is.anEmptyMap",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: ".this.is.anEmptyMap accessor error: map[] is of the type map[string]interface {}, expected string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "numberAsValue",
|
||||||
|
pathToField: "this.is.aNumber",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: ".this.is.aNumber accessor error: 1000 is of the type int, expected string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nilAsValue",
|
||||||
|
pathToField: "this.is.aNilValue",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: ".this.is.aNilValue accessor error: <nil> is of the type <nil>, expected string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unrecognizable",
|
||||||
|
pathToField: "this.is.unrecognizable.Name",
|
||||||
|
errorExpected: true,
|
||||||
|
errorMsg: ".this.is.unrecognizable.Name accessor error: {fooBar <nil> false} is of the type testing.InternalExample, expected map[string]interface{}",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
s, err := kunstructured.GetFieldValue(test.pathToField)
|
||||||
|
if test.errorExpected {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("%q; path %q - should return error, but no error returned",
|
||||||
|
test.name, test.pathToField)
|
||||||
|
}
|
||||||
|
if test.errorMsg != err.Error() {
|
||||||
|
t.Fatalf("%q; path %q - expected error: \"%s\", got error: \"%v\"",
|
||||||
|
test.name, test.pathToField, test.errorMsg, err.Error())
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%q; path %q - unexpected error %v",
|
||||||
|
test.name, test.pathToField, err)
|
||||||
|
}
|
||||||
|
if test.expectedValue != s {
|
||||||
|
t.Fatalf("%q; Got: %s expected: %s",
|
||||||
|
test.name, s, test.expectedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,33 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["factory.go"],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer",
|
||||||
|
importpath = "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash:go_default_library",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch: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",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash:all-srcs",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch:all-srcs",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
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 provides transformer factory
|
||||||
|
package transformer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash"
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FactoryImpl makes patch transformer and name hash transformer
|
||||||
|
type FactoryImpl struct{}
|
||||||
|
|
||||||
|
// NewFactoryImpl makes a new factoryImpl instance
|
||||||
|
func NewFactoryImpl() *FactoryImpl {
|
||||||
|
return &FactoryImpl{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakePatchTransformer makes a new patch transformer
|
||||||
|
func (p *FactoryImpl) MakePatchTransformer(slice []*resource.Resource, rf *resource.Factory) (transformers.Transformer, error) {
|
||||||
|
return patch.NewPatchTransformer(slice, rf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeHashTransformer makes a new name hash transformer
|
||||||
|
func (p *FactoryImpl) MakeHashTransformer() transformers.Transformer {
|
||||||
|
return hash.NewNameHashTransformer()
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"hash.go",
|
||||||
|
"namehash.go",
|
||||||
|
],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash",
|
||||||
|
importpath = "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/resmap:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/transformers:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = [
|
||||||
|
"hash_test.go",
|
||||||
|
"namehash_test.go",
|
||||||
|
],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct: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/resid: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,168 @@
|
|||||||
|
/*
|
||||||
|
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 hash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KustHash compute hash for unstructured objects
|
||||||
|
type KustHash struct{}
|
||||||
|
|
||||||
|
// NewKustHash returns a KustHash object
|
||||||
|
func NewKustHash() *KustHash {
|
||||||
|
return &KustHash{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash returns a hash of either a ConfigMap or a Secret
|
||||||
|
func (h *KustHash) Hash(m map[string]interface{}) (string, error) {
|
||||||
|
u := unstructured.Unstructured{
|
||||||
|
Object: m,
|
||||||
|
}
|
||||||
|
kind := u.GetKind()
|
||||||
|
switch kind {
|
||||||
|
case "ConfigMap":
|
||||||
|
cm, err := unstructuredToConfigmap(u)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return ConfigMapHash(cm)
|
||||||
|
case "Secret":
|
||||||
|
sec, err := unstructuredToSecret(u)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return SecretHash(sec)
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("type %s is supported for hashing in %v", kind, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigMapHash returns a hash of the ConfigMap.
|
||||||
|
// The Data, Kind, and Name are taken into account.
|
||||||
|
func ConfigMapHash(cm *v1.ConfigMap) (string, error) {
|
||||||
|
encoded, err := encodeConfigMap(cm)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
h, err := encodeHash(hash(encoded))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return h, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretHash returns a hash of the Secret.
|
||||||
|
// The Data, Kind, Name, and Type are taken into account.
|
||||||
|
func SecretHash(sec *v1.Secret) (string, error) {
|
||||||
|
encoded, err := encodeSecret(sec)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
h, err := encodeHash(hash(encoded))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return h, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeConfigMap encodes a ConfigMap.
|
||||||
|
// Data, Kind, and Name are taken into account.
|
||||||
|
func encodeConfigMap(cm *v1.ConfigMap) (string, error) {
|
||||||
|
// json.Marshal sorts the keys in a stable order in the encoding
|
||||||
|
m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, "data": cm.Data}
|
||||||
|
if len(cm.BinaryData) > 0 {
|
||||||
|
m["binaryData"] = cm.BinaryData
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(m)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeSecret encodes a Secret.
|
||||||
|
// Data, Kind, Name, and Type are taken into account.
|
||||||
|
func encodeSecret(sec *v1.Secret) (string, error) {
|
||||||
|
// json.Marshal sorts the keys in a stable order in the encoding
|
||||||
|
data, err := json.Marshal(map[string]interface{}{"kind": "Secret", "type": sec.Type, "name": sec.Name, "data": sec.Data})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeHash extracts the first 40 bits of the hash from the hex string
|
||||||
|
// (1 hex char represents 4 bits), and then maps vowels and vowel-like hex
|
||||||
|
// characters to consonants to prevent bad words from being formed (the theory
|
||||||
|
// is that no vowels makes it really hard to make bad words). Since the string
|
||||||
|
// is hex, the only vowels it can contain are 'a' and 'e'.
|
||||||
|
// We picked some arbitrary consonants to map to from the same character set as GenerateName.
|
||||||
|
// See: https://github.com/kubernetes/apimachinery/blob/dc1f89aff9a7509782bde3b68824c8043a3e58cc/pkg/util/rand/rand.go#L75
|
||||||
|
// If the hex string contains fewer than ten characters, returns an error.
|
||||||
|
func encodeHash(hex string) (string, error) {
|
||||||
|
if len(hex) < 10 {
|
||||||
|
return "", fmt.Errorf("the hex string must contain at least 10 characters")
|
||||||
|
}
|
||||||
|
enc := []rune(hex[:10])
|
||||||
|
for i := range enc {
|
||||||
|
switch enc[i] {
|
||||||
|
case '0':
|
||||||
|
enc[i] = 'g'
|
||||||
|
case '1':
|
||||||
|
enc[i] = 'h'
|
||||||
|
case '3':
|
||||||
|
enc[i] = 'k'
|
||||||
|
case 'a':
|
||||||
|
enc[i] = 'm'
|
||||||
|
case 'e':
|
||||||
|
enc[i] = 't'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(enc), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// hash hashes `data` with sha256 and returns the hex string
|
||||||
|
func hash(data string) string {
|
||||||
|
return fmt.Sprintf("%x", sha256.Sum256([]byte(data)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func unstructuredToConfigmap(u unstructured.Unstructured) (*v1.ConfigMap, error) {
|
||||||
|
marshaled, err := json.Marshal(u.Object)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var out v1.ConfigMap
|
||||||
|
err = json.Unmarshal(marshaled, &out)
|
||||||
|
return &out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func unstructuredToSecret(u unstructured.Unstructured) (*v1.Secret, error) {
|
||||||
|
marshaled, err := json.Marshal(u.Object)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var out v1.Secret
|
||||||
|
err = json.Unmarshal(marshaled, &out)
|
||||||
|
return &out, err
|
||||||
|
}
|
@@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
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 hash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||||
|
)
|
||||||
|
|
||||||
|
var service = gvk.Gvk{Version: "v1", Kind: "Service"}
|
||||||
|
var secret = gvk.Gvk{Version: "v1", Kind: "Secret"}
|
||||||
|
var cmap = gvk.Gvk{Version: "v1", Kind: "ConfigMap"}
|
||||||
|
var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}
|
||||||
|
|
||||||
|
func TestConfigMapHash(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
desc string
|
||||||
|
cm *v1.ConfigMap
|
||||||
|
hash string
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
// empty map
|
||||||
|
{"empty data", &v1.ConfigMap{Data: map[string]string{}, BinaryData: map[string][]byte{}}, "42745tchd9", ""},
|
||||||
|
// one key
|
||||||
|
{"one key", &v1.ConfigMap{Data: map[string]string{"one": ""}}, "9g67k2htb6", ""},
|
||||||
|
// three keys (tests sorting order)
|
||||||
|
{"three keys", &v1.ConfigMap{Data: map[string]string{"two": "2", "one": "", "three": "3"}}, "f5h7t85m9b", ""},
|
||||||
|
// empty binary data map
|
||||||
|
{"empty binary data", &v1.ConfigMap{BinaryData: map[string][]byte{}}, "dk855m5d49", ""},
|
||||||
|
// one key with binary data
|
||||||
|
{"one key with binary data", &v1.ConfigMap{BinaryData: map[string][]byte{"one": []byte("")}}, "mk79584b8c", ""},
|
||||||
|
// three keys with binary data (tests sorting order)
|
||||||
|
{"three keys with binary data", &v1.ConfigMap{BinaryData: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "t458mc6db2", ""},
|
||||||
|
// two keys, one with string and another with binary data
|
||||||
|
{"two keys with one each", &v1.ConfigMap{Data: map[string]string{"one": ""}, BinaryData: map[string][]byte{"two": []byte("")}}, "698h7c7t9m", ""},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
h, err := ConfigMapHash(c.cm)
|
||||||
|
if SkipRest(t, c.desc, err, c.err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if c.hash != h {
|
||||||
|
t.Errorf("case %q, expect hash %q but got %q", c.desc, c.hash, h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSecretHash(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
desc string
|
||||||
|
secret *v1.Secret
|
||||||
|
hash string
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
// empty map
|
||||||
|
{"empty data", &v1.Secret{Type: "my-type", Data: map[string][]byte{}}, "t75bgf6ctb", ""},
|
||||||
|
// one key
|
||||||
|
{"one key", &v1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}}, "74bd68bm66", ""},
|
||||||
|
// three keys (tests sorting order)
|
||||||
|
{"three keys", &v1.Secret{Type: "my-type", Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "dgcb6h9tmk", ""},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
h, err := SecretHash(c.secret)
|
||||||
|
if SkipRest(t, c.desc, err, c.err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if c.hash != h {
|
||||||
|
t.Errorf("case %q, expect hash %q but got %q", c.desc, c.hash, h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncodeConfigMap(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
desc string
|
||||||
|
cm *v1.ConfigMap
|
||||||
|
expect string
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
// empty map
|
||||||
|
{"empty data", &v1.ConfigMap{Data: map[string]string{}}, `{"data":{},"kind":"ConfigMap","name":""}`, ""},
|
||||||
|
// one key
|
||||||
|
{"one key", &v1.ConfigMap{Data: map[string]string{"one": ""}}, `{"data":{"one":""},"kind":"ConfigMap","name":""}`, ""},
|
||||||
|
// three keys (tests sorting order)
|
||||||
|
{"three keys", &v1.ConfigMap{Data: map[string]string{"two": "2", "one": "", "three": "3"}},
|
||||||
|
`{"data":{"one":"","three":"3","two":"2"},"kind":"ConfigMap","name":""}`, ""},
|
||||||
|
// empty binary map
|
||||||
|
{"empty data", &v1.ConfigMap{BinaryData: map[string][]byte{}}, `{"data":null,"kind":"ConfigMap","name":""}`, ""},
|
||||||
|
// one key with binary data
|
||||||
|
{"one key", &v1.ConfigMap{BinaryData: map[string][]byte{"one": []byte("")}},
|
||||||
|
`{"binaryData":{"one":""},"data":null,"kind":"ConfigMap","name":""}`, ""},
|
||||||
|
// three keys with binary data (tests sorting order)
|
||||||
|
{"three keys", &v1.ConfigMap{BinaryData: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}},
|
||||||
|
`{"binaryData":{"one":"","three":"Mw==","two":"Mg=="},"data":null,"kind":"ConfigMap","name":""}`, ""},
|
||||||
|
// two keys, one string and one binary values
|
||||||
|
{"two keys with one each", &v1.ConfigMap{Data: map[string]string{"one": ""}, BinaryData: map[string][]byte{"two": []byte("")}},
|
||||||
|
`{"binaryData":{"two":""},"data":{"one":""},"kind":"ConfigMap","name":""}`, ""},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
s, err := encodeConfigMap(c.cm)
|
||||||
|
if SkipRest(t, c.desc, err, c.err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s != c.expect {
|
||||||
|
t.Errorf("case %q, expect %q but got %q from encode %#v", c.desc, c.expect, s, c.cm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncodeSecret(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
desc string
|
||||||
|
secret *v1.Secret
|
||||||
|
expect string
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
// empty map
|
||||||
|
{"empty data", &v1.Secret{Type: "my-type", Data: map[string][]byte{}}, `{"data":{},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
||||||
|
// one key
|
||||||
|
{"one key", &v1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}}, `{"data":{"one":""},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
||||||
|
// three keys (tests sorting order) - note json.Marshal base64 encodes the values because they come in as []byte
|
||||||
|
{"three keys", &v1.Secret{
|
||||||
|
Type: "my-type",
|
||||||
|
Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")},
|
||||||
|
},
|
||||||
|
`{"data":{"one":"","three":"Mw==","two":"Mg=="},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
s, err := encodeSecret(c.secret)
|
||||||
|
if SkipRest(t, c.desc, err, c.err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s != c.expect {
|
||||||
|
t.Errorf("case %q, expect %q but got %q from encode %#v", c.desc, c.expect, s, c.secret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHash(t *testing.T) {
|
||||||
|
// hash the empty string to be sure that sha256 is being used
|
||||||
|
expect := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||||
|
sum := hash("")
|
||||||
|
if expect != sum {
|
||||||
|
t.Errorf("expected hash %q but got %q", expect, sum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// warn devs who change types that they might have to update a hash function
|
||||||
|
// not perfect, as it only checks the number of top-level fields
|
||||||
|
func TestTypeStability(t *testing.T) {
|
||||||
|
errfmt := `case %q, expected %d fields but got %d
|
||||||
|
Depending on the field(s) you added, you may need to modify the hash function for this type.
|
||||||
|
To guide you: the hash function targets fields that comprise the contents of objects,
|
||||||
|
not their metadata (e.g. the Data of a ConfigMap, but nothing in ObjectMeta).
|
||||||
|
`
|
||||||
|
cases := []struct {
|
||||||
|
typeName string
|
||||||
|
obj interface{}
|
||||||
|
expect int
|
||||||
|
}{
|
||||||
|
{"ConfigMap", v1.ConfigMap{}, 4},
|
||||||
|
{"Secret", v1.Secret{}, 5},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
val := reflect.ValueOf(c.obj)
|
||||||
|
if num := val.NumField(); c.expect != num {
|
||||||
|
t.Errorf(errfmt, c.typeName, c.expect, num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkipRest returns true if there was a non-nil error or if we expected an error that didn't happen,
|
||||||
|
// and logs the appropriate error on the test object.
|
||||||
|
// The return value indicates whether we should skip the rest of the test case due to the error result.
|
||||||
|
func SkipRest(t *testing.T, desc string, err error, contains string) bool {
|
||||||
|
if err != nil {
|
||||||
|
if len(contains) == 0 {
|
||||||
|
t.Errorf("case %q, expect nil error but got %q", desc, err.Error())
|
||||||
|
} else if !strings.Contains(err.Error(), contains) {
|
||||||
|
t.Errorf("case %q, expect error to contain %q but got %q", desc, contains, err.Error())
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else if len(contains) > 0 {
|
||||||
|
t.Errorf("case %q, expect error to contain %q but got nil error", desc, contains)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
@@ -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 hash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||||
|
)
|
||||||
|
|
||||||
|
type nameHashTransformer struct{}
|
||||||
|
|
||||||
|
var _ transformers.Transformer = &nameHashTransformer{}
|
||||||
|
|
||||||
|
// NewNameHashTransformer construct a nameHashTransformer.
|
||||||
|
func NewNameHashTransformer() transformers.Transformer {
|
||||||
|
return &nameHashTransformer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform appends hash to generated resources.
|
||||||
|
func (o *nameHashTransformer) Transform(m resmap.ResMap) error {
|
||||||
|
for _, res := range m {
|
||||||
|
if res.IsGenerated() {
|
||||||
|
h, err := NewKustHash().Hash(res.Map())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res.SetName(fmt.Sprintf("%s-%s", res.GetName(), h))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@@ -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 hash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resid"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNameHashTransformer(t *testing.T) {
|
||||||
|
rf := resource.NewFactory(
|
||||||
|
kunstruct.NewKunstructuredFactoryImpl())
|
||||||
|
objs := resmap.ResMap{
|
||||||
|
resid.NewResId(cmap, "cm1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "ConfigMap",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "cm1",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
resid.NewResId(deploy, "deploy1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"group": "apps",
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"old-label": "old-value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:1.7.9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
resid.NewResId(service, "svc1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Service",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "svc1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"ports": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "port1",
|
||||||
|
"port": "12345",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
resid.NewResId(secret, "secret1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Secret",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "secret1",
|
||||||
|
},
|
||||||
|
}).SetBehavior(ifc.BehaviorCreate),
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := resmap.ResMap{
|
||||||
|
resid.NewResId(cmap, "cm1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "ConfigMap",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "cm1",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
resid.NewResId(deploy, "deploy1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"group": "apps",
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"old-label": "old-value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:1.7.9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
resid.NewResId(service, "svc1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Service",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "svc1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"ports": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "port1",
|
||||||
|
"port": "12345",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
resid.NewResId(secret, "secret1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Secret",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "secret1-7kc45hd5f7",
|
||||||
|
},
|
||||||
|
}).SetBehavior(ifc.BehaviorCreate),
|
||||||
|
}
|
||||||
|
|
||||||
|
tran := NewNameHashTransformer()
|
||||||
|
tran.Transform(objs)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(objs, expected) {
|
||||||
|
err := expected.ErrorIfNotEqual(objs)
|
||||||
|
t.Fatalf("actual doesn't match expected: %v", err)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,51 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"patch.go",
|
||||||
|
"patchconflictdetector.go",
|
||||||
|
],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch",
|
||||||
|
importpath = "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/mergepatch:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||||
|
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/gvk: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",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["patch_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/gvk: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",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
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,174 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/evanphx/json-patch"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||||
|
)
|
||||||
|
|
||||||
|
// patchTransformer applies patches.
|
||||||
|
type patchTransformer struct {
|
||||||
|
patches []*resource.Resource
|
||||||
|
rf *resource.Factory
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ transformers.Transformer = &patchTransformer{}
|
||||||
|
|
||||||
|
// NewPatchTransformer constructs a patchTransformer.
|
||||||
|
func NewPatchTransformer(
|
||||||
|
slice []*resource.Resource, rf *resource.Factory) (transformers.Transformer, error) {
|
||||||
|
if len(slice) == 0 {
|
||||||
|
return transformers.NewNoOpTransformer(), nil
|
||||||
|
}
|
||||||
|
return &patchTransformer{patches: slice, rf: rf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform apply the patches on top of the base resources.
|
||||||
|
func (pt *patchTransformer) Transform(baseResourceMap resmap.ResMap) error {
|
||||||
|
// Merge and then index the patches by Id.
|
||||||
|
patches, err := pt.mergePatches()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategic merge the resources exist in both base and patches.
|
||||||
|
for _, patch := range patches {
|
||||||
|
// Merge patches with base resource.
|
||||||
|
id := patch.Id()
|
||||||
|
matchedIds := baseResourceMap.FindByGVKN(id)
|
||||||
|
if len(matchedIds) == 0 {
|
||||||
|
return fmt.Errorf("failed to find an object with %#v to apply the patch", id.Gvk())
|
||||||
|
}
|
||||||
|
if len(matchedIds) > 1 {
|
||||||
|
return fmt.Errorf("found multiple objects %#v targeted by patch %#v (ambiguous)", matchedIds, id)
|
||||||
|
}
|
||||||
|
id = matchedIds[0]
|
||||||
|
base := baseResourceMap[id]
|
||||||
|
merged := map[string]interface{}{}
|
||||||
|
versionedObj, err := scheme.Scheme.New(toSchemaGvk(id.Gvk()))
|
||||||
|
baseName := base.GetName()
|
||||||
|
switch {
|
||||||
|
case runtime.IsNotRegisteredError(err):
|
||||||
|
// Use JSON merge patch to handle types w/o schema
|
||||||
|
baseBytes, err := json.Marshal(base.Map())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
patchBytes, err := json.Marshal(patch.Map())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mergedBytes, err := jsonpatch.MergePatch(baseBytes, patchBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(mergedBytes, &merged)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
// Use Strategic-Merge-Patch to handle types w/ schema
|
||||||
|
// TODO: Change this to use the new Merge package.
|
||||||
|
// Store the name of the base object, because this name may have been munged.
|
||||||
|
// Apply this name to the patched object.
|
||||||
|
lookupPatchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
merged, err = strategicpatch.StrategicMergeMapPatchUsingLookupPatchMeta(
|
||||||
|
base.Map(),
|
||||||
|
patch.Map(),
|
||||||
|
lookupPatchMeta)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.SetName(baseName)
|
||||||
|
baseResourceMap[id].SetMap(merged)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// mergePatches merge and index patches by Id.
|
||||||
|
// It errors out if there is conflict between patches.
|
||||||
|
func (pt *patchTransformer) mergePatches() (resmap.ResMap, error) {
|
||||||
|
rc := resmap.ResMap{}
|
||||||
|
for ix, patch := range pt.patches {
|
||||||
|
id := patch.Id()
|
||||||
|
existing, found := rc[id]
|
||||||
|
if !found {
|
||||||
|
rc[id] = patch
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
versionedObj, err := scheme.Scheme.New(toSchemaGvk(id.Gvk()))
|
||||||
|
if err != nil && !runtime.IsNotRegisteredError(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var cd conflictDetector
|
||||||
|
if err != nil {
|
||||||
|
cd = newJMPConflictDetector(pt.rf)
|
||||||
|
} else {
|
||||||
|
cd, err = newSMPConflictDetector(versionedObj, pt.rf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conflict, err := cd.hasConflict(existing, patch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if conflict {
|
||||||
|
conflictingPatch, err := cd.findConflict(ix, pt.patches)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"conflict between %#v and %#v",
|
||||||
|
conflictingPatch.Map(), patch.Map())
|
||||||
|
}
|
||||||
|
merged, err := cd.mergePatches(existing, patch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rc[id] = merged
|
||||||
|
}
|
||||||
|
return rc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toSchemaGvk converts to a schema.GroupVersionKind.
|
||||||
|
func toSchemaGvk(x gvk.Gvk) schema.GroupVersionKind {
|
||||||
|
return schema.GroupVersionKind{
|
||||||
|
Group: x.Group,
|
||||||
|
Version: x.Version,
|
||||||
|
Kind: x.Kind,
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,563 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resid"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resmap"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
var rf = resource.NewFactory(
|
||||||
|
kunstruct.NewKunstructuredFactoryImpl())
|
||||||
|
var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}
|
||||||
|
var foo = gvk.Gvk{Group: "example.com", Version: "v1", Kind: "Foo"}
|
||||||
|
|
||||||
|
func TestOverlayRun(t *testing.T) {
|
||||||
|
base := resmap.ResMap{
|
||||||
|
resid.NewResId(deploy, "deploy1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"old-label": "old-value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
patch := []*resource.Resource{
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"another-label": "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:latest",
|
||||||
|
"env": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "SOMEENV",
|
||||||
|
"value": "BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
expected := resmap.ResMap{
|
||||||
|
resid.NewResId(deploy, "deploy1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"old-label": "old-value",
|
||||||
|
"another-label": "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:latest",
|
||||||
|
"env": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "SOMEENV",
|
||||||
|
"value": "BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
lt, err := NewPatchTransformer(patch, rf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
err = lt.Transform(base)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(base, expected) {
|
||||||
|
err = expected.ErrorIfNotEqual(base)
|
||||||
|
t.Fatalf("actual doesn't match expected: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultiplePatches(t *testing.T) {
|
||||||
|
base := resmap.ResMap{
|
||||||
|
resid.NewResId(deploy, "deploy1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
patch := []*resource.Resource{
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:latest",
|
||||||
|
"env": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "SOMEENV",
|
||||||
|
"value": "BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"env": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "ANOTHERENV",
|
||||||
|
"value": "HELLO",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "busybox",
|
||||||
|
"image": "busybox",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
expected := resmap.ResMap{
|
||||||
|
resid.NewResId(deploy, "deploy1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:latest",
|
||||||
|
"env": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "ANOTHERENV",
|
||||||
|
"value": "HELLO",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "SOMEENV",
|
||||||
|
"value": "BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "busybox",
|
||||||
|
"image": "busybox",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
lt, err := NewPatchTransformer(patch, rf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
err = lt.Transform(base)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(base, expected) {
|
||||||
|
err = expected.ErrorIfNotEqual(base)
|
||||||
|
t.Fatalf("actual doesn't match expected: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultiplePatchesWithConflict(t *testing.T) {
|
||||||
|
base := resmap.ResMap{
|
||||||
|
resid.NewResId(deploy, "deploy1"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
patch := []*resource.Resource{
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:latest",
|
||||||
|
"env": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "SOMEENV",
|
||||||
|
"value": "BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "deploy1",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"containers": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": "nginx",
|
||||||
|
"image": "nginx:1.7.9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
lt, err := NewPatchTransformer(patch, rf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
err = lt.Transform(base)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("did not get expected error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "conflict") {
|
||||||
|
t.Fatalf("expected error to contain %q but get %v", "conflict", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoSchemaOverlayRun(t *testing.T) {
|
||||||
|
base := resmap.ResMap{
|
||||||
|
resid.NewResId(foo, "my-foo"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"A": "X",
|
||||||
|
"B": "Y",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
patch := []*resource.Resource{
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"B": nil,
|
||||||
|
"C": "Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
expected := resmap.ResMap{
|
||||||
|
resid.NewResId(foo, "my-foo"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"A": "X",
|
||||||
|
"C": "Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
lt, err := NewPatchTransformer(patch, rf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
err = lt.Transform(base)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if err = expected.ErrorIfNotEqual(base); err != nil {
|
||||||
|
t.Fatalf("actual doesn't match expected: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoSchemaMultiplePatches(t *testing.T) {
|
||||||
|
base := resmap.ResMap{
|
||||||
|
resid.NewResId(foo, "my-foo"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"A": "X",
|
||||||
|
"B": "Y",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
patch := []*resource.Resource{
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"B": nil,
|
||||||
|
"C": "Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"C": "Z",
|
||||||
|
"D": "W",
|
||||||
|
},
|
||||||
|
"baz": map[string]interface{}{
|
||||||
|
"hello": "world",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
expected := resmap.ResMap{
|
||||||
|
resid.NewResId(foo, "my-foo"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"A": "X",
|
||||||
|
"C": "Z",
|
||||||
|
"D": "W",
|
||||||
|
},
|
||||||
|
"baz": map[string]interface{}{
|
||||||
|
"hello": "world",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
lt, err := NewPatchTransformer(patch, rf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
err = lt.Transform(base)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if err = expected.ErrorIfNotEqual(base); err != nil {
|
||||||
|
t.Fatalf("actual doesn't match expected: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoSchemaMultiplePatchesWithConflict(t *testing.T) {
|
||||||
|
base := resmap.ResMap{
|
||||||
|
resid.NewResId(foo, "my-foo"): rf.FromMap(
|
||||||
|
map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"A": "X",
|
||||||
|
"B": "Y",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
patch := []*resource.Resource{
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"B": nil,
|
||||||
|
"C": "Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
rf.FromMap(map[string]interface{}{
|
||||||
|
"apiVersion": "example.com/v1",
|
||||||
|
"kind": "Foo",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "my-foo",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"C": "NOT_Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
lt, err := NewPatchTransformer(patch, rf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
err = lt.Transform(base)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("did not get expected error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "conflict") {
|
||||||
|
t.Fatalf("expected error to contain %q but get %v", "conflict", err)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/evanphx/json-patch"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||||
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
type conflictDetector interface {
|
||||||
|
hasConflict(patch1, patch2 *resource.Resource) (bool, error)
|
||||||
|
findConflict(conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error)
|
||||||
|
mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type jsonMergePatch struct {
|
||||||
|
rf *resource.Factory
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ conflictDetector = &jsonMergePatch{}
|
||||||
|
|
||||||
|
func newJMPConflictDetector(rf *resource.Factory) conflictDetector {
|
||||||
|
return &jsonMergePatch{rf: rf}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (jmp *jsonMergePatch) hasConflict(
|
||||||
|
patch1, patch2 *resource.Resource) (bool, error) {
|
||||||
|
return mergepatch.HasConflicts(patch1.Map(), patch2.Map())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (jmp *jsonMergePatch) findConflict(
|
||||||
|
conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error) {
|
||||||
|
for i, patch := range patches {
|
||||||
|
if i == conflictingPatchIdx {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !patches[conflictingPatchIdx].Id().GvknEquals(patch.Id()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
conflict, err := mergepatch.HasConflicts(
|
||||||
|
patch.Map(),
|
||||||
|
patches[conflictingPatchIdx].Map())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if conflict {
|
||||||
|
return patch, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (jmp *jsonMergePatch) mergePatches(
|
||||||
|
patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
||||||
|
baseBytes, err := json.Marshal(patch1.Map())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
patchBytes, err := json.Marshal(patch2.Map())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mergedBytes, err := jsonpatch.MergeMergePatches(baseBytes, patchBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mergedMap := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(mergedBytes, &mergedMap)
|
||||||
|
return jmp.rf.FromMap(mergedMap), err
|
||||||
|
}
|
||||||
|
|
||||||
|
type strategicMergePatch struct {
|
||||||
|
lookupPatchMeta strategicpatch.LookupPatchMeta
|
||||||
|
rf *resource.Factory
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ conflictDetector = &strategicMergePatch{}
|
||||||
|
|
||||||
|
func newSMPConflictDetector(
|
||||||
|
versionedObj runtime.Object,
|
||||||
|
rf *resource.Factory) (conflictDetector, error) {
|
||||||
|
lookupPatchMeta, err := strategicpatch.NewPatchMetaFromStruct(versionedObj)
|
||||||
|
return &strategicMergePatch{lookupPatchMeta: lookupPatchMeta, rf: rf}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (smp *strategicMergePatch) hasConflict(p1, p2 *resource.Resource) (bool, error) {
|
||||||
|
return strategicpatch.MergingMapsHaveConflicts(
|
||||||
|
p1.Map(), p2.Map(), smp.lookupPatchMeta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (smp *strategicMergePatch) findConflict(
|
||||||
|
conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error) {
|
||||||
|
for i, patch := range patches {
|
||||||
|
if i == conflictingPatchIdx {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !patches[conflictingPatchIdx].Id().GvknEquals(patch.Id()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
conflict, err := strategicpatch.MergingMapsHaveConflicts(
|
||||||
|
patch.Map(),
|
||||||
|
patches[conflictingPatchIdx].Map(),
|
||||||
|
smp.lookupPatchMeta)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if conflict {
|
||||||
|
return patch, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (smp *strategicMergePatch) mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
||||||
|
mergeJSONMap, err := strategicpatch.MergeStrategicMergeMapPatchUsingLookupPatchMeta(
|
||||||
|
smp.lookupPatchMeta, patch1.Map(), patch2.Map())
|
||||||
|
return smp.rf.FromMap(mergeJSONMap), err
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["validators.go"],
|
||||||
|
importmap = "k8s.io/kubernetes/vendor/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator",
|
||||||
|
importpath = "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/api/validation:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field: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,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 validator provides functions to validate labels, annotations, namespace using apimachinery
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
apivalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||||
|
v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KustValidator validates Labels and annotations by apimachinery
|
||||||
|
type KustValidator struct{}
|
||||||
|
|
||||||
|
// NewKustValidator returns a KustValidator object
|
||||||
|
func NewKustValidator() *KustValidator {
|
||||||
|
return &KustValidator{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeAnnotationValidator returns a MapValidatorFunc using apimachinery.
|
||||||
|
func (v *KustValidator) MakeAnnotationValidator() func(map[string]string) error {
|
||||||
|
return func(x map[string]string) error {
|
||||||
|
errs := apivalidation.ValidateAnnotations(x, field.NewPath("field"))
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.New(errs.ToAggregate().Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeLabelValidator returns a MapValidatorFunc using apimachinery.
|
||||||
|
func (v *KustValidator) MakeLabelValidator() func(map[string]string) error {
|
||||||
|
return func(x map[string]string) error {
|
||||||
|
errs := v1validation.ValidateLabels(x, field.NewPath("field"))
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.New(errs.ToAggregate().Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateNamespace validates a string is a valid namespace using apimachinery.
|
||||||
|
func (v *KustValidator) ValidateNamespace(s string) []string {
|
||||||
|
return validation.IsDNS1123Label(s)
|
||||||
|
}
|
220
staging/src/k8s.io/sample-cli-plugin/Godeps/Godeps.json
generated
220
staging/src/k8s.io/sample-cli-plugin/Godeps/Godeps.json
generated
@@ -6,10 +6,50 @@
|
|||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
"Deps": [
|
"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",
|
"ImportPath": "github.com/evanphx/json-patch",
|
||||||
"Rev": "36442dbdb585210f8d5a1b45e67aa323c197d5c4"
|
"Rev": "36442dbdb585210f8d5a1b45e67aa323c197d5c4"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"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",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Rev": "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
"Rev": "342cbe0a04158f6dcb03ca0079991a51a4248c02"
|
||||||
@@ -78,6 +118,18 @@
|
|||||||
"ImportPath": "github.com/json-iterator/go",
|
"ImportPath": "github.com/json-iterator/go",
|
||||||
"Rev": "ab8a2e0c74be9d3be70b3184d9acc634935ded82"
|
"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",
|
"ImportPath": "github.com/modern-go/concurrent",
|
||||||
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||||
@@ -90,6 +142,10 @@
|
|||||||
"ImportPath": "github.com/peterbourgon/diskv",
|
"ImportPath": "github.com/peterbourgon/diskv",
|
||||||
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/pkg/errors",
|
||||||
|
"Rev": "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/cobra",
|
"ImportPath": "github.com/spf13/cobra",
|
||||||
"Rev": "c439c4fa093711d42e1b01acb1235b52004753c1"
|
"Rev": "c439c4fa093711d42e1b01acb1235b52004753c1"
|
||||||
@@ -138,6 +194,10 @@
|
|||||||
"ImportPath": "golang.org/x/sys/windows",
|
"ImportPath": "golang.org/x/sys/windows",
|
||||||
"Rev": "95c6576299259db960f6c5b9b69ea52422860fce"
|
"Rev": "95c6576299259db960f6c5b9b69ea52422860fce"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/cases",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/encoding",
|
"ImportPath": "golang.org/x/text/encoding",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
@@ -154,10 +214,22 @@
|
|||||||
"ImportPath": "golang.org/x/text/encoding/unicode",
|
"ImportPath": "golang.org/x/text/encoding/unicode",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/internal",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/internal/tag",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/internal/utf8internal",
|
"ImportPath": "golang.org/x/text/internal/utf8internal",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/language",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/runes",
|
"ImportPath": "golang.org/x/text/runes",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
@@ -166,6 +238,10 @@
|
|||||||
"ImportPath": "golang.org/x/text/secure/bidirule",
|
"ImportPath": "golang.org/x/text/secure/bidirule",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/secure/precis",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/transform",
|
"ImportPath": "golang.org/x/text/transform",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
@@ -178,6 +254,10 @@
|
|||||||
"ImportPath": "golang.org/x/text/unicode/norm",
|
"ImportPath": "golang.org/x/text/unicode/norm",
|
||||||
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/width",
|
||||||
|
"Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/time/rate",
|
"ImportPath": "golang.org/x/time/rate",
|
||||||
"Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
"Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
||||||
@@ -318,6 +398,10 @@
|
|||||||
"ImportPath": "k8s.io/api/storage/v1beta1",
|
"ImportPath": "k8s.io/api/storage/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -330,6 +414,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/api/validation",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -342,6 +430,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -422,6 +514,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -438,6 +534,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -458,6 +558,10 @@
|
|||||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -474,6 +578,34 @@
|
|||||||
"ImportPath": "k8s.io/cli-runtime/pkg/genericclioptions/resource",
|
"ImportPath": "k8s.io/cli-runtime/pkg/genericclioptions/resource",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/configmapandsecret",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/kunstruct",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/patch",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator",
|
||||||
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/client-go/discovery",
|
"ImportPath": "k8s.io/client-go/discovery",
|
||||||
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
@@ -574,6 +706,94 @@
|
|||||||
"ImportPath": "k8s.io/klog",
|
"ImportPath": "k8s.io/klog",
|
||||||
"Rev": "8139d8cb77af419532b33dfa7dd09fbc5f1d344f"
|
"Rev": "8139d8cb77af419532b33dfa7dd09fbc5f1d344f"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/kube-openapi/pkg/common",
|
||||||
|
"Rev": "c59034cc13d587f5ef4e85ca0ade0c1866ae8e1d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
||||||
|
"Rev": "c59034cc13d587f5ef4e85ca0ade0c1866ae8e1d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/commands/build",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/constants",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/expansion",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/factory",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/fs",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/gvk",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/ifc/transformer",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/internal/error",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/loader",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/patch/transformer",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resid",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resmap",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/resource",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/target",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "sigs.k8s.io/kustomize/pkg/types",
|
||||||
|
"Rev": "ef51cceff55b17542fc91d6c4e30ea0bbb9641f7"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "sigs.k8s.io/yaml",
|
"ImportPath": "sigs.k8s.io/yaml",
|
||||||
"Rev": "fd68e9863619f6ec2fdd8625fe1f02e7c877e480"
|
"Rev": "fd68e9863619f6ec2fdd8625fe1f02e7c877e480"
|
||||||
|
16
vendor/BUILD
vendored
16
vendor/BUILD
vendored
@@ -467,6 +467,22 @@ filegroup(
|
|||||||
"//vendor/k8s.io/utils/clock:all-srcs",
|
"//vendor/k8s.io/utils/clock:all-srcs",
|
||||||
"//vendor/k8s.io/utils/exec:all-srcs",
|
"//vendor/k8s.io/utils/exec:all-srcs",
|
||||||
"//vendor/k8s.io/utils/pointer:all-srcs",
|
"//vendor/k8s.io/utils/pointer: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/gvk:all-srcs",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/ifc: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/yaml:all-srcs",
|
"//vendor/sigs.k8s.io/yaml:all-srcs",
|
||||||
"//vendor/vbom.ml/util/sortorder:all-srcs",
|
"//vendor/vbom.ml/util/sortorder:all-srcs",
|
||||||
],
|
],
|
||||||
|
201
vendor/sigs.k8s.io/kustomize/LICENSE
generated
vendored
Normal file
201
vendor/sigs.k8s.io/kustomize/LICENSE
generated
vendored
Normal file
@@ -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.
|
33
vendor/sigs.k8s.io/kustomize/pkg/commands/build/BUILD
generated
vendored
Normal file
33
vendor/sigs.k8s.io/kustomize/pkg/commands/build/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
120
vendor/sigs.k8s.io/kustomize/pkg/commands/build/build.go
generated
vendored
Normal file
120
vendor/sigs.k8s.io/kustomize/pkg/commands/build/build.go
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
type buildOptions struct {
|
||||||
|
kustomizationPath string
|
||||||
|
outputPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
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 buildOptions
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "build [path]",
|
||||||
|
Short: "Print current configuration per contents of " + constants.KustomizationFileName,
|
||||||
|
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 *buildOptions) Validate(args []string) error {
|
||||||
|
if len(args) > 1 {
|
||||||
|
return errors.New("specify one path to " + constants.KustomizationFileName)
|
||||||
|
}
|
||||||
|
if len(args) == 0 {
|
||||||
|
o.kustomizationPath = "./"
|
||||||
|
} else {
|
||||||
|
o.kustomizationPath = args[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunBuild runs build command.
|
||||||
|
func (o *buildOptions) 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
|
||||||
|
}
|
23
vendor/sigs.k8s.io/kustomize/pkg/constants/BUILD
generated
vendored
Normal file
23
vendor/sigs.k8s.io/kustomize/pkg/constants/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
31
vendor/sigs.k8s.io/kustomize/pkg/constants/constants.go
generated
vendored
Normal file
31
vendor/sigs.k8s.io/kustomize/pkg/constants/constants.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
// KustomizationFileSuffix is expected suffix for KustomizationFileName.
|
||||||
|
const KustomizationFileSuffix = ".yaml"
|
||||||
|
|
||||||
|
// SecondaryKustomizationFileSuffix is the second expected suffix when KustomizationFileSuffix is not found
|
||||||
|
const SecondaryKustomizationFileSuffix = ".yml"
|
||||||
|
|
||||||
|
// KustomizationFileName is the Well-Known File Name for a kustomize configuration file.
|
||||||
|
const KustomizationFileName = "kustomization" + KustomizationFileSuffix
|
||||||
|
|
||||||
|
// SecondaryKustomizationFileName is the secondary File Name for a kustomize configuration file when
|
||||||
|
// KustomizationFileName is not found
|
||||||
|
const SecondaryKustomizationFileName = "kustomization" + SecondaryKustomizationFileSuffix
|
23
vendor/sigs.k8s.io/kustomize/pkg/expansion/BUILD
generated
vendored
Normal file
23
vendor/sigs.k8s.io/kustomize/pkg/expansion/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
119
vendor/sigs.k8s.io/kustomize/pkg/expansion/expand.go
generated
vendored
Normal file
119
vendor/sigs.k8s.io/kustomize/pkg/expansion/expand.go
generated
vendored
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
29
vendor/sigs.k8s.io/kustomize/pkg/factory/BUILD
generated
vendored
Normal file
29
vendor/sigs.k8s.io/kustomize/pkg/factory/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
39
vendor/sigs.k8s.io/kustomize/pkg/factory/factory.go
generated
vendored
Normal file
39
vendor/sigs.k8s.io/kustomize/pkg/factory/factory.go
generated
vendored
Normal file
@@ -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,
|
||||||
|
}
|
||||||
|
}
|
31
vendor/sigs.k8s.io/kustomize/pkg/fs/BUILD
generated
vendored
Normal file
31
vendor/sigs.k8s.io/kustomize/pkg/fs/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 = [
|
||||||
|
"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"],
|
||||||
|
)
|
69
vendor/sigs.k8s.io/kustomize/pkg/fs/fakefile.go
generated
vendored
Normal file
69
vendor/sigs.k8s.io/kustomize/pkg/fs/fakefile.go
generated
vendored
Normal file
@@ -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
|
||||||
|
}
|
47
vendor/sigs.k8s.io/kustomize/pkg/fs/fakefileinfo.go
generated
vendored
Normal file
47
vendor/sigs.k8s.io/kustomize/pkg/fs/fakefileinfo.go
generated
vendored
Normal file
@@ -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 }
|
171
vendor/sigs.k8s.io/kustomize/pkg/fs/fakefs.go
generated
vendored
Normal file
171
vendor/sigs.k8s.io/kustomize/pkg/fs/fakefs.go
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
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 = `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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.KustomizationFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.KustomizationFileName, bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *fakeFs) pathMatch(path, pattern string) bool {
|
||||||
|
match, _ := filepath.Match(pattern, path)
|
||||||
|
return match
|
||||||
|
}
|
43
vendor/sigs.k8s.io/kustomize/pkg/fs/fs.go
generated
vendored
Normal file
43
vendor/sigs.k8s.io/kustomize/pkg/fs/fs.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
}
|
40
vendor/sigs.k8s.io/kustomize/pkg/fs/realfile.go
generated
vendored
Normal file
40
vendor/sigs.k8s.io/kustomize/pkg/fs/realfile.go
generated
vendored
Normal file
@@ -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() }
|
82
vendor/sigs.k8s.io/kustomize/pkg/fs/realfs.go
generated
vendored
Normal file
82
vendor/sigs.k8s.io/kustomize/pkg/fs/realfs.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
"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) }
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
23
vendor/sigs.k8s.io/kustomize/pkg/gvk/BUILD
generated
vendored
Normal file
23
vendor/sigs.k8s.io/kustomize/pkg/gvk/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
168
vendor/sigs.k8s.io/kustomize/pkg/gvk/gvk.go
generated
vendored
Normal file
168
vendor/sigs.k8s.io/kustomize/pkg/gvk/gvk.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
noGroup = "noGroup"
|
||||||
|
noVersion = "noVersion"
|
||||||
|
noKind = "noKind"
|
||||||
|
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 as a wildcard and always return true.
|
||||||
|
// e.g. selector <Group: "", Version: "", Kind: "Deployment"> CAN select
|
||||||
|
// <Group: "extensions", Version: "v1beta1", Kind: "Deployment">.
|
||||||
|
// selector <Group: "apps", Version: "", Kind: "Deployment"> CANNOT select
|
||||||
|
// <Group: "extensions", Version: "v1beta1", 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{
|
||||||
|
"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
|
||||||
|
}
|
34
vendor/sigs.k8s.io/kustomize/pkg/ifc/BUILD
generated
vendored
Normal file
34
vendor/sigs.k8s.io/kustomize/pkg/ifc/BUILD
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"generationbehavior.go",
|
||||||
|
"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/fs:go_default_library",
|
||||||
|
"//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"],
|
||||||
|
)
|
59
vendor/sigs.k8s.io/kustomize/pkg/ifc/generationbehavior.go
generated
vendored
Normal file
59
vendor/sigs.k8s.io/kustomize/pkg/ifc/generationbehavior.go
generated
vendored
Normal file
@@ -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 ifc
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
74
vendor/sigs.k8s.io/kustomize/pkg/ifc/ifc.go
generated
vendored
Normal file
74
vendor/sigs.k8s.io/kustomize/pkg/ifc/ifc.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
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/fs"
|
||||||
|
"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(fs fs.FileSystem, ldr Loader)
|
||||||
|
}
|
||||||
|
|
||||||
|
// See core.v1.SecretTypeOpaque
|
||||||
|
const SecretTypeOpaque = "Opaque"
|
27
vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer/BUILD
generated
vendored
Normal file
27
vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
29
vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer/factory.go
generated
vendored
Normal file
29
vendor/sigs.k8s.io/kustomize/pkg/ifc/transformer/factory.go
generated
vendored
Normal file
@@ -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
|
||||||
|
}
|
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/BUILD
generated
vendored
Normal file
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/configmaperror.go
generated
vendored
Normal file
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/configmaperror.go
generated
vendored
Normal file
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
32
vendor/sigs.k8s.io/kustomize/pkg/internal/error/patcherror.go
generated
vendored
Normal file
32
vendor/sigs.k8s.io/kustomize/pkg/internal/error/patcherror.go
generated
vendored
Normal file
@@ -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)
|
||||||
|
}
|
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/resourceerror.go
generated
vendored
Normal file
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/resourceerror.go
generated
vendored
Normal file
@@ -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)
|
||||||
|
}
|
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/secreterror.go
generated
vendored
Normal file
30
vendor/sigs.k8s.io/kustomize/pkg/internal/error/secreterror.go
generated
vendored
Normal file
@@ -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")
|
||||||
|
}
|
32
vendor/sigs.k8s.io/kustomize/pkg/loader/BUILD
generated
vendored
Normal file
32
vendor/sigs.k8s.io/kustomize/pkg/loader/BUILD
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"fileloader.go",
|
||||||
|
"gitcloner.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/github.com/pkg/errors:go_default_library",
|
||||||
|
"//vendor/sigs.k8s.io/kustomize/pkg/fs: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"],
|
||||||
|
)
|
224
vendor/sigs.k8s.io/kustomize/pkg/loader/fileloader.go
generated
vendored
Normal file
224
vendor/sigs.k8s.io/kustomize/pkg/loader/fileloader.go
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
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/ifc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: 2018/Nov/20 remove this before next release.
|
||||||
|
// Leave only the true path. Retaining only for
|
||||||
|
// quick revert.
|
||||||
|
const enforceRelocatable = true
|
||||||
|
|
||||||
|
// fileLoader loads files, returning an array of bytes.
|
||||||
|
// It also enforces two kustomization requirements:
|
||||||
|
//
|
||||||
|
// 1) relocatable
|
||||||
|
//
|
||||||
|
// A kustomization and the resources, bases,
|
||||||
|
// patches, etc. that it depends on should be
|
||||||
|
// relocatable, so all path specifications
|
||||||
|
// must be relative, not absolute. The paths
|
||||||
|
// are taken relative to the location of the
|
||||||
|
// kusttomization file.
|
||||||
|
//
|
||||||
|
// 2) acyclic
|
||||||
|
//
|
||||||
|
// There should be no cycles in overlay to base
|
||||||
|
// relationships, including no cycles between
|
||||||
|
// git repositories.
|
||||||
|
//
|
||||||
|
// The loader has a notion of a current working directory
|
||||||
|
// (CWD), called 'root', that is independent of the CWD
|
||||||
|
// of the process. When `Load` is called with a file path
|
||||||
|
// argument, the load is done relative to this root,
|
||||||
|
// not relative to the process CWD.
|
||||||
|
//
|
||||||
|
// The loader offers a `New` method returning a new loader
|
||||||
|
// with a new root. The new root can be one of two things,
|
||||||
|
// a remote git repo URL, or a directory specified relative
|
||||||
|
// to the current root. In the former case, the remote
|
||||||
|
// repository is locally cloned, and the new loader is
|
||||||
|
// rooted on a path in that clone.
|
||||||
|
//
|
||||||
|
// Crucially, a root history is used to so that New fails
|
||||||
|
// if its argument either matches or is a parent of the
|
||||||
|
// current or any previously used root.
|
||||||
|
//
|
||||||
|
// This disallows:
|
||||||
|
//
|
||||||
|
// * A base that is a git repository that, in turn,
|
||||||
|
// specifies a base repository seen previously
|
||||||
|
// in the loading process (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 encourage cycles,
|
||||||
|
// particularly if some future change were to
|
||||||
|
// introduce globbing to file specifications in
|
||||||
|
// the kustomization file.
|
||||||
|
//
|
||||||
|
type fileLoader struct {
|
||||||
|
// Previously visited directories, tracked to
|
||||||
|
// avoid cycles. The last entry is the current root.
|
||||||
|
roots []string
|
||||||
|
// File system utilities.
|
||||||
|
fSys fs.FileSystem
|
||||||
|
// Used to clone repositories.
|
||||||
|
cloner gitCloner
|
||||||
|
// 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, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root returns the absolute path that is prepended to any
|
||||||
|
// relative paths used in Load.
|
||||||
|
func (l *fileLoader) Root() string {
|
||||||
|
return l.roots[len(l.roots)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader {
|
||||||
|
l, err := newFileLoaderAt(
|
||||||
|
path, fSys, []string{}, simpleGitCloner)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("unable to make loader at '%s'; %v", path, err)
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// newFileLoaderAt returns a new fileLoader with given root.
|
||||||
|
func newFileLoaderAt(
|
||||||
|
root string, fSys fs.FileSystem,
|
||||||
|
roots []string, cloner gitCloner) (*fileLoader, error) {
|
||||||
|
if root == "" {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"loader root cannot be empty")
|
||||||
|
}
|
||||||
|
root, err := filepath.Abs(root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"absolute path error in '%s' : %v", root, err)
|
||||||
|
}
|
||||||
|
if !fSys.IsDir(root) {
|
||||||
|
return nil, fmt.Errorf("absolute root dir '%s' does not exist", root)
|
||||||
|
}
|
||||||
|
return &fileLoader{
|
||||||
|
roots: append(roots, root),
|
||||||
|
fSys: fSys,
|
||||||
|
cloner: cloner,
|
||||||
|
cleaner: func() error { return nil },
|
||||||
|
}, 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(root string) (ifc.Loader, error) {
|
||||||
|
if root == "" {
|
||||||
|
return nil, fmt.Errorf("new root cannot be empty")
|
||||||
|
}
|
||||||
|
if isRepoUrl(root) {
|
||||||
|
if err := l.seenBefore(root); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return newGitLoader(root, l.fSys, l.roots, l.cloner)
|
||||||
|
}
|
||||||
|
if enforceRelocatable && filepath.IsAbs(root) {
|
||||||
|
return nil, fmt.Errorf("new root '%s' cannot be absolute", root)
|
||||||
|
}
|
||||||
|
// Get absolute path to squeeze out "..", ".", etc.
|
||||||
|
// to facilitate the seenBefore test.
|
||||||
|
absRoot, err := filepath.Abs(filepath.Join(l.Root(), root))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"problem joining '%s' to '%s': %v", l.Root(), root, err)
|
||||||
|
}
|
||||||
|
if err := l.seenBefore(absRoot); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return newFileLoaderAt(absRoot, l.fSys, l.roots, l.cloner)
|
||||||
|
}
|
||||||
|
|
||||||
|
// newGitLoader returns a new Loader pinned to a temporary
|
||||||
|
// directory holding a cloned git repo.
|
||||||
|
func newGitLoader(
|
||||||
|
root string, fSys fs.FileSystem,
|
||||||
|
roots []string, cloner gitCloner) (ifc.Loader, error) {
|
||||||
|
tmpDirForRepo, pathInRepo, err := cloner(root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
trueRoot := filepath.Join(tmpDirForRepo, pathInRepo)
|
||||||
|
if !fSys.IsDir(trueRoot) {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"something wrong cloning '%s'; unable to find '%s'",
|
||||||
|
root, trueRoot)
|
||||||
|
}
|
||||||
|
return &fileLoader{
|
||||||
|
roots: append(roots, root, trueRoot),
|
||||||
|
fSys: fSys,
|
||||||
|
cloner: cloner,
|
||||||
|
cleaner: func() error { return fSys.RemoveAll(tmpDirForRepo) },
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// seenBefore tests whether the current or any previously
|
||||||
|
// visited root begins with the given path.
|
||||||
|
func (l *fileLoader) seenBefore(path string) error {
|
||||||
|
for _, r := range l.roots {
|
||||||
|
if strings.HasPrefix(r, path) {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"cycle detected: new root '%s' contains previous root '%s'",
|
||||||
|
path, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load returns content of file at the given relative path.
|
||||||
|
func (l *fileLoader) Load(path string) ([]byte, error) {
|
||||||
|
if filepath.IsAbs(path) {
|
||||||
|
if enforceRelocatable {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"must use relative path; '%s' is absolute", path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
path = filepath.Join(l.Root(), path)
|
||||||
|
}
|
||||||
|
return l.fSys.ReadFile(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup runs the cleaner.
|
||||||
|
func (l *fileLoader) Cleanup() error {
|
||||||
|
return l.cleaner()
|
||||||
|
}
|
133
vendor/sigs.k8s.io/kustomize/pkg/loader/gitcloner.go
generated
vendored
Normal file
133
vendor/sigs.k8s.io/kustomize/pkg/loader/gitcloner.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// gitCloner is a function that can clone a git repo.
|
||||||
|
type gitCloner func(url string) (
|
||||||
|
// Directory where the repo is cloned to.
|
||||||
|
checkoutDir string,
|
||||||
|
// Relative path in the checkoutDir to location
|
||||||
|
// of kustomization file.
|
||||||
|
pathInCoDir string,
|
||||||
|
// Any error encountered when cloning.
|
||||||
|
err error)
|
||||||
|
|
||||||
|
// isRepoUrl checks if a string is likely a github repo Url.
|
||||||
|
func isRepoUrl(arg string) bool {
|
||||||
|
arg = strings.ToLower(arg)
|
||||||
|
return !filepath.IsAbs(arg) &&
|
||||||
|
(strings.HasPrefix(arg, "git::") ||
|
||||||
|
strings.HasPrefix(arg, "gh:") ||
|
||||||
|
strings.HasPrefix(arg, "github.com") ||
|
||||||
|
strings.HasPrefix(arg, "git@github.com:") ||
|
||||||
|
strings.Index(arg, "github.com/") > -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeTmpDir() (string, error) {
|
||||||
|
return ioutil.TempDir("", "kustomize-")
|
||||||
|
}
|
||||||
|
|
||||||
|
func simpleGitCloner(spec string) (
|
||||||
|
checkoutDir string, pathInCoDir string, err error) {
|
||||||
|
gitProgram, err := exec.LookPath("git")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", errors.Wrap(err, "no 'git' program on path")
|
||||||
|
}
|
||||||
|
checkoutDir, err = makeTmpDir()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
repo, pathInCoDir, gitRef, err := parseGithubUrl(spec)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cmd := exec.Command(
|
||||||
|
gitProgram,
|
||||||
|
"clone",
|
||||||
|
"https://github.com/"+repo+".git",
|
||||||
|
checkoutDir)
|
||||||
|
var out bytes.Buffer
|
||||||
|
cmd.Stdout = &out
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", "",
|
||||||
|
errors.Wrapf(err, "trouble cloning %s", spec)
|
||||||
|
}
|
||||||
|
if gitRef == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cmd = exec.Command(gitProgram, "checkout", gitRef)
|
||||||
|
cmd.Dir = checkoutDir
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", "",
|
||||||
|
errors.Wrapf(err, "trouble checking out href %s", gitRef)
|
||||||
|
}
|
||||||
|
return checkoutDir, pathInCoDir, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const refQuery = "?ref="
|
||||||
|
|
||||||
|
// From strings like git@github.com:someOrg/someRepo.git or
|
||||||
|
// https://github.com/someOrg/someRepo?ref=someHash, extract
|
||||||
|
// the parts.
|
||||||
|
func parseGithubUrl(n string) (
|
||||||
|
repo string, path string, gitRef string, err error) {
|
||||||
|
for _, p := range []string{
|
||||||
|
// Order matters here.
|
||||||
|
"git::", "gh:", "https://", "http://",
|
||||||
|
"git@", "github.com:", "github.com/", "gitlab.com/"} {
|
||||||
|
if strings.ToLower(n[:len(p)]) == p {
|
||||||
|
n = n[len(p):]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(n, ".git") {
|
||||||
|
n = n[0 : len(n)-len(".git")]
|
||||||
|
}
|
||||||
|
i := strings.Index(n, string(filepath.Separator))
|
||||||
|
if i < 1 {
|
||||||
|
return "", "", "", errors.New("no separator")
|
||||||
|
}
|
||||||
|
j := strings.Index(n[i+1:], string(filepath.Separator))
|
||||||
|
if j >= 0 {
|
||||||
|
j += i + 1
|
||||||
|
repo = n[:j]
|
||||||
|
path, gitRef = peelQuery(n[j+1:])
|
||||||
|
} else {
|
||||||
|
path = ""
|
||||||
|
repo, 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, ""
|
||||||
|
}
|
33
vendor/sigs.k8s.io/kustomize/pkg/loader/loader.go
generated
vendored
Normal file
33
vendor/sigs.k8s.io/kustomize/pkg/loader/loader.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
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/ifc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewLoader returns a Loader.
|
||||||
|
func NewLoader(root string, fSys fs.FileSystem) (ifc.Loader, error) {
|
||||||
|
if isRepoUrl(root) {
|
||||||
|
return newGitLoader(
|
||||||
|
root, fSys, []string{}, simpleGitCloner)
|
||||||
|
}
|
||||||
|
return newFileLoaderAt(
|
||||||
|
root, fSys, []string{}, simpleGitCloner)
|
||||||
|
}
|
30
vendor/sigs.k8s.io/kustomize/pkg/patch/BUILD
generated
vendored
Normal file
30
vendor/sigs.k8s.io/kustomize/pkg/patch/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
40
vendor/sigs.k8s.io/kustomize/pkg/patch/json6902.go
generated
vendored
Normal file
40
vendor/sigs.k8s.io/kustomize/pkg/patch/json6902.go
generated
vendored
Normal file
@@ -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).
|
||||||
|
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"`
|
||||||
|
}
|
40
vendor/sigs.k8s.io/kustomize/pkg/patch/strategicmerge.go
generated
vendored
Normal file
40
vendor/sigs.k8s.io/kustomize/pkg/patch/strategicmerge.go
generated
vendored
Normal file
@@ -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
|
||||||
|
}
|
38
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/BUILD
generated
vendored
Normal file
38
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
97
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/factory.go
generated
vendored
Normal file
97
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/factory.go
generated
vendored
Normal file
@@ -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
|
||||||
|
}
|
46
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/util.go
generated
vendored
Normal file
46
vendor/sigs.k8s.io/kustomize/pkg/patch/transformer/util.go
generated
vendored
Normal file
@@ -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
|
||||||
|
}
|
24
vendor/sigs.k8s.io/kustomize/pkg/resid/BUILD
generated
vendored
Normal file
24
vendor/sigs.k8s.io/kustomize/pkg/resid/BUILD
generated
vendored
Normal file
@@ -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"],
|
||||||
|
)
|
220
vendor/sigs.k8s.io/kustomize/pkg/resid/resid.go
generated
vendored
Normal file
220
vendor/sigs.k8s.io/kustomize/pkg/resid/resid.go
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"fmt"
|
||||||
|
"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}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewResIdWithPrefix creates new resource identifier with a prefix
|
||||||
|
func NewResIdWithPrefix(k gvk.Gvk, n, p string) ResId {
|
||||||
|
return ResId{gvKind: k, name: n, prefix: p}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewResIdWithSuffix creates new resource identifier with a suffix
|
||||||
|
func NewResIdWithSuffix(k gvk.Gvk, n, s string) ResId {
|
||||||
|
return ResId{gvKind: k, name: n, 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 = "noNamespace"
|
||||||
|
noPrefix = "noPrefix"
|
||||||
|
noName = "noName"
|
||||||
|
noSuffix = "noSuffix"
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameWithPrefixSuffix returns resource name with prefix and suffix.
|
||||||
|
func (n ResId) NameWithPrefixSuffix() string {
|
||||||
|
prefix := strings.Join(n.prefixList(), "")
|
||||||
|
suffix := strings.Join(n.suffixList(), "")
|
||||||
|
return fmt.Sprintf("%s%s%s", prefix, n.name, suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefix returns name prefix.
|
||||||
|
func (n ResId) Prefix() string {
|
||||||
|
return n.prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
// Suffix returns name suffix.
|
||||||
|
func (n ResId) Suffix() string {
|
||||||
|
return n.suffix
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
prefix := n.prefix
|
||||||
|
if p != "" {
|
||||||
|
prefix = n.concatPrefix(p)
|
||||||
|
}
|
||||||
|
suffix := n.suffix
|
||||||
|
if s != "" {
|
||||||
|
suffix = n.concatSuffix(s)
|
||||||
|
}
|
||||||
|
return ResId{gvKind: n.gvKind, name: n.name, prefix: prefix, suffix: suffix, namespace: n.namespace}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyWithNewNamespace make a new copy from current ResId and set a new namespace
|
||||||
|
func (n ResId) CopyWithNewNamespace(ns string) ResId {
|
||||||
|
return ResId{gvKind: n.gvKind, name: n.name, prefix: n.prefix, suffix: n.suffix, namespace: ns}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, ":")
|
||||||
|
}
|
37
vendor/sigs.k8s.io/kustomize/pkg/resmap/BUILD
generated
vendored
Normal file
37
vendor/sigs.k8s.io/kustomize/pkg/resmap/BUILD
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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/fs: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"],
|
||||||
|
)
|
124
vendor/sigs.k8s.io/kustomize/pkg/resmap/factory.go
generated
vendored
Normal file
124
vendor/sigs.k8s.io/kustomize/pkg/resmap/factory.go
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
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/fs"
|
||||||
|
"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 MergeWithoutOverride(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 filesystem and loader for the underlying factory
|
||||||
|
func (rmF *Factory) Set(fs fs.FileSystem, ldr ifc.Loader) {
|
||||||
|
rmF.resF.Set(fs, 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
|
||||||
|
}
|
37
vendor/sigs.k8s.io/kustomize/pkg/resmap/idslice.go
generated
vendored
Normal file
37
vendor/sigs.k8s.io/kustomize/pkg/resmap/idslice.go
generated
vendored
Normal file
@@ -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()
|
||||||
|
}
|
213
vendor/sigs.k8s.io/kustomize/pkg/resmap/resmap.go
generated
vendored
Normal file
213
vendor/sigs.k8s.io/kustomize/pkg/resmap/resmap.go
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/ghodss/yaml"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resid"
|
||||||
|
"sigs.k8s.io/kustomize/pkg/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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] = rf.FromKunstructured(obj.Copy())
|
||||||
|
mcopy[id].SetBehavior(obj.Behavior())
|
||||||
|
}
|
||||||
|
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.Namespace() == inputId.Namespace() && id.HasSameLeftmostPrefix(inputId) && id.HasSameRightmostSuffix(inputId) {
|
||||||
|
result[id] = res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergeWithoutOverride combines multiple ResMap instances, failing on key collision
|
||||||
|
// and skipping nil maps. In case if all of the maps are nil, an empty ResMap is returned.
|
||||||
|
func MergeWithoutOverride(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 ifc.BehaviorReplace:
|
||||||
|
log.Printf(
|
||||||
|
"Replace %v with %v", result[id].Map(), r.Map())
|
||||||
|
r.Replace(result[id])
|
||||||
|
result[id] = r
|
||||||
|
result[id].SetBehavior(ifc.BehaviorCreate)
|
||||||
|
case ifc.BehaviorMerge:
|
||||||
|
log.Printf(
|
||||||
|
"Merging %v with %v", result[id].Map(), r.Map())
|
||||||
|
r.Merge(result[id])
|
||||||
|
result[id] = r
|
||||||
|
log.Printf(
|
||||||
|
"Merged object is %v", result[id].Map())
|
||||||
|
result[id].SetBehavior(ifc.BehaviorCreate)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("id %#v exists; must merge or replace", id)
|
||||||
|
}
|
||||||
|
} else if len(matchedId) == 0 {
|
||||||
|
switch r.Behavior() {
|
||||||
|
case ifc.BehaviorMerge, ifc.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
|
||||||
|
}
|
34
vendor/sigs.k8s.io/kustomize/pkg/resource/BUILD
generated
vendored
Normal file
34
vendor/sigs.k8s.io/kustomize/pkg/resource/BUILD
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
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/fs: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/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"],
|
||||||
|
)
|
116
vendor/sigs.k8s.io/kustomize/pkg/resource/factory.go
generated
vendored
Normal file
116
vendor/sigs.k8s.io/kustomize/pkg/resource/factory.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/pkg/fs"
|
||||||
|
"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),
|
||||||
|
b: ifc.BehaviorUnspecified}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, b: ifc.BehaviorUnspecified}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 _, u := range kunStructs {
|
||||||
|
result = append(result, rf.FromKunstructured(u))
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the filesystem and loader for the underlying factory
|
||||||
|
func (rf *Factory) Set(fs fs.FileSystem, ldr ifc.Loader) {
|
||||||
|
rf.kf.Set(fs, 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, b: fixBehavior(args.Behavior)}, 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, b: fixBehavior(args.Behavior)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fixBehavior(s string) ifc.GenerationBehavior {
|
||||||
|
b := ifc.NewGenerationBehavior(s)
|
||||||
|
if b == ifc.BehaviorUnspecified {
|
||||||
|
return ifc.BehaviorCreate
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
103
vendor/sigs.k8s.io/kustomize/pkg/resource/resource.go
generated
vendored
Normal file
103
vendor/sigs.k8s.io/kustomize/pkg/resource/resource.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Resource is map representation of a Kubernetes API resource object
|
||||||
|
// paired with a GenerationBehavior.
|
||||||
|
type Resource struct {
|
||||||
|
ifc.Kunstructured
|
||||||
|
b ifc.GenerationBehavior
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns resource as JSON.
|
||||||
|
func (r *Resource) String() string {
|
||||||
|
bs, err := r.MarshalJSON()
|
||||||
|
if err != nil {
|
||||||
|
return "<" + err.Error() + ">"
|
||||||
|
}
|
||||||
|
return r.b.String() + ":" + strings.TrimSpace(string(bs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Behavior returns the behavior for the resource.
|
||||||
|
func (r *Resource) Behavior() ifc.GenerationBehavior {
|
||||||
|
return r.b
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBehavior changes the resource to the new behavior
|
||||||
|
func (r *Resource) SetBehavior(b ifc.GenerationBehavior) *Resource {
|
||||||
|
r.b = b
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsGenerated checks if the resource is generated from a generator
|
||||||
|
func (r *Resource) IsGenerated() bool {
|
||||||
|
return r.b != ifc.BehaviorUnspecified
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
39
vendor/sigs.k8s.io/kustomize/pkg/target/BUILD
generated
vendored
Normal file
39
vendor/sigs.k8s.io/kustomize/pkg/target/BUILD
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["kusttarget.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"],
|
||||||
|
)
|
383
vendor/sigs.k8s.io/kustomize/pkg/target/kusttarget.go
generated
vendored
Normal file
383
vendor/sigs.k8s.io/kustomize/pkg/target/kusttarget.go
generated
vendored
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
/*
|
||||||
|
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 being customized.
|
||||||
|
package target
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"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/resid"
|
||||||
|
"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
|
||||||
|
tConfig *config.TransformerConfig
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var k types.Kustomization
|
||||||
|
err = unmarshal(content, &k)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
k.DealWithDeprecatedFields()
|
||||||
|
tConfig, err := makeTransformerConfig(ldr, k.Configurations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &KustTarget{
|
||||||
|
kustomization: &k,
|
||||||
|
ldr: ldr,
|
||||||
|
fSys: fSys,
|
||||||
|
rFactory: rFactory,
|
||||||
|
tConfig: tConfig,
|
||||||
|
tFactory: tFactory,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeTransformerConfig returns a complete TransformerConfig object from either files
|
||||||
|
// or the default configs
|
||||||
|
func makeTransformerConfig(ldr ifc.Loader, paths []string) (*config.TransformerConfig, error) {
|
||||||
|
if paths == nil || len(paths) == 0 {
|
||||||
|
return config.NewFactory(nil).DefaultConfig(), nil
|
||||||
|
}
|
||||||
|
return config.NewFactory(ldr).FromFiles(paths)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeCustomizedResMap creates a ResMap per kustomization instructions.
|
||||||
|
// The Resources in the returned ResMap are fully customized.
|
||||||
|
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
|
||||||
|
m, err := kt.loadCustomizedResMap()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return kt.resolveRefsToGeneratedResources(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolveRefsToGeneratedResources fixes all name references.
|
||||||
|
func (kt *KustTarget) resolveRefsToGeneratedResources(m resmap.ResMap) (resmap.ResMap, error) {
|
||||||
|
if kt.kustomization.GeneratorOptions == nil ||
|
||||||
|
!kt.kustomization.GeneratorOptions.DisableNameSuffixHash {
|
||||||
|
// This effects only generated resources.
|
||||||
|
// It changes only the Name field in the
|
||||||
|
// resource held in the ResMap's value, not
|
||||||
|
// the Name in the key in the ResMap.
|
||||||
|
err := kt.tFactory.MakeHashTransformer().Transform(m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var r []transformers.Transformer
|
||||||
|
t, err := transformers.NewNameReferenceTransformer(kt.tConfig.NameReference)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r = append(r, t)
|
||||||
|
|
||||||
|
refVars, err := kt.resolveRefVars(m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
t = transformers.NewRefVarTransformer(refVars, kt.tConfig.VarReference)
|
||||||
|
r = append(r, t)
|
||||||
|
|
||||||
|
err = transformers.NewMultiTransformer(r).Transform(m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadCustomizedResMap loads and customizes resources to build a ResMap.
|
||||||
|
func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) {
|
||||||
|
errs := &interror.KustomizationErrors{}
|
||||||
|
result, err := kt.loadResMapFromBasesAndResources()
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(errors.Wrap(err, "loadResMapFromBasesAndResources"))
|
||||||
|
}
|
||||||
|
crdTc, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds)
|
||||||
|
kt.tConfig = kt.tConfig.Merge(crdTc)
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(errors.Wrap(err, "LoadCRDs"))
|
||||||
|
}
|
||||||
|
resMap, err := kt.generateConfigMapsAndSecrets(errs)
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(errors.Wrap(err, "generateConfigMapsAndSecrets"))
|
||||||
|
}
|
||||||
|
result, err = resmap.MergeWithOverride(result, 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
|
||||||
|
}
|
||||||
|
|
||||||
|
var r []transformers.Transformer
|
||||||
|
t, err := kt.newTransformer(patches)
|
||||||
|
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.NewImageTagTransformer(kt.kustomization.ImageTags)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r = append(r, t)
|
||||||
|
|
||||||
|
err = transformers.NewMultiTransformer(r).Transform(result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kt *KustTarget) generateConfigMapsAndSecrets(
|
||||||
|
errs *interror.KustomizationErrors) (resmap.ResMap, error) {
|
||||||
|
kt.rFactory.Set(kt.fSys, 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.MergeWithoutOverride(cms, secrets)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets Bases and Resources as advertised.
|
||||||
|
func (kt *KustTarget) loadResMapFromBasesAndResources() (resmap.ResMap, error) {
|
||||||
|
bases, errs := kt.loadCustomizedBases()
|
||||||
|
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 nil, errs
|
||||||
|
}
|
||||||
|
return resmap.MergeWithoutOverride(resources, bases)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through the Bases of this kustomization recursively loading resources.
|
||||||
|
// Combine into one ResMap, demanding unique Ids for each resource.
|
||||||
|
func (kt *KustTarget) loadCustomizedBases() (resmap.ResMap, *interror.KustomizationErrors) {
|
||||||
|
var list []resmap.ResMap
|
||||||
|
errs := &interror.KustomizationErrors{}
|
||||||
|
for _, path := range kt.kustomization.Bases {
|
||||||
|
ldr, err := kt.ldr.New(path)
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(errors.Wrap(err, "couldn't make ldr for "+path))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
target, err := NewKustTarget(
|
||||||
|
ldr, kt.fSys,
|
||||||
|
kt.rFactory, kt.tFactory)
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(errors.Wrap(err, "couldn't make target for "+path))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resMap, err := target.loadCustomizedResMap()
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(errors.Wrap(err, "SemiResources"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ldr.Cleanup()
|
||||||
|
list = append(list, resMap)
|
||||||
|
}
|
||||||
|
result, err := resmap.MergeWithoutOverride(list...)
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(errors.Wrap(err, "Merge failed"))
|
||||||
|
}
|
||||||
|
return result, errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kt *KustTarget) loadBasesAsFlatList() ([]*KustTarget, error) {
|
||||||
|
var result []*KustTarget
|
||||||
|
errs := &interror.KustomizationErrors{}
|
||||||
|
for _, path := range kt.kustomization.Bases {
|
||||||
|
ldr, err := kt.ldr.New(path)
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
target, err := NewKustTarget(
|
||||||
|
ldr, kt.fSys, kt.rFactory, kt.tFactory)
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, target)
|
||||||
|
}
|
||||||
|
if len(errs.Get()) > 0 {
|
||||||
|
return nil, errs
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newTransformer makes a Transformer that does everything except resolve generated names.
|
||||||
|
func (kt *KustTarget) newTransformer(patches []*resource.Resource) (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), kt.tConfig.NameSpace))
|
||||||
|
t, err = transformers.NewNamePrefixSuffixTransformer(
|
||||||
|
string(kt.kustomization.NamePrefix),
|
||||||
|
string(kt.kustomization.NameSuffix),
|
||||||
|
kt.tConfig.NamePrefix,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r = append(r, t)
|
||||||
|
t, err = transformers.NewLabelsMapTransformer(
|
||||||
|
kt.kustomization.CommonLabels, kt.tConfig.CommonLabels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r = append(r, t)
|
||||||
|
t, err = transformers.NewAnnotationsMapTransformer(
|
||||||
|
kt.kustomization.CommonAnnotations, kt.tConfig.CommonAnnotations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r = append(r, t)
|
||||||
|
return transformers.NewMultiTransformer(r), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kt *KustTarget) resolveRefVars(m resmap.ResMap) (map[string]string, error) {
|
||||||
|
result := map[string]string{}
|
||||||
|
vars, err := kt.getAllVars()
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
for _, v := range vars {
|
||||||
|
id := resid.NewResId(v.ObjRef.GVK(), v.ObjRef.Name)
|
||||||
|
if r, found := m.DemandOneMatchForId(id); found {
|
||||||
|
s, err := r.GetFieldValue(v.FieldRef.FieldPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to resolve referred var: %+v", v)
|
||||||
|
}
|
||||||
|
result[v.Name] = s
|
||||||
|
} else {
|
||||||
|
log.Printf("couldn't resolve v: %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getAllVars returns all the "environment" style Var instances defined in the app.
|
||||||
|
func (kt *KustTarget) getAllVars() ([]types.Var, error) {
|
||||||
|
var result []types.Var
|
||||||
|
errs := &interror.KustomizationErrors{}
|
||||||
|
|
||||||
|
bases, err := kt.loadBasesAsFlatList()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: computing vars and resources for bases can be combined
|
||||||
|
for _, b := range bases {
|
||||||
|
vars, err := b.getAllVars()
|
||||||
|
if err != nil {
|
||||||
|
errs.Append(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b.ldr.Cleanup()
|
||||||
|
result = append(result, vars...)
|
||||||
|
}
|
||||||
|
for _, v := range kt.kustomization.Vars {
|
||||||
|
v.Defaulting()
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
if len(errs.Get()) > 0 {
|
||||||
|
return nil, errs
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadKustFile(ldr ifc.Loader) ([]byte, error) {
|
||||||
|
for _, kf := range []string{constants.KustomizationFileName, constants.SecondaryKustomizationFileName} {
|
||||||
|
content, err := ldr.Load(kf)
|
||||||
|
if err == nil {
|
||||||
|
return content, nil
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "no such file or directory") {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no kustomization.yaml file under %s", ldr.Root())
|
||||||
|
}
|
45
vendor/sigs.k8s.io/kustomize/pkg/transformers/BUILD
generated
vendored
Normal file
45
vendor/sigs.k8s.io/kustomize/pkg/transformers/BUILD
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"imagetag.go",
|
||||||
|
"labelsandannotations.go",
|
||||||
|
"multitransformer.go",
|
||||||
|
"namereference.go",
|
||||||
|
"namespace.go",
|
||||||
|
"nooptransformer.go",
|
||||||
|
"prefixsuffixname.go",
|
||||||
|
"refvars.go",
|
||||||
|
"transformer.go",
|
||||||
|
"util.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/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",
|
||||||
|
"//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/transformers/config:all-srcs",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
40
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/BUILD
generated
vendored
Normal file
40
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/BUILD
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"constants.go",
|
||||||
|
"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/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"],
|
||||||
|
)
|
42
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/constants.go
generated
vendored
Normal file
42
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/constants.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
// Annotation is to mark a field as annotations.
|
||||||
|
// "x-kubernetes-annotation": ""
|
||||||
|
const Annotation = "x-kubernetes-annotation"
|
||||||
|
|
||||||
|
// LabelSelector is to mark a field as LabelSelector
|
||||||
|
// "x-kubernetes-label-selector": ""
|
||||||
|
const LabelSelector = "x-kubernetes-label-selector"
|
||||||
|
|
||||||
|
// Identity is to mark a field as Identity
|
||||||
|
// "x-kubernetes-identity": ""
|
||||||
|
const Identity = "x-kubernetes-identity"
|
||||||
|
|
||||||
|
// Version marks the type version of an object ref field
|
||||||
|
// "x-kubernetes-object-ref-api-version": <apiVersion name>
|
||||||
|
const Version = "x-kubernetes-object-ref-api-version"
|
||||||
|
|
||||||
|
// Kind marks the type name of an object ref field
|
||||||
|
// "x-kubernetes-object-ref-kind": <kind name>
|
||||||
|
const Kind = "x-kubernetes-object-ref-kind"
|
||||||
|
|
||||||
|
// NameKey marks the field key that refers to an object of an object ref field
|
||||||
|
// "x-kubernetes-object-ref-name-key": "name"
|
||||||
|
// default is "name"
|
||||||
|
const NameKey = "x-kubernetes-object-ref-name-key"
|
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
|
||||||
|
|
||||||
|
`
|
157
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/commonlabels.go
generated
vendored
Normal file
157
vendor/sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig/commonlabels.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
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/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
|
||||||
|
`
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user