mirror of
https://github.com/kubernetes/sample-controller.git
synced 2025-02-20 23:56:23 +08:00
Merge pull request #51321 from mengqiy/kubectl_apply_openapi
Automatic merge from submit-queue (batch tested with PRs 51321, 55969, 55039, 56183, 55976). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Kubectl apply and strategic merge patch using openapi - [x] support openapi in strategic merge patch - [x] test openapi in strategic merge patch - [x] kubectl apply use openapi to calculate diff be default. It will fall back to use baked-in types when openapi is not available. - [x] test openapi in kubectl apply Fixes: kubernetes/kubectl#55 ```release-note kubectl apply use openapi to calculate diff be default. It will fall back to use baked-in types when openapi is not available. ``` /assign @apelisse Kubernetes-commit: e412ad5393b8c949474b904616fc411c3aa478a9
This commit is contained in:
commit
e34822d285
366
Godeps/Godeps.json
generated
366
Godeps/Godeps.json
generated
@ -240,731 +240,735 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/apps/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/apps/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/apps/v1beta2",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authentication/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authentication/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authorization/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authorization/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/autoscaling/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/batch/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/batch/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/batch/v2alpha1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/certificates/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/core/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/extensions/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/networking/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/policy/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/rbac/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/rbac/v1alpha1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/rbac/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/settings/v1alpha1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/storage/v1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/storage/v1alpha1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/storage/v1beta1",
|
||||
"Rev": "5d9772a8cd731dd1b872ea0e753eebe4d77d976d"
|
||||
"Rev": "bc27cbc7921e1343f1320ec077c51729064fc98f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1alpha1",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||
"Rev": "8b356a985a4a3415073ed7e5e897c01e374383f6"
|
||||
"Rev": "f751f89784950a0354a8e96d65e58dd5d44d5bb7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/discovery",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/discovery/fake",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/admissionregistration",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/admissionregistration/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/admissionregistration/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/apps",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/apps/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/apps/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/apps/v1beta2",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/autoscaling",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/autoscaling/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/autoscaling/v2beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/batch",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/batch/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/batch/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/batch/v2alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/certificates",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/certificates/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/core",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/core/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/extensions",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/extensions/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/internalinterfaces",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/networking",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/networking/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/policy",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/policy/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/rbac",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/rbac/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/rbac/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/rbac/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/scheduling",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/scheduling/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/settings",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/settings/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/storage",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/storage/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/storage/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/informers/storage/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/scheme",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta2",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/core/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/networking/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/policy/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/admissionregistration/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/admissionregistration/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/apps/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/apps/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/apps/v1beta2",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/autoscaling/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/autoscaling/v2beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/batch/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/batch/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/batch/v2alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/certificates/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/core/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/extensions/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/networking/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/policy/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/rbac/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/rbac/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/rbac/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/scheduling/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/settings/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/storage/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/storage/v1alpha1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/listers/storage/v1beta1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/pkg/version",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/rest",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/rest/watch",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/testing",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/auth",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/cache",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/clientcmd",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/clientcmd/api",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/clientcmd/api/latest",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/clientcmd/api/v1",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/metrics",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/pager",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/record",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/tools/reference",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/transport",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/util/buffer",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/util/cert",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/util/flowcontrol",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/util/homedir",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/util/integer",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/util/workqueue",
|
||||
"Rev": "be57bfe69be6afb72b0644ce503d9404deaaa916"
|
||||
"Rev": "d2ae8ddbe0283932e6f40f37220ef371a6f0218a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/common",
|
||||
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
||||
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
1
vendor/k8s.io/api/apps/v1/types.go
generated
vendored
1
vendor/k8s.io/api/apps/v1/types.go
generated
vendored
@ -28,6 +28,7 @@ const (
|
||||
StatefulSetRevisionLabel = ControllerRevisionHashLabelKey
|
||||
DeprecatedRollbackTo = "deprecated.deployment.rollback.to"
|
||||
DeprecatedTemplateGeneration = "deprecated.daemonset.template.generation"
|
||||
StatefulSetPodNameLabel = "statefulset.kubernetes.io/pod-name"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
|
1
vendor/k8s.io/api/apps/v1beta1/types.go
generated
vendored
1
vendor/k8s.io/api/apps/v1beta1/types.go
generated
vendored
@ -26,6 +26,7 @@ import (
|
||||
const (
|
||||
ControllerRevisionHashLabelKey = "controller-revision-hash"
|
||||
StatefulSetRevisionLabel = ControllerRevisionHashLabelKey
|
||||
StatefulSetPodNameLabel = "statefulset.kubernetes.io/pod-name"
|
||||
)
|
||||
|
||||
// ScaleSpec describes the attributes of a scale subresource
|
||||
|
1
vendor/k8s.io/api/apps/v1beta2/types.go
generated
vendored
1
vendor/k8s.io/api/apps/v1beta2/types.go
generated
vendored
@ -28,6 +28,7 @@ const (
|
||||
StatefulSetRevisionLabel = ControllerRevisionHashLabelKey
|
||||
DeprecatedRollbackTo = "deprecated.deployment.rollback.to"
|
||||
DeprecatedTemplateGeneration = "deprecated.daemonset.template.generation"
|
||||
StatefulSetPodNameLabel = "statefulset.kubernetes.io/pod-name"
|
||||
)
|
||||
|
||||
// ScaleSpec describes the attributes of a scale subresource
|
||||
|
2609
vendor/k8s.io/api/core/v1/generated.pb.go
generated
vendored
2609
vendor/k8s.io/api/core/v1/generated.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
46
vendor/k8s.io/api/core/v1/generated.proto
generated
vendored
46
vendor/k8s.io/api/core/v1/generated.proto
generated
vendored
@ -2681,6 +2681,38 @@ message PodCondition {
|
||||
optional string message = 6;
|
||||
}
|
||||
|
||||
// PodDNSConfig defines the DNS parameters of a pod in addition to
|
||||
// those generated from DNSPolicy.
|
||||
message PodDNSConfig {
|
||||
// A list of DNS name server IP addresses.
|
||||
// This will be appended to the base nameservers generated from DNSPolicy.
|
||||
// Duplicated nameservers will be removed.
|
||||
// +optional
|
||||
repeated string nameservers = 1;
|
||||
|
||||
// A list of DNS search domains for host-name lookup.
|
||||
// This will be appended to the base search paths generated from DNSPolicy.
|
||||
// Duplicated search paths will be removed.
|
||||
// +optional
|
||||
repeated string searches = 2;
|
||||
|
||||
// A list of DNS resolver options.
|
||||
// This will be merged with the base options generated from DNSPolicy.
|
||||
// Duplicated entries will be removed. Resolution options given in Options
|
||||
// will override those that appear in the base DNSPolicy.
|
||||
// +optional
|
||||
repeated PodDNSConfigOption options = 3;
|
||||
}
|
||||
|
||||
// PodDNSConfigOption defines DNS resolver options of a pod.
|
||||
message PodDNSConfigOption {
|
||||
// Required.
|
||||
optional string name = 1;
|
||||
|
||||
// +optional
|
||||
optional string value = 2;
|
||||
}
|
||||
|
||||
// PodExecOptions is the query options to a Pod's remote exec call.
|
||||
// ---
|
||||
// TODO: This is largely identical to PodAttachOptions above, make sure they stay in sync and see about merging
|
||||
@ -2905,10 +2937,12 @@ message PodSpec {
|
||||
// +optional
|
||||
optional int64 activeDeadlineSeconds = 5;
|
||||
|
||||
// Set DNS policy for containers within the pod.
|
||||
// One of 'ClusterFirstWithHostNet', 'ClusterFirst' or 'Default'.
|
||||
// Set DNS policy for the pod.
|
||||
// Defaults to "ClusterFirst".
|
||||
// To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.
|
||||
// Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'.
|
||||
// DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy.
|
||||
// To have DNS options set along with hostNetwork, you have to specify DNS policy
|
||||
// explicitly to 'ClusterFirstWithHostNet'.
|
||||
// +optional
|
||||
optional string dnsPolicy = 6;
|
||||
|
||||
@ -3017,6 +3051,12 @@ message PodSpec {
|
||||
// The higher the value, the higher the priority.
|
||||
// +optional
|
||||
optional int32 priority = 25;
|
||||
|
||||
// Specifies the DNS parameters of a pod.
|
||||
// Parameters specified here will be merged to the generated DNS
|
||||
// configuration based on DNSPolicy.
|
||||
// +optional
|
||||
optional PodDNSConfig dnsConfig = 26;
|
||||
}
|
||||
|
||||
// PodStatus represents information about the status of a pod. Status may trail the actual
|
||||
|
49
vendor/k8s.io/api/core/v1/types.go
generated
vendored
49
vendor/k8s.io/api/core/v1/types.go
generated
vendored
@ -2431,6 +2431,11 @@ const (
|
||||
// determined by kubelet) DNS settings.
|
||||
DNSDefault DNSPolicy = "Default"
|
||||
|
||||
// DNSNone indicates that the pod should use empty DNS settings. DNS
|
||||
// parameters such as nameservers and search paths should be defined via
|
||||
// DNSConfig.
|
||||
DNSNone DNSPolicy = "None"
|
||||
|
||||
DefaultTerminationGracePeriodSeconds = 30
|
||||
)
|
||||
|
||||
@ -2760,10 +2765,12 @@ type PodSpec struct {
|
||||
// Value must be a positive integer.
|
||||
// +optional
|
||||
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" protobuf:"varint,5,opt,name=activeDeadlineSeconds"`
|
||||
// Set DNS policy for containers within the pod.
|
||||
// One of 'ClusterFirstWithHostNet', 'ClusterFirst' or 'Default'.
|
||||
// Set DNS policy for the pod.
|
||||
// Defaults to "ClusterFirst".
|
||||
// To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.
|
||||
// Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'.
|
||||
// DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy.
|
||||
// To have DNS options set along with hostNetwork, you have to specify DNS policy
|
||||
// explicitly to 'ClusterFirstWithHostNet'.
|
||||
// +optional
|
||||
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty" protobuf:"bytes,6,opt,name=dnsPolicy,casttype=DNSPolicy"`
|
||||
// NodeSelector is a selector which must be true for the pod to fit on a node.
|
||||
@ -2856,6 +2863,11 @@ type PodSpec struct {
|
||||
// The higher the value, the higher the priority.
|
||||
// +optional
|
||||
Priority *int32 `json:"priority,omitempty" protobuf:"bytes,25,opt,name=priority"`
|
||||
// Specifies the DNS parameters of a pod.
|
||||
// Parameters specified here will be merged to the generated DNS
|
||||
// configuration based on DNSPolicy.
|
||||
// +optional
|
||||
DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" protobuf:"bytes,26,opt,name=dnsConfig"`
|
||||
}
|
||||
|
||||
// HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the
|
||||
@ -2923,6 +2935,35 @@ const (
|
||||
PodQOSBestEffort PodQOSClass = "BestEffort"
|
||||
)
|
||||
|
||||
// PodDNSConfig defines the DNS parameters of a pod in addition to
|
||||
// those generated from DNSPolicy.
|
||||
type PodDNSConfig struct {
|
||||
// A list of DNS name server IP addresses.
|
||||
// This will be appended to the base nameservers generated from DNSPolicy.
|
||||
// Duplicated nameservers will be removed.
|
||||
// +optional
|
||||
Nameservers []string `json:"nameservers,omitempty" protobuf:"bytes,1,rep,name=nameservers"`
|
||||
// A list of DNS search domains for host-name lookup.
|
||||
// This will be appended to the base search paths generated from DNSPolicy.
|
||||
// Duplicated search paths will be removed.
|
||||
// +optional
|
||||
Searches []string `json:"searches,omitempty" protobuf:"bytes,2,rep,name=searches"`
|
||||
// A list of DNS resolver options.
|
||||
// This will be merged with the base options generated from DNSPolicy.
|
||||
// Duplicated entries will be removed. Resolution options given in Options
|
||||
// will override those that appear in the base DNSPolicy.
|
||||
// +optional
|
||||
Options []PodDNSConfigOption `json:"options,omitempty" protobuf:"bytes,3,rep,name=options"`
|
||||
}
|
||||
|
||||
// PodDNSConfigOption defines DNS resolver options of a pod.
|
||||
type PodDNSConfigOption struct {
|
||||
// Required.
|
||||
Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
|
||||
// +optional
|
||||
Value *string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"`
|
||||
}
|
||||
|
||||
// PodStatus represents information about the status of a pod. Status may trail the actual
|
||||
// state of a system.
|
||||
type PodStatus struct {
|
||||
@ -3940,8 +3981,6 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
// Namespace prefix for opaque counted resources (alpha).
|
||||
ResourceOpaqueIntPrefix = "pod.alpha.kubernetes.io/opaque-int-resource-"
|
||||
// Default namespace prefix.
|
||||
ResourceDefaultNamespacePrefix = "kubernetes.io/"
|
||||
// Name prefix for huge page resources (alpha).
|
||||
|
23
vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go
generated
vendored
23
vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go
generated
vendored
@ -1356,6 +1356,26 @@ func (PodCondition) SwaggerDoc() map[string]string {
|
||||
return map_PodCondition
|
||||
}
|
||||
|
||||
var map_PodDNSConfig = map[string]string{
|
||||
"": "PodDNSConfig defines the DNS parameters of a pod in addition to those generated from DNSPolicy.",
|
||||
"nameservers": "A list of DNS name server IP addresses. This will be appended to the base nameservers generated from DNSPolicy. Duplicated nameservers will be removed.",
|
||||
"searches": "A list of DNS search domains for host-name lookup. This will be appended to the base search paths generated from DNSPolicy. Duplicated search paths will be removed.",
|
||||
"options": "A list of DNS resolver options. This will be merged with the base options generated from DNSPolicy. Duplicated entries will be removed. Resolution options given in Options will override those that appear in the base DNSPolicy.",
|
||||
}
|
||||
|
||||
func (PodDNSConfig) SwaggerDoc() map[string]string {
|
||||
return map_PodDNSConfig
|
||||
}
|
||||
|
||||
var map_PodDNSConfigOption = map[string]string{
|
||||
"": "PodDNSConfigOption defines DNS resolver options of a pod.",
|
||||
"name": "Required.",
|
||||
}
|
||||
|
||||
func (PodDNSConfigOption) SwaggerDoc() map[string]string {
|
||||
return map_PodDNSConfigOption
|
||||
}
|
||||
|
||||
var map_PodExecOptions = map[string]string{
|
||||
"": "PodExecOptions is the query options to a Pod's remote exec call.",
|
||||
"stdin": "Redirect the standard input stream of the pod for this call. Defaults to false.",
|
||||
@ -1444,7 +1464,7 @@ var map_PodSpec = map[string]string{
|
||||
"restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy",
|
||||
"terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.",
|
||||
"activeDeadlineSeconds": "Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.",
|
||||
"dnsPolicy": "Set DNS policy for containers within the pod. One of 'ClusterFirstWithHostNet', 'ClusterFirst' or 'Default'. Defaults to \"ClusterFirst\". To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.",
|
||||
"dnsPolicy": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.",
|
||||
"nodeSelector": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/",
|
||||
"serviceAccountName": "ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/",
|
||||
"serviceAccount": "DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. Deprecated: Use serviceAccountName instead.",
|
||||
@ -1463,6 +1483,7 @@ var map_PodSpec = map[string]string{
|
||||
"hostAliases": "HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods.",
|
||||
"priorityClassName": "If specified, indicates the pod's priority. \"SYSTEM\" is a special keyword which indicates the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default.",
|
||||
"priority": "The priority value. Various system components use this field to find the priority of the pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.",
|
||||
"dnsConfig": "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.",
|
||||
}
|
||||
|
||||
func (PodSpec) SwaggerDoc() map[string]string {
|
||||
|
67
vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go
generated
vendored
67
vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go
generated
vendored
@ -3483,6 +3483,64 @@ func (in *PodCondition) DeepCopy() *PodCondition {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodDNSConfig) DeepCopyInto(out *PodDNSConfig) {
|
||||
*out = *in
|
||||
if in.Nameservers != nil {
|
||||
in, out := &in.Nameservers, &out.Nameservers
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Searches != nil {
|
||||
in, out := &in.Searches, &out.Searches
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Options != nil {
|
||||
in, out := &in.Options, &out.Options
|
||||
*out = make([]PodDNSConfigOption, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodDNSConfig.
|
||||
func (in *PodDNSConfig) DeepCopy() *PodDNSConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodDNSConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodDNSConfigOption) DeepCopyInto(out *PodDNSConfigOption) {
|
||||
*out = *in
|
||||
if in.Value != nil {
|
||||
in, out := &in.Value, &out.Value
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodDNSConfigOption.
|
||||
func (in *PodDNSConfigOption) DeepCopy() *PodDNSConfigOption {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodDNSConfigOption)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodExecOptions) DeepCopyInto(out *PodExecOptions) {
|
||||
*out = *in
|
||||
@ -3853,6 +3911,15 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) {
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.DNSConfig != nil {
|
||||
in, out := &in.DNSConfig, &out.DNSConfig
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(PodDNSConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
19
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/BUILD
generated
vendored
19
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/BUILD
generated
vendored
@ -9,26 +9,38 @@ load(
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["patch_test.go"],
|
||||
data = [
|
||||
"testdata/swagger-merge-item.json",
|
||||
"testdata/swagger-precision-item.json",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/mergepatch:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["patch.go"],
|
||||
srcs = [
|
||||
"errors.go",
|
||||
"meta.go",
|
||||
"patch.go",
|
||||
"types.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/mergepatch:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/third_party/forked/golang/json:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -41,6 +53,9 @@ filegroup(
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/testing:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
49
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/errors.go
generated
vendored
Normal file
49
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/errors.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
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 strategicpatch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type LookupPatchMetaError struct {
|
||||
Path string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e LookupPatchMetaError) Error() string {
|
||||
return fmt.Sprintf("LookupPatchMetaError(%s): %v", e.Path, e.Err)
|
||||
}
|
||||
|
||||
type FieldNotFoundError struct {
|
||||
Path string
|
||||
Field string
|
||||
}
|
||||
|
||||
func (e FieldNotFoundError) Error() string {
|
||||
return fmt.Sprintf("unable to find api field %q in %s", e.Field, e.Path)
|
||||
}
|
||||
|
||||
type InvalidTypeError struct {
|
||||
Path string
|
||||
Expected string
|
||||
Actual string
|
||||
}
|
||||
|
||||
func (e InvalidTypeError) Error() string {
|
||||
return fmt.Sprintf("invalid type for %s: got %q, expected %q", e.Path, e.Actual, e.Expected)
|
||||
}
|
194
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go
generated
vendored
Normal file
194
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/meta.go
generated
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
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 strategicpatch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||
forkedjson "k8s.io/apimachinery/third_party/forked/golang/json"
|
||||
openapi "k8s.io/kube-openapi/pkg/util/proto"
|
||||
)
|
||||
|
||||
type PatchMeta struct {
|
||||
patchStrategies []string
|
||||
patchMergeKey string
|
||||
}
|
||||
|
||||
func (pm PatchMeta) GetPatchStrategies() []string {
|
||||
if pm.patchStrategies == nil {
|
||||
return []string{}
|
||||
}
|
||||
return pm.patchStrategies
|
||||
}
|
||||
|
||||
func (pm PatchMeta) SetPatchStrategies(ps []string) {
|
||||
pm.patchStrategies = ps
|
||||
}
|
||||
|
||||
func (pm PatchMeta) GetPatchMergeKey() string {
|
||||
return pm.patchMergeKey
|
||||
}
|
||||
|
||||
func (pm PatchMeta) SetPatchMergeKey(pmk string) {
|
||||
pm.patchMergeKey = pmk
|
||||
}
|
||||
|
||||
type LookupPatchMeta interface {
|
||||
// LookupPatchMetadataForStruct gets subschema and the patch metadata (e.g. patch strategy and merge key) for map.
|
||||
LookupPatchMetadataForStruct(key string) (LookupPatchMeta, PatchMeta, error)
|
||||
// LookupPatchMetadataForSlice get subschema and the patch metadata for slice.
|
||||
LookupPatchMetadataForSlice(key string) (LookupPatchMeta, PatchMeta, error)
|
||||
// Get the type name of the field
|
||||
Name() string
|
||||
}
|
||||
|
||||
type PatchMetaFromStruct struct {
|
||||
T reflect.Type
|
||||
}
|
||||
|
||||
func NewPatchMetaFromStruct(dataStruct interface{}) (PatchMetaFromStruct, error) {
|
||||
t, err := getTagStructType(dataStruct)
|
||||
return PatchMetaFromStruct{T: t}, err
|
||||
}
|
||||
|
||||
var _ LookupPatchMeta = PatchMetaFromStruct{}
|
||||
|
||||
func (s PatchMetaFromStruct) LookupPatchMetadataForStruct(key string) (LookupPatchMeta, PatchMeta, error) {
|
||||
fieldType, fieldPatchStrategies, fieldPatchMergeKey, err := forkedjson.LookupPatchMetadataForStruct(s.T, key)
|
||||
if err != nil {
|
||||
return nil, PatchMeta{}, err
|
||||
}
|
||||
|
||||
return PatchMetaFromStruct{T: fieldType},
|
||||
PatchMeta{
|
||||
patchStrategies: fieldPatchStrategies,
|
||||
patchMergeKey: fieldPatchMergeKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s PatchMetaFromStruct) LookupPatchMetadataForSlice(key string) (LookupPatchMeta, PatchMeta, error) {
|
||||
subschema, patchMeta, err := s.LookupPatchMetadataForStruct(key)
|
||||
if err != nil {
|
||||
return nil, PatchMeta{}, err
|
||||
}
|
||||
elemPatchMetaFromStruct := subschema.(PatchMetaFromStruct)
|
||||
t := elemPatchMetaFromStruct.T
|
||||
|
||||
var elemType reflect.Type
|
||||
switch t.Kind() {
|
||||
// If t is an array or a slice, get the element type.
|
||||
// If element is still an array or a slice, return an error.
|
||||
// Otherwise, return element type.
|
||||
case reflect.Array, reflect.Slice:
|
||||
elemType = t.Elem()
|
||||
if elemType.Kind() == reflect.Array || elemType.Kind() == reflect.Slice {
|
||||
return nil, PatchMeta{}, errors.New("unexpected slice of slice")
|
||||
}
|
||||
// If t is an pointer, get the underlying element.
|
||||
// If the underlying element is neither an array nor a slice, the pointer is pointing to a slice,
|
||||
// e.g. https://github.com/kubernetes/kubernetes/blob/bc22e206c79282487ea0bf5696d5ccec7e839a76/staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch_test.go#L2782-L2822
|
||||
// If the underlying element is either an array or a slice, return its element type.
|
||||
case reflect.Ptr:
|
||||
t = t.Elem()
|
||||
if t.Kind() == reflect.Array || t.Kind() == reflect.Slice {
|
||||
t = t.Elem()
|
||||
}
|
||||
elemType = t
|
||||
default:
|
||||
return nil, PatchMeta{}, fmt.Errorf("expected slice or array type, but got: %s", s.T.Kind().String())
|
||||
}
|
||||
|
||||
return PatchMetaFromStruct{T: elemType}, patchMeta, nil
|
||||
}
|
||||
|
||||
func (s PatchMetaFromStruct) Name() string {
|
||||
return s.T.Kind().String()
|
||||
}
|
||||
|
||||
func getTagStructType(dataStruct interface{}) (reflect.Type, error) {
|
||||
if dataStruct == nil {
|
||||
return nil, mergepatch.ErrBadArgKind(struct{}{}, nil)
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(dataStruct)
|
||||
// Get the underlying type for pointers
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Struct {
|
||||
return nil, mergepatch.ErrBadArgKind(struct{}{}, dataStruct)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func GetTagStructTypeOrDie(dataStruct interface{}) reflect.Type {
|
||||
t, err := getTagStructType(dataStruct)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
type PatchMetaFromOpenAPI struct {
|
||||
Schema openapi.Schema
|
||||
}
|
||||
|
||||
func NewPatchMetaFromOpenAPI(s openapi.Schema) PatchMetaFromOpenAPI {
|
||||
return PatchMetaFromOpenAPI{Schema: s}
|
||||
}
|
||||
|
||||
var _ LookupPatchMeta = PatchMetaFromOpenAPI{}
|
||||
|
||||
func (s PatchMetaFromOpenAPI) LookupPatchMetadataForStruct(key string) (LookupPatchMeta, PatchMeta, error) {
|
||||
if s.Schema == nil {
|
||||
return nil, PatchMeta{}, nil
|
||||
}
|
||||
kindItem := NewKindItem(key, s.Schema.GetPath())
|
||||
s.Schema.Accept(kindItem)
|
||||
|
||||
err := kindItem.Error()
|
||||
if err != nil {
|
||||
return nil, PatchMeta{}, err
|
||||
}
|
||||
return PatchMetaFromOpenAPI{Schema: kindItem.subschema},
|
||||
kindItem.patchmeta, nil
|
||||
}
|
||||
|
||||
func (s PatchMetaFromOpenAPI) LookupPatchMetadataForSlice(key string) (LookupPatchMeta, PatchMeta, error) {
|
||||
if s.Schema == nil {
|
||||
return nil, PatchMeta{}, nil
|
||||
}
|
||||
sliceItem := NewSliceItem(key, s.Schema.GetPath())
|
||||
s.Schema.Accept(sliceItem)
|
||||
|
||||
err := sliceItem.Error()
|
||||
if err != nil {
|
||||
return nil, PatchMeta{}, err
|
||||
}
|
||||
return PatchMetaFromOpenAPI{Schema: sliceItem.subschema},
|
||||
sliceItem.patchmeta, nil
|
||||
}
|
||||
|
||||
func (s PatchMetaFromOpenAPI) Name() string {
|
||||
schema := s.Schema
|
||||
return schema.GetName()
|
||||
}
|
302
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go
generated
vendored
302
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go
generated
vendored
@ -25,7 +25,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||
forkedjson "k8s.io/apimachinery/third_party/forked/golang/json"
|
||||
)
|
||||
|
||||
// An alternate implementation of JSON Merge Patch
|
||||
@ -93,6 +92,16 @@ type MergeOptions struct {
|
||||
// return a patch that yields the modified document when applied to the original document, or an error
|
||||
// if either of the two documents is invalid.
|
||||
func CreateTwoWayMergePatch(original, modified []byte, dataStruct interface{}, fns ...mergepatch.PreconditionFunc) ([]byte, error) {
|
||||
schema, err := NewPatchMetaFromStruct(dataStruct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return CreateTwoWayMergePatchUsingLookupPatchMeta(original, modified, schema, fns...)
|
||||
}
|
||||
|
||||
func CreateTwoWayMergePatchUsingLookupPatchMeta(
|
||||
original, modified []byte, schema LookupPatchMeta, fns ...mergepatch.PreconditionFunc) ([]byte, error) {
|
||||
originalMap := map[string]interface{}{}
|
||||
if len(original) > 0 {
|
||||
if err := json.Unmarshal(original, &originalMap); err != nil {
|
||||
@ -107,7 +116,7 @@ func CreateTwoWayMergePatch(original, modified []byte, dataStruct interface{}, f
|
||||
}
|
||||
}
|
||||
|
||||
patchMap, err := CreateTwoWayMergeMapPatch(originalMap, modifiedMap, dataStruct, fns...)
|
||||
patchMap, err := CreateTwoWayMergeMapPatchUsingLookupPatchMeta(originalMap, modifiedMap, schema, fns...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -119,15 +128,19 @@ func CreateTwoWayMergePatch(original, modified []byte, dataStruct interface{}, f
|
||||
// encoded JSONMap.
|
||||
// The serialized version of the map can then be passed to StrategicMergeMapPatch.
|
||||
func CreateTwoWayMergeMapPatch(original, modified JSONMap, dataStruct interface{}, fns ...mergepatch.PreconditionFunc) (JSONMap, error) {
|
||||
t, err := getTagStructType(dataStruct)
|
||||
schema, err := NewPatchMetaFromStruct(dataStruct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return CreateTwoWayMergeMapPatchUsingLookupPatchMeta(original, modified, schema, fns...)
|
||||
}
|
||||
|
||||
func CreateTwoWayMergeMapPatchUsingLookupPatchMeta(original, modified JSONMap, schema LookupPatchMeta, fns ...mergepatch.PreconditionFunc) (JSONMap, error) {
|
||||
diffOptions := DiffOptions{
|
||||
SetElementOrder: true,
|
||||
}
|
||||
patchMap, err := diffMaps(original, modified, t, diffOptions)
|
||||
patchMap, err := diffMaps(original, modified, schema, diffOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -152,12 +165,9 @@ func CreateTwoWayMergeMapPatch(original, modified JSONMap, dataStruct interface{
|
||||
// - IFF list of primitives && merge strategy - use parallel deletion list
|
||||
// - IFF list of maps or primitives with replace strategy (default) - set patch value to the value in modified
|
||||
// - Build $retainKeys directive for fields with retainKeys patch strategy
|
||||
func diffMaps(original, modified map[string]interface{}, t reflect.Type, diffOptions DiffOptions) (map[string]interface{}, error) {
|
||||
func diffMaps(original, modified map[string]interface{}, schema LookupPatchMeta, diffOptions DiffOptions) (map[string]interface{}, error) {
|
||||
patch := map[string]interface{}{}
|
||||
// Get the underlying type for pointers
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
// This will be used to build the $retainKeys directive sent in the patch
|
||||
retainKeysList := make([]interface{}, 0, len(modified))
|
||||
|
||||
@ -199,10 +209,10 @@ func diffMaps(original, modified map[string]interface{}, t reflect.Type, diffOpt
|
||||
switch originalValueTyped := originalValue.(type) {
|
||||
case map[string]interface{}:
|
||||
modifiedValueTyped := modifiedValue.(map[string]interface{})
|
||||
err = handleMapDiff(key, originalValueTyped, modifiedValueTyped, patch, t, diffOptions)
|
||||
err = handleMapDiff(key, originalValueTyped, modifiedValueTyped, patch, schema, diffOptions)
|
||||
case []interface{}:
|
||||
modifiedValueTyped := modifiedValue.([]interface{})
|
||||
err = handleSliceDiff(key, originalValueTyped, modifiedValueTyped, patch, t, diffOptions)
|
||||
err = handleSliceDiff(key, originalValueTyped, modifiedValueTyped, patch, schema, diffOptions)
|
||||
default:
|
||||
replacePatchFieldIfNotEqual(key, originalValue, modifiedValue, patch, diffOptions)
|
||||
}
|
||||
@ -249,8 +259,9 @@ func handleDirectiveMarker(key string, originalValue, modifiedValue interface{},
|
||||
// patch is the patch map that contains key and the updated value, and it is the parent of originalValue, modifiedValue
|
||||
// diffOptions contains multiple options to control how we do the diff.
|
||||
func handleMapDiff(key string, originalValue, modifiedValue, patch map[string]interface{},
|
||||
t reflect.Type, diffOptions DiffOptions) error {
|
||||
fieldType, fieldPatchStrategies, _, err := forkedjson.LookupPatchMetadata(t, key)
|
||||
schema LookupPatchMeta, diffOptions DiffOptions) error {
|
||||
subschema, patchMeta, err := schema.LookupPatchMetadataForStruct(key)
|
||||
|
||||
if err != nil {
|
||||
// We couldn't look up metadata for the field
|
||||
// If the values are identical, this doesn't matter, no patch is needed
|
||||
@ -260,7 +271,7 @@ func handleMapDiff(key string, originalValue, modifiedValue, patch map[string]in
|
||||
// Otherwise, return the error
|
||||
return err
|
||||
}
|
||||
retainKeys, patchStrategy, err := extractRetainKeysPatchStrategy(fieldPatchStrategies)
|
||||
retainKeys, patchStrategy, err := extractRetainKeysPatchStrategy(patchMeta.GetPatchStrategies())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -272,7 +283,7 @@ func handleMapDiff(key string, originalValue, modifiedValue, patch map[string]in
|
||||
patch[key] = modifiedValue
|
||||
}
|
||||
default:
|
||||
patchValue, err := diffMaps(originalValue, modifiedValue, fieldType, diffOptions)
|
||||
patchValue, err := diffMaps(originalValue, modifiedValue, subschema, diffOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -291,8 +302,8 @@ func handleMapDiff(key string, originalValue, modifiedValue, patch map[string]in
|
||||
// patch is the patch map that contains key and the updated value, and it is the parent of originalValue, modifiedValue
|
||||
// diffOptions contains multiple options to control how we do the diff.
|
||||
func handleSliceDiff(key string, originalValue, modifiedValue []interface{}, patch map[string]interface{},
|
||||
t reflect.Type, diffOptions DiffOptions) error {
|
||||
fieldType, fieldPatchStrategies, fieldPatchMergeKey, err := forkedjson.LookupPatchMetadata(t, key)
|
||||
schema LookupPatchMeta, diffOptions DiffOptions) error {
|
||||
subschema, patchMeta, err := schema.LookupPatchMetadataForSlice(key)
|
||||
if err != nil {
|
||||
// We couldn't look up metadata for the field
|
||||
// If the values are identical, this doesn't matter, no patch is needed
|
||||
@ -302,7 +313,7 @@ func handleSliceDiff(key string, originalValue, modifiedValue []interface{}, pat
|
||||
// Otherwise, return the error
|
||||
return err
|
||||
}
|
||||
retainKeys, patchStrategy, err := extractRetainKeysPatchStrategy(fieldPatchStrategies)
|
||||
retainKeys, patchStrategy, err := extractRetainKeysPatchStrategy(patchMeta.GetPatchStrategies())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -310,7 +321,7 @@ func handleSliceDiff(key string, originalValue, modifiedValue []interface{}, pat
|
||||
// Merge the 2 slices using mergePatchKey
|
||||
case mergeDirective:
|
||||
diffOptions.BuildRetainKeysDirective = retainKeys
|
||||
addList, deletionList, setOrderList, err := diffLists(originalValue, modifiedValue, fieldType.Elem(), fieldPatchMergeKey, diffOptions)
|
||||
addList, deletionList, setOrderList, err := diffLists(originalValue, modifiedValue, subschema, patchMeta.GetPatchMergeKey(), diffOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -537,7 +548,7 @@ func normalizeSliceOrder(toSort, order []interface{}, mergeKey string, kind refl
|
||||
// another list to set the order of the list
|
||||
// Only list of primitives with merge strategy will generate a parallel deletion list.
|
||||
// These two lists should yield modified when applied to original, for lists with merge semantics.
|
||||
func diffLists(original, modified []interface{}, t reflect.Type, mergeKey string, diffOptions DiffOptions) ([]interface{}, []interface{}, []interface{}, error) {
|
||||
func diffLists(original, modified []interface{}, schema LookupPatchMeta, mergeKey string, diffOptions DiffOptions) ([]interface{}, []interface{}, []interface{}, error) {
|
||||
if len(original) == 0 {
|
||||
// Both slices are empty - do nothing
|
||||
if len(modified) == 0 || diffOptions.IgnoreChangesAndAdditions {
|
||||
@ -557,7 +568,7 @@ func diffLists(original, modified []interface{}, t reflect.Type, mergeKey string
|
||||
kind := elementType.Kind()
|
||||
switch kind {
|
||||
case reflect.Map:
|
||||
patchList, deleteList, err = diffListsOfMaps(original, modified, t, mergeKey, diffOptions)
|
||||
patchList, deleteList, err = diffListsOfMaps(original, modified, schema, mergeKey, diffOptions)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@ -703,15 +714,15 @@ func compareListValuesAtIndex(list1Inbounds, list2Inbounds bool, list1Value, lis
|
||||
// diffListsOfMaps takes a pair of lists and
|
||||
// returns a (recursive) strategic merge patch list contains additions and changes and
|
||||
// a deletion list contains deletions
|
||||
func diffListsOfMaps(original, modified []interface{}, t reflect.Type, mergeKey string, diffOptions DiffOptions) ([]interface{}, []interface{}, error) {
|
||||
func diffListsOfMaps(original, modified []interface{}, schema LookupPatchMeta, mergeKey string, diffOptions DiffOptions) ([]interface{}, []interface{}, error) {
|
||||
patch := make([]interface{}, 0, len(modified))
|
||||
deletionList := make([]interface{}, 0, len(original))
|
||||
|
||||
originalSorted, err := sortMergeListsByNameArray(original, t, mergeKey, false)
|
||||
originalSorted, err := sortMergeListsByNameArray(original, schema, mergeKey, false)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
modifiedSorted, err := sortMergeListsByNameArray(modified, t, mergeKey, false)
|
||||
modifiedSorted, err := sortMergeListsByNameArray(modified, schema, mergeKey, false)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -746,7 +757,7 @@ func diffListsOfMaps(original, modified []interface{}, t reflect.Type, mergeKey
|
||||
switch {
|
||||
case bothInBounds && ItemMatchesOriginalAndModifiedSlice(originalElementMergeKeyValueString, modifiedElementMergeKeyValueString):
|
||||
// Merge key values are equal, so recurse
|
||||
patchValue, err := diffMaps(originalElement, modifiedElement, t, diffOptions)
|
||||
patchValue, err := diffMaps(originalElement, modifiedElement, schema, diffOptions)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -799,6 +810,15 @@ func getMapAndMergeKeyValueByIndex(index int, mergeKey string, listOfMaps []inte
|
||||
// must be json encoded content. A patch can be created from an original and a modified document
|
||||
// by calling CreateStrategicMergePatch.
|
||||
func StrategicMergePatch(original, patch []byte, dataStruct interface{}) ([]byte, error) {
|
||||
schema, err := NewPatchMetaFromStruct(dataStruct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return StrategicMergePatchUsingLookupPatchMeta(original, patch, schema)
|
||||
}
|
||||
|
||||
func StrategicMergePatchUsingLookupPatchMeta(original, patch []byte, schema LookupPatchMeta) ([]byte, error) {
|
||||
originalMap, err := handleUnmarshal(original)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -808,7 +828,7 @@ func StrategicMergePatch(original, patch []byte, dataStruct interface{}) ([]byte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := StrategicMergeMapPatch(originalMap, patchMap, dataStruct)
|
||||
result, err := StrategicMergeMapPatchUsingLookupPatchMeta(originalMap, patchMap, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -834,7 +854,7 @@ func handleUnmarshal(j []byte) (map[string]interface{}, error) {
|
||||
// calling CreateTwoWayMergeMapPatch.
|
||||
// Warning: the original and patch JSONMap objects are mutated by this function and should not be reused.
|
||||
func StrategicMergeMapPatch(original, patch JSONMap, dataStruct interface{}) (JSONMap, error) {
|
||||
t, err := getTagStructType(dataStruct)
|
||||
schema, err := NewPatchMetaFromStruct(dataStruct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -849,29 +869,15 @@ func StrategicMergeMapPatch(original, patch JSONMap, dataStruct interface{}) (JS
|
||||
return nil, mergepatch.ErrUnsupportedStrategicMergePatchFormat
|
||||
}
|
||||
|
||||
return StrategicMergeMapPatchUsingLookupPatchMeta(original, patch, schema)
|
||||
}
|
||||
|
||||
func StrategicMergeMapPatchUsingLookupPatchMeta(original, patch JSONMap, schema LookupPatchMeta) (JSONMap, error) {
|
||||
mergeOptions := MergeOptions{
|
||||
MergeParallelList: true,
|
||||
IgnoreUnmatchedNulls: true,
|
||||
}
|
||||
return mergeMap(original, patch, t, mergeOptions)
|
||||
}
|
||||
|
||||
func getTagStructType(dataStruct interface{}) (reflect.Type, error) {
|
||||
if dataStruct == nil {
|
||||
return nil, mergepatch.ErrBadArgKind(struct{}{}, nil)
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(dataStruct)
|
||||
// Get the underlying type for pointers
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Struct {
|
||||
return nil, mergepatch.ErrBadArgKind(struct{}{}, dataStruct)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
return mergeMap(original, patch, schema, mergeOptions)
|
||||
}
|
||||
|
||||
// handleDirectiveInMergeMap handles the patch directive when merging 2 maps.
|
||||
@ -1079,7 +1085,7 @@ func applyRetainKeysDirective(original, patch map[string]interface{}, options Me
|
||||
// The precedence is $setElementOrder > order in patch list > order in live list.
|
||||
// This function will delete the item after merging it to prevent process it again in the future.
|
||||
// Ref: https://git.k8s.io/community/contributors/design-proposals/cli/preserve-order-in-strategic-merge-patch.md
|
||||
func mergePatchIntoOriginal(original, patch map[string]interface{}, t reflect.Type, mergeOptions MergeOptions) error {
|
||||
func mergePatchIntoOriginal(original, patch map[string]interface{}, schema LookupPatchMeta, mergeOptions MergeOptions) error {
|
||||
for key, patchV := range patch {
|
||||
// Do nothing if there is no ordering directive
|
||||
if !strings.HasPrefix(key, setElementOrderDirectivePrefix) {
|
||||
@ -1106,9 +1112,9 @@ func mergePatchIntoOriginal(original, patch map[string]interface{}, t reflect.Ty
|
||||
var (
|
||||
ok bool
|
||||
originalFieldValue, patchFieldValue, merged []interface{}
|
||||
patchStrategy, mergeKey string
|
||||
patchStrategies []string
|
||||
fieldType reflect.Type
|
||||
patchStrategy string
|
||||
patchMeta PatchMeta
|
||||
subschema LookupPatchMeta
|
||||
)
|
||||
typedSetElementOrderList, ok := setElementOrderInPatch.([]interface{})
|
||||
if !ok {
|
||||
@ -1134,16 +1140,16 @@ func mergePatchIntoOriginal(original, patch map[string]interface{}, t reflect.Ty
|
||||
return mergepatch.ErrBadArgType(patchFieldValue, patchList)
|
||||
}
|
||||
}
|
||||
fieldType, patchStrategies, mergeKey, err = forkedjson.LookupPatchMetadata(t, originalKey)
|
||||
subschema, patchMeta, err = schema.LookupPatchMetadataForSlice(originalKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, patchStrategy, err = extractRetainKeysPatchStrategy(patchStrategies)
|
||||
_, patchStrategy, err = extractRetainKeysPatchStrategy(patchMeta.GetPatchStrategies())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Check for consistency between the element order list and the field it applies to
|
||||
err = validatePatchWithSetOrderList(patchFieldValue, typedSetElementOrderList, mergeKey)
|
||||
err = validatePatchWithSetOrderList(patchFieldValue, typedSetElementOrderList, patchMeta.GetPatchMergeKey())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1156,8 +1162,8 @@ func mergePatchIntoOriginal(original, patch map[string]interface{}, t reflect.Ty
|
||||
// list was added
|
||||
merged = patchFieldValue
|
||||
case foundOriginal && foundPatch:
|
||||
merged, err = mergeSliceHandler(originalList, patchList, fieldType,
|
||||
patchStrategy, mergeKey, false, mergeOptions)
|
||||
merged, err = mergeSliceHandler(originalList, patchList, subschema,
|
||||
patchStrategy, patchMeta.GetPatchMergeKey(), false, mergeOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1167,13 +1173,13 @@ func mergePatchIntoOriginal(original, patch map[string]interface{}, t reflect.Ty
|
||||
|
||||
// Split all items into patch items and server-only items and then enforce the order.
|
||||
var patchItems, serverOnlyItems []interface{}
|
||||
if len(mergeKey) == 0 {
|
||||
if len(patchMeta.GetPatchMergeKey()) == 0 {
|
||||
// Primitives doesn't need merge key to do partitioning.
|
||||
patchItems, serverOnlyItems = partitionPrimitivesByPresentInList(merged, typedSetElementOrderList)
|
||||
|
||||
} else {
|
||||
// Maps need merge key to do partitioning.
|
||||
patchItems, serverOnlyItems, err = partitionMapsByPresentInList(merged, typedSetElementOrderList, mergeKey)
|
||||
patchItems, serverOnlyItems, err = partitionMapsByPresentInList(merged, typedSetElementOrderList, patchMeta.GetPatchMergeKey())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1187,7 +1193,7 @@ func mergePatchIntoOriginal(original, patch map[string]interface{}, t reflect.Ty
|
||||
// normalize merged list
|
||||
// typedSetElementOrderList contains all the relative order in typedPatchList,
|
||||
// so don't need to use typedPatchList
|
||||
both, err := normalizeElementOrder(patchItems, serverOnlyItems, typedSetElementOrderList, originalFieldValue, mergeKey, kind)
|
||||
both, err := normalizeElementOrder(patchItems, serverOnlyItems, typedSetElementOrderList, originalFieldValue, patchMeta.GetPatchMergeKey(), kind)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1249,7 +1255,7 @@ func partitionMapsByPresentInList(original, partitionBy []interface{}, mergeKey
|
||||
// If patch contains any null field (e.g. field_1: null) that is not
|
||||
// present in original, then to propagate it to the end result use
|
||||
// mergeOptions.IgnoreUnmatchedNulls == false.
|
||||
func mergeMap(original, patch map[string]interface{}, t reflect.Type, mergeOptions MergeOptions) (map[string]interface{}, error) {
|
||||
func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, mergeOptions MergeOptions) (map[string]interface{}, error) {
|
||||
if v, ok := patch[directiveMarker]; ok {
|
||||
return handleDirectiveInMergeMap(v, patch)
|
||||
}
|
||||
@ -1269,7 +1275,7 @@ func mergeMap(original, patch map[string]interface{}, t reflect.Type, mergeOptio
|
||||
// When not merging the directive, it will make sure $setElementOrder list exist only in original.
|
||||
// When merging the directive, it will process $setElementOrder and its patch list together.
|
||||
// This function will delete the merged elements from patch so they will not be reprocessed
|
||||
err = mergePatchIntoOriginal(original, patch, t, mergeOptions)
|
||||
err = mergePatchIntoOriginal(original, patch, schema, mergeOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1307,11 +1313,6 @@ func mergeMap(original, patch map[string]interface{}, t reflect.Type, mergeOptio
|
||||
continue
|
||||
}
|
||||
|
||||
// If the data type is a pointer, resolve the element.
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
originalType := reflect.TypeOf(original[k])
|
||||
patchType := reflect.TypeOf(patchV)
|
||||
if originalType != patchType {
|
||||
@ -1319,22 +1320,27 @@ func mergeMap(original, patch map[string]interface{}, t reflect.Type, mergeOptio
|
||||
continue
|
||||
}
|
||||
// If they're both maps or lists, recurse into the value.
|
||||
// First find the fieldPatchStrategy and fieldPatchMergeKey.
|
||||
fieldType, fieldPatchStrategies, fieldPatchMergeKey, err := forkedjson.LookupPatchMetadata(t, k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, patchStrategy, err := extractRetainKeysPatchStrategy(fieldPatchStrategies)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch originalType.Kind() {
|
||||
case reflect.Map:
|
||||
|
||||
original[k], err = mergeMapHandler(original[k], patchV, fieldType, patchStrategy, mergeOptions)
|
||||
subschema, patchMeta, err := schema.LookupPatchMetadataForStruct(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, patchStrategy, err := extractRetainKeysPatchStrategy(patchMeta.GetPatchStrategies())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
original[k], err = mergeMapHandler(original[k], patchV, subschema, patchStrategy, mergeOptions)
|
||||
case reflect.Slice:
|
||||
original[k], err = mergeSliceHandler(original[k], patchV, fieldType, patchStrategy, fieldPatchMergeKey, isDeleteList, mergeOptions)
|
||||
subschema, patchMeta, err := schema.LookupPatchMetadataForSlice(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, patchStrategy, err := extractRetainKeysPatchStrategy(patchMeta.GetPatchStrategies())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
original[k], err = mergeSliceHandler(original[k], patchV, subschema, patchStrategy, patchMeta.GetPatchMergeKey(), isDeleteList, mergeOptions)
|
||||
default:
|
||||
original[k] = patchV
|
||||
}
|
||||
@ -1347,7 +1353,7 @@ func mergeMap(original, patch map[string]interface{}, t reflect.Type, mergeOptio
|
||||
|
||||
// mergeMapHandler handles how to merge `patchV` whose key is `key` with `original` respecting
|
||||
// fieldPatchStrategy and mergeOptions.
|
||||
func mergeMapHandler(original, patch interface{}, fieldType reflect.Type,
|
||||
func mergeMapHandler(original, patch interface{}, schema LookupPatchMeta,
|
||||
fieldPatchStrategy string, mergeOptions MergeOptions) (map[string]interface{}, error) {
|
||||
typedOriginal, typedPatch, err := mapTypeAssertion(original, patch)
|
||||
if err != nil {
|
||||
@ -1355,7 +1361,7 @@ func mergeMapHandler(original, patch interface{}, fieldType reflect.Type,
|
||||
}
|
||||
|
||||
if fieldPatchStrategy != replaceDirective {
|
||||
return mergeMap(typedOriginal, typedPatch, fieldType, mergeOptions)
|
||||
return mergeMap(typedOriginal, typedPatch, schema, mergeOptions)
|
||||
} else {
|
||||
return typedPatch, nil
|
||||
}
|
||||
@ -1363,7 +1369,7 @@ func mergeMapHandler(original, patch interface{}, fieldType reflect.Type,
|
||||
|
||||
// mergeSliceHandler handles how to merge `patchV` whose key is `key` with `original` respecting
|
||||
// fieldPatchStrategy, fieldPatchMergeKey, isDeleteList and mergeOptions.
|
||||
func mergeSliceHandler(original, patch interface{}, fieldType reflect.Type,
|
||||
func mergeSliceHandler(original, patch interface{}, schema LookupPatchMeta,
|
||||
fieldPatchStrategy, fieldPatchMergeKey string, isDeleteList bool, mergeOptions MergeOptions) ([]interface{}, error) {
|
||||
typedOriginal, typedPatch, err := sliceTypeAssertion(original, patch)
|
||||
if err != nil {
|
||||
@ -1371,8 +1377,7 @@ func mergeSliceHandler(original, patch interface{}, fieldType reflect.Type,
|
||||
}
|
||||
|
||||
if fieldPatchStrategy == mergeDirective {
|
||||
elemType := fieldType.Elem()
|
||||
return mergeSlice(typedOriginal, typedPatch, elemType, fieldPatchMergeKey, mergeOptions, isDeleteList)
|
||||
return mergeSlice(typedOriginal, typedPatch, schema, fieldPatchMergeKey, mergeOptions, isDeleteList)
|
||||
} else {
|
||||
return typedPatch, nil
|
||||
}
|
||||
@ -1381,7 +1386,7 @@ func mergeSliceHandler(original, patch interface{}, fieldType reflect.Type,
|
||||
// Merge two slices together. Note: This may modify both the original slice and
|
||||
// the patch because getting a deep copy of a slice in golang is highly
|
||||
// non-trivial.
|
||||
func mergeSlice(original, patch []interface{}, elemType reflect.Type, mergeKey string, mergeOptions MergeOptions, isDeleteList bool) ([]interface{}, error) {
|
||||
func mergeSlice(original, patch []interface{}, schema LookupPatchMeta, mergeKey string, mergeOptions MergeOptions, isDeleteList bool) ([]interface{}, error) {
|
||||
if len(original) == 0 && len(patch) == 0 {
|
||||
return original, nil
|
||||
}
|
||||
@ -1406,7 +1411,7 @@ func mergeSlice(original, patch []interface{}, elemType reflect.Type, mergeKey s
|
||||
|
||||
} else {
|
||||
if mergeKey == "" {
|
||||
return nil, fmt.Errorf("cannot merge lists without merge key for type %s", elemType.Kind().String())
|
||||
return nil, fmt.Errorf("cannot merge lists without merge key for %s", schema.Name())
|
||||
}
|
||||
|
||||
original, patch, err = mergeSliceWithSpecialElements(original, patch, mergeKey)
|
||||
@ -1414,7 +1419,7 @@ func mergeSlice(original, patch []interface{}, elemType reflect.Type, mergeKey s
|
||||
return nil, err
|
||||
}
|
||||
|
||||
merged, err = mergeSliceWithoutSpecialElements(original, patch, mergeKey, elemType, mergeOptions)
|
||||
merged, err = mergeSliceWithoutSpecialElements(original, patch, mergeKey, schema, mergeOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1492,7 +1497,7 @@ func deleteMatchingEntries(original []interface{}, mergeKey string, mergeValue i
|
||||
|
||||
// mergeSliceWithoutSpecialElements merges slices with non-special elements.
|
||||
// original and patch must be slices of maps, they should be checked before calling this function.
|
||||
func mergeSliceWithoutSpecialElements(original, patch []interface{}, mergeKey string, elemType reflect.Type, mergeOptions MergeOptions) ([]interface{}, error) {
|
||||
func mergeSliceWithoutSpecialElements(original, patch []interface{}, mergeKey string, schema LookupPatchMeta, mergeOptions MergeOptions) ([]interface{}, error) {
|
||||
for _, v := range patch {
|
||||
typedV := v.(map[string]interface{})
|
||||
mergeValue, ok := typedV[mergeKey]
|
||||
@ -1511,7 +1516,7 @@ func mergeSliceWithoutSpecialElements(original, patch []interface{}, mergeKey st
|
||||
var mergedMaps interface{}
|
||||
var err error
|
||||
// Merge into original.
|
||||
mergedMaps, err = mergeMap(originalMap, typedV, elemType, mergeOptions)
|
||||
mergedMaps, err = mergeMap(originalMap, typedV, schema, mergeOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1560,14 +1565,14 @@ func findMapInSliceBasedOnKeyValue(m []interface{}, key string, value interface{
|
||||
// by key. This is needed by tests because in JSON, list order is significant,
|
||||
// but in Strategic Merge Patch, merge lists do not have significant order.
|
||||
// Sorting the lists allows for order-insensitive comparison of patched maps.
|
||||
func sortMergeListsByName(mapJSON []byte, dataStruct interface{}) ([]byte, error) {
|
||||
func sortMergeListsByName(mapJSON []byte, schema LookupPatchMeta) ([]byte, error) {
|
||||
var m map[string]interface{}
|
||||
err := json.Unmarshal(mapJSON, &m)
|
||||
if err != nil {
|
||||
return nil, mergepatch.ErrBadJSONDoc
|
||||
}
|
||||
|
||||
newM, err := sortMergeListsByNameMap(m, reflect.TypeOf(dataStruct))
|
||||
newM, err := sortMergeListsByNameMap(m, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1576,7 +1581,7 @@ func sortMergeListsByName(mapJSON []byte, dataStruct interface{}) ([]byte, error
|
||||
}
|
||||
|
||||
// Function sortMergeListsByNameMap recursively sorts the merge lists by its mergeKey in a map.
|
||||
func sortMergeListsByNameMap(s map[string]interface{}, t reflect.Type) (map[string]interface{}, error) {
|
||||
func sortMergeListsByNameMap(s map[string]interface{}, schema LookupPatchMeta) (map[string]interface{}, error) {
|
||||
newS := map[string]interface{}{}
|
||||
for k, v := range s {
|
||||
if k == retainKeysDirective {
|
||||
@ -1597,26 +1602,29 @@ func sortMergeListsByNameMap(s map[string]interface{}, t reflect.Type) (map[stri
|
||||
return nil, mergepatch.ErrBadPatchFormatForSetElementOrderList
|
||||
}
|
||||
} else if k != directiveMarker {
|
||||
fieldType, fieldPatchStrategies, fieldPatchMergeKey, err := forkedjson.LookupPatchMetadata(t, k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, patchStrategy, err := extractRetainKeysPatchStrategy(fieldPatchStrategies)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If v is a map or a merge slice, recurse.
|
||||
if typedV, ok := v.(map[string]interface{}); ok {
|
||||
var err error
|
||||
v, err = sortMergeListsByNameMap(typedV, fieldType)
|
||||
// recurse for map and slice.
|
||||
switch typedV := v.(type) {
|
||||
case map[string]interface{}:
|
||||
subschema, _, err := schema.LookupPatchMetadataForStruct(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v, err = sortMergeListsByNameMap(typedV, subschema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case []interface{}:
|
||||
subschema, patchMeta, err := schema.LookupPatchMetadataForSlice(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, patchStrategy, err := extractRetainKeysPatchStrategy(patchMeta.GetPatchStrategies())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if typedV, ok := v.([]interface{}); ok {
|
||||
if patchStrategy == mergeDirective {
|
||||
var err error
|
||||
v, err = sortMergeListsByNameArray(typedV, fieldType.Elem(), fieldPatchMergeKey, true)
|
||||
v, err = sortMergeListsByNameArray(typedV, subschema, patchMeta.GetPatchMergeKey(), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1631,7 +1639,7 @@ func sortMergeListsByNameMap(s map[string]interface{}, t reflect.Type) (map[stri
|
||||
}
|
||||
|
||||
// Function sortMergeListsByNameMap recursively sorts the merge lists by its mergeKey in an array.
|
||||
func sortMergeListsByNameArray(s []interface{}, elemType reflect.Type, mergeKey string, recurse bool) ([]interface{}, error) {
|
||||
func sortMergeListsByNameArray(s []interface{}, schema LookupPatchMeta, mergeKey string, recurse bool) ([]interface{}, error) {
|
||||
if len(s) == 0 {
|
||||
return s, nil
|
||||
}
|
||||
@ -1654,7 +1662,7 @@ func sortMergeListsByNameArray(s []interface{}, elemType reflect.Type, mergeKey
|
||||
for _, elem := range s {
|
||||
if recurse {
|
||||
typedElem := elem.(map[string]interface{})
|
||||
newElem, err := sortMergeListsByNameMap(typedElem, elemType)
|
||||
newElem, err := sortMergeListsByNameMap(typedElem, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1800,18 +1808,13 @@ func sliceElementType(slices ...[]interface{}) (reflect.Type, error) {
|
||||
// objects overlap with different values in any key. All keys are required to be
|
||||
// strings. Since patches of the same Type have congruent keys, this is valid
|
||||
// for multiple patch types. This method supports strategic merge patch semantics.
|
||||
func MergingMapsHaveConflicts(left, right map[string]interface{}, dataStruct interface{}) (bool, error) {
|
||||
t, err := getTagStructType(dataStruct)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
return mergingMapFieldsHaveConflicts(left, right, t, "", "")
|
||||
func MergingMapsHaveConflicts(left, right map[string]interface{}, schema LookupPatchMeta) (bool, error) {
|
||||
return mergingMapFieldsHaveConflicts(left, right, schema, "", "")
|
||||
}
|
||||
|
||||
func mergingMapFieldsHaveConflicts(
|
||||
left, right interface{},
|
||||
fieldType reflect.Type,
|
||||
schema LookupPatchMeta,
|
||||
fieldPatchStrategy, fieldPatchMergeKey string,
|
||||
) (bool, error) {
|
||||
switch leftType := left.(type) {
|
||||
@ -1842,15 +1845,14 @@ func mergingMapFieldsHaveConflicts(
|
||||
return false, nil
|
||||
}
|
||||
// Check the individual keys.
|
||||
return mapsHaveConflicts(leftType, rightType, fieldType)
|
||||
return mapsHaveConflicts(leftType, rightType, schema)
|
||||
|
||||
case []interface{}:
|
||||
rightType, ok := right.([]interface{})
|
||||
if !ok {
|
||||
return true, nil
|
||||
}
|
||||
return slicesHaveConflicts(leftType, rightType, fieldType, fieldPatchStrategy, fieldPatchMergeKey)
|
||||
|
||||
return slicesHaveConflicts(leftType, rightType, schema, fieldPatchStrategy, fieldPatchMergeKey)
|
||||
case string, float64, bool, int, int64, nil:
|
||||
return !reflect.DeepEqual(left, right), nil
|
||||
default:
|
||||
@ -1858,21 +1860,37 @@ func mergingMapFieldsHaveConflicts(
|
||||
}
|
||||
}
|
||||
|
||||
func mapsHaveConflicts(typedLeft, typedRight map[string]interface{}, structType reflect.Type) (bool, error) {
|
||||
func mapsHaveConflicts(typedLeft, typedRight map[string]interface{}, schema LookupPatchMeta) (bool, error) {
|
||||
for key, leftValue := range typedLeft {
|
||||
if key != directiveMarker && key != retainKeysDirective {
|
||||
if rightValue, ok := typedRight[key]; ok {
|
||||
fieldType, fieldPatchStrategies, fieldPatchMergeKey, err := forkedjson.LookupPatchMetadata(structType, key)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
_, patchStrategy, err := extractRetainKeysPatchStrategy(fieldPatchStrategies)
|
||||
if err != nil {
|
||||
return true, err
|
||||
var subschema LookupPatchMeta
|
||||
var patchMeta PatchMeta
|
||||
var patchStrategy string
|
||||
var err error
|
||||
switch leftValue.(type) {
|
||||
case []interface{}:
|
||||
subschema, patchMeta, err = schema.LookupPatchMetadataForSlice(key)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
_, patchStrategy, err = extractRetainKeysPatchStrategy(patchMeta.patchStrategies)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
case map[string]interface{}:
|
||||
subschema, patchMeta, err = schema.LookupPatchMetadataForStruct(key)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
_, patchStrategy, err = extractRetainKeysPatchStrategy(patchMeta.patchStrategies)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
|
||||
if hasConflicts, err := mergingMapFieldsHaveConflicts(leftValue, rightValue,
|
||||
fieldType, patchStrategy, fieldPatchMergeKey); hasConflicts {
|
||||
subschema, patchStrategy, patchMeta.GetPatchMergeKey()); hasConflicts {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
@ -1884,7 +1902,7 @@ func mapsHaveConflicts(typedLeft, typedRight map[string]interface{}, structType
|
||||
|
||||
func slicesHaveConflicts(
|
||||
typedLeft, typedRight []interface{},
|
||||
fieldType reflect.Type,
|
||||
schema LookupPatchMeta,
|
||||
fieldPatchStrategy, fieldPatchMergeKey string,
|
||||
) (bool, error) {
|
||||
elementType, err := sliceElementType(typedLeft, typedRight)
|
||||
@ -1892,7 +1910,6 @@ func slicesHaveConflicts(
|
||||
return true, err
|
||||
}
|
||||
|
||||
valueType := fieldType.Elem()
|
||||
if fieldPatchStrategy == mergeDirective {
|
||||
// Merging lists of scalars have no conflicts by definition
|
||||
// So we only need to check further if the elements are maps
|
||||
@ -1911,7 +1928,7 @@ func slicesHaveConflicts(
|
||||
return true, err
|
||||
}
|
||||
|
||||
return mapsOfMapsHaveConflicts(leftMap, rightMap, valueType)
|
||||
return mapsOfMapsHaveConflicts(leftMap, rightMap, schema)
|
||||
}
|
||||
|
||||
// Either we don't have type information, or these are non-merging lists
|
||||
@ -1929,7 +1946,7 @@ func slicesHaveConflicts(
|
||||
// Compare the slices element by element in order
|
||||
// This test will fail if the slices are not sorted
|
||||
for i := range typedLeft {
|
||||
if hasConflicts, err := mergingMapFieldsHaveConflicts(typedLeft[i], typedRight[i], valueType, "", ""); hasConflicts {
|
||||
if hasConflicts, err := mergingMapFieldsHaveConflicts(typedLeft[i], typedRight[i], schema, "", ""); hasConflicts {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
@ -1956,10 +1973,10 @@ func sliceOfMapsToMapOfMaps(slice []interface{}, mergeKey string) (map[string]in
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func mapsOfMapsHaveConflicts(typedLeft, typedRight map[string]interface{}, structType reflect.Type) (bool, error) {
|
||||
func mapsOfMapsHaveConflicts(typedLeft, typedRight map[string]interface{}, schema LookupPatchMeta) (bool, error) {
|
||||
for key, leftValue := range typedLeft {
|
||||
if rightValue, ok := typedRight[key]; ok {
|
||||
if hasConflicts, err := mergingMapFieldsHaveConflicts(leftValue, rightValue, structType, "", ""); hasConflicts {
|
||||
if hasConflicts, err := mergingMapFieldsHaveConflicts(leftValue, rightValue, schema, "", ""); hasConflicts {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
@ -1979,7 +1996,7 @@ func mapsOfMapsHaveConflicts(typedLeft, typedRight map[string]interface{}, struc
|
||||
// in a way that is different from how it is changed in current (e.g., deleting it, changing its
|
||||
// value). We also propagate values fields that do not exist in original but are explicitly
|
||||
// defined in modified.
|
||||
func CreateThreeWayMergePatch(original, modified, current []byte, dataStruct interface{}, overwrite bool, fns ...mergepatch.PreconditionFunc) ([]byte, error) {
|
||||
func CreateThreeWayMergePatch(original, modified, current []byte, schema LookupPatchMeta, overwrite bool, fns ...mergepatch.PreconditionFunc) ([]byte, error) {
|
||||
originalMap := map[string]interface{}{}
|
||||
if len(original) > 0 {
|
||||
if err := json.Unmarshal(original, &originalMap); err != nil {
|
||||
@ -2001,11 +2018,6 @@ func CreateThreeWayMergePatch(original, modified, current []byte, dataStruct int
|
||||
}
|
||||
}
|
||||
|
||||
t, err := getTagStructType(dataStruct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The patch is the difference from current to modified without deletions, plus deletions
|
||||
// from original to modified. To find it, we compute deletions, which are the deletions from
|
||||
// original to modified, and delta, which is the difference from current to modified without
|
||||
@ -2014,7 +2026,7 @@ func CreateThreeWayMergePatch(original, modified, current []byte, dataStruct int
|
||||
IgnoreDeletions: true,
|
||||
SetElementOrder: true,
|
||||
}
|
||||
deltaMap, err := diffMaps(currentMap, modifiedMap, t, deltaMapDiffOptions)
|
||||
deltaMap, err := diffMaps(currentMap, modifiedMap, schema, deltaMapDiffOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -2022,13 +2034,13 @@ func CreateThreeWayMergePatch(original, modified, current []byte, dataStruct int
|
||||
SetElementOrder: true,
|
||||
IgnoreChangesAndAdditions: true,
|
||||
}
|
||||
deletionsMap, err := diffMaps(originalMap, modifiedMap, t, deletionsMapDiffOptions)
|
||||
deletionsMap, err := diffMaps(originalMap, modifiedMap, schema, deletionsMapDiffOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mergeOptions := MergeOptions{}
|
||||
patchMap, err := mergeMap(deletionsMap, deltaMap, t, mergeOptions)
|
||||
patchMap, err := mergeMap(deletionsMap, deltaMap, schema, mergeOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -2044,12 +2056,12 @@ func CreateThreeWayMergePatch(original, modified, current []byte, dataStruct int
|
||||
// then return a conflict error.
|
||||
if !overwrite {
|
||||
changeMapDiffOptions := DiffOptions{}
|
||||
changedMap, err := diffMaps(originalMap, currentMap, t, changeMapDiffOptions)
|
||||
changedMap, err := diffMaps(originalMap, currentMap, schema, changeMapDiffOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasConflicts, err := MergingMapsHaveConflicts(patchMap, changedMap, dataStruct)
|
||||
hasConflicts, err := MergingMapsHaveConflicts(patchMap, changedMap, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
193
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/types.go
generated
vendored
Normal file
193
vendor/k8s.io/apimachinery/pkg/util/strategicpatch/types.go
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
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 strategicpatch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||
openapi "k8s.io/kube-openapi/pkg/util/proto"
|
||||
)
|
||||
|
||||
const (
|
||||
patchStrategyOpenapiextensionKey = "x-kubernetes-patch-strategy"
|
||||
patchMergeKeyOpenapiextensionKey = "x-kubernetes-patch-merge-key"
|
||||
)
|
||||
|
||||
type LookupPatchItem interface {
|
||||
openapi.SchemaVisitor
|
||||
|
||||
Error() error
|
||||
Path() *openapi.Path
|
||||
}
|
||||
|
||||
type kindItem struct {
|
||||
key string
|
||||
path *openapi.Path
|
||||
err error
|
||||
patchmeta PatchMeta
|
||||
subschema openapi.Schema
|
||||
hasVisitKind bool
|
||||
}
|
||||
|
||||
func NewKindItem(key string, path *openapi.Path) *kindItem {
|
||||
return &kindItem{
|
||||
key: key,
|
||||
path: path,
|
||||
}
|
||||
}
|
||||
|
||||
var _ LookupPatchItem = &kindItem{}
|
||||
|
||||
func (item *kindItem) Error() error {
|
||||
return item.err
|
||||
}
|
||||
|
||||
func (item *kindItem) Path() *openapi.Path {
|
||||
return item.path
|
||||
}
|
||||
|
||||
func (item *kindItem) VisitPrimitive(schema *openapi.Primitive) {
|
||||
item.err = errors.New("expected kind, but got primitive")
|
||||
}
|
||||
|
||||
func (item *kindItem) VisitArray(schema *openapi.Array) {
|
||||
item.err = errors.New("expected kind, but got slice")
|
||||
}
|
||||
|
||||
func (item *kindItem) VisitMap(schema *openapi.Map) {
|
||||
item.err = errors.New("expected kind, but got map")
|
||||
}
|
||||
|
||||
func (item *kindItem) VisitReference(schema openapi.Reference) {
|
||||
if !item.hasVisitKind {
|
||||
schema.SubSchema().Accept(item)
|
||||
}
|
||||
}
|
||||
|
||||
func (item *kindItem) VisitKind(schema *openapi.Kind) {
|
||||
subschema, ok := schema.Fields[item.key]
|
||||
if !ok {
|
||||
item.err = FieldNotFoundError{Path: schema.GetPath().String(), Field: item.key}
|
||||
return
|
||||
}
|
||||
|
||||
mergeKey, patchStrategies, err := parsePatchMetadata(subschema.GetExtensions())
|
||||
if err != nil {
|
||||
item.err = err
|
||||
return
|
||||
}
|
||||
item.patchmeta = PatchMeta{
|
||||
patchStrategies: patchStrategies,
|
||||
patchMergeKey: mergeKey,
|
||||
}
|
||||
item.subschema = subschema
|
||||
}
|
||||
|
||||
type sliceItem struct {
|
||||
key string
|
||||
path *openapi.Path
|
||||
err error
|
||||
patchmeta PatchMeta
|
||||
subschema openapi.Schema
|
||||
hasVisitKind bool
|
||||
}
|
||||
|
||||
func NewSliceItem(key string, path *openapi.Path) *sliceItem {
|
||||
return &sliceItem{
|
||||
key: key,
|
||||
path: path,
|
||||
}
|
||||
}
|
||||
|
||||
var _ LookupPatchItem = &sliceItem{}
|
||||
|
||||
func (item *sliceItem) Error() error {
|
||||
return item.err
|
||||
}
|
||||
|
||||
func (item *sliceItem) Path() *openapi.Path {
|
||||
return item.path
|
||||
}
|
||||
|
||||
func (item *sliceItem) VisitPrimitive(schema *openapi.Primitive) {
|
||||
item.err = errors.New("expected slice, but got primitive")
|
||||
}
|
||||
|
||||
func (item *sliceItem) VisitArray(schema *openapi.Array) {
|
||||
if !item.hasVisitKind {
|
||||
item.err = errors.New("expected visit kind first, then visit array")
|
||||
}
|
||||
subschema := schema.SubType
|
||||
item.subschema = subschema
|
||||
}
|
||||
|
||||
func (item *sliceItem) VisitMap(schema *openapi.Map) {
|
||||
item.err = errors.New("expected slice, but got map")
|
||||
}
|
||||
|
||||
func (item *sliceItem) VisitReference(schema openapi.Reference) {
|
||||
if !item.hasVisitKind {
|
||||
schema.SubSchema().Accept(item)
|
||||
} else {
|
||||
item.subschema = schema.SubSchema()
|
||||
}
|
||||
}
|
||||
|
||||
func (item *sliceItem) VisitKind(schema *openapi.Kind) {
|
||||
subschema, ok := schema.Fields[item.key]
|
||||
if !ok {
|
||||
item.err = FieldNotFoundError{Path: schema.GetPath().String(), Field: item.key}
|
||||
return
|
||||
}
|
||||
|
||||
mergeKey, patchStrategies, err := parsePatchMetadata(subschema.GetExtensions())
|
||||
if err != nil {
|
||||
item.err = err
|
||||
return
|
||||
}
|
||||
item.patchmeta = PatchMeta{
|
||||
patchStrategies: patchStrategies,
|
||||
patchMergeKey: mergeKey,
|
||||
}
|
||||
item.hasVisitKind = true
|
||||
subschema.Accept(item)
|
||||
}
|
||||
|
||||
func parsePatchMetadata(extensions map[string]interface{}) (string, []string, error) {
|
||||
ps, foundPS := extensions[patchStrategyOpenapiextensionKey]
|
||||
var patchStrategies []string
|
||||
var mergeKey, patchStrategy string
|
||||
var ok bool
|
||||
if foundPS {
|
||||
patchStrategy, ok = ps.(string)
|
||||
if ok {
|
||||
patchStrategies = strings.Split(patchStrategy, ",")
|
||||
} else {
|
||||
return "", nil, mergepatch.ErrBadArgType(patchStrategy, ps)
|
||||
}
|
||||
}
|
||||
mk, foundMK := extensions[patchMergeKeyOpenapiextensionKey]
|
||||
if foundMK {
|
||||
mergeKey, ok = mk.(string)
|
||||
if !ok {
|
||||
return "", nil, mergepatch.ErrBadArgType(mergeKey, mk)
|
||||
}
|
||||
}
|
||||
return mergeKey, patchStrategies, nil
|
||||
}
|
9
vendor/k8s.io/apimachinery/third_party/forked/golang/json/fields.go
generated
vendored
9
vendor/k8s.io/apimachinery/third_party/forked/golang/json/fields.go
generated
vendored
@ -26,17 +26,14 @@ const (
|
||||
// struct field given the struct type and the JSON name of the field.
|
||||
// It returns field type, a slice of patch strategies, merge key and error.
|
||||
// TODO: fix the returned errors to be introspectable.
|
||||
func LookupPatchMetadata(t reflect.Type, jsonField string) (
|
||||
func LookupPatchMetadataForStruct(t reflect.Type, jsonField string) (
|
||||
elemType reflect.Type, patchStrategies []string, patchMergeKey string, e error) {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Kind() == reflect.Map {
|
||||
elemType = t.Elem()
|
||||
return
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Struct {
|
||||
e = fmt.Errorf("merging an object in json but data type is not map or struct, instead is: %s",
|
||||
e = fmt.Errorf("merging an object in json but data type is not struct, instead is: %s",
|
||||
t.Kind().String())
|
||||
return
|
||||
}
|
||||
|
19
vendor/k8s.io/kube-openapi/pkg/util/proto/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/kube-openapi/pkg/util/proto/doc.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 proto is a collection of libraries for parsing and indexing the type definitions.
|
||||
// The openapi spec contains the object model definitions and extensions metadata.
|
||||
package proto
|
275
vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
generated
vendored
Normal file
275
vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
generated
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
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 proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func newSchemaError(path *Path, format string, a ...interface{}) error {
|
||||
err := fmt.Sprintf(format, a...)
|
||||
if path.Len() == 0 {
|
||||
return fmt.Errorf("SchemaError: %v", err)
|
||||
}
|
||||
return fmt.Errorf("SchemaError(%v): %v", path, err)
|
||||
}
|
||||
|
||||
// VendorExtensionToMap converts openapi VendorExtension to a map.
|
||||
func VendorExtensionToMap(e []*openapi_v2.NamedAny) map[string]interface{} {
|
||||
values := map[string]interface{}{}
|
||||
|
||||
for _, na := range e {
|
||||
if na.GetName() == "" || na.GetValue() == nil {
|
||||
continue
|
||||
}
|
||||
if na.GetValue().GetYaml() == "" {
|
||||
continue
|
||||
}
|
||||
var value interface{}
|
||||
err := yaml.Unmarshal([]byte(na.GetValue().GetYaml()), &value)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
values[na.GetName()] = value
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
// Definitions is an implementation of `Models`. It looks for
|
||||
// models in an openapi Schema.
|
||||
type Definitions struct {
|
||||
models map[string]Schema
|
||||
}
|
||||
|
||||
var _ Models = &Definitions{}
|
||||
|
||||
// NewOpenAPIData creates a new `Models` out of the openapi document.
|
||||
func NewOpenAPIData(doc *openapi_v2.Document) (Models, error) {
|
||||
definitions := Definitions{
|
||||
models: map[string]Schema{},
|
||||
}
|
||||
|
||||
// Save the list of all models first. This will allow us to
|
||||
// validate that we don't have any dangling reference.
|
||||
for _, namedSchema := range doc.GetDefinitions().GetAdditionalProperties() {
|
||||
definitions.models[namedSchema.GetName()] = nil
|
||||
}
|
||||
|
||||
// Now, parse each model. We can validate that references exists.
|
||||
for _, namedSchema := range doc.GetDefinitions().GetAdditionalProperties() {
|
||||
path := NewPath(namedSchema.GetName())
|
||||
schema, err := definitions.ParseSchema(namedSchema.GetValue(), &path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
definitions.models[namedSchema.GetName()] = schema
|
||||
}
|
||||
|
||||
return &definitions, nil
|
||||
}
|
||||
|
||||
// We believe the schema is a reference, verify that and returns a new
|
||||
// Schema
|
||||
func (d *Definitions) parseReference(s *openapi_v2.Schema, path *Path) (Schema, error) {
|
||||
if len(s.GetProperties().GetAdditionalProperties()) > 0 {
|
||||
return nil, newSchemaError(path, "unallowed embedded type definition")
|
||||
}
|
||||
if len(s.GetType().GetValue()) > 0 {
|
||||
return nil, newSchemaError(path, "definition reference can't have a type")
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(s.GetXRef(), "#/definitions/") {
|
||||
return nil, newSchemaError(path, "unallowed reference to non-definition %q", s.GetXRef())
|
||||
}
|
||||
reference := strings.TrimPrefix(s.GetXRef(), "#/definitions/")
|
||||
if _, ok := d.models[reference]; !ok {
|
||||
return nil, newSchemaError(path, "unknown model in reference: %q", reference)
|
||||
}
|
||||
return &Ref{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
reference: reference,
|
||||
definitions: d,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Definitions) parseBaseSchema(s *openapi_v2.Schema, path *Path) BaseSchema {
|
||||
return BaseSchema{
|
||||
Description: s.GetDescription(),
|
||||
Extensions: VendorExtensionToMap(s.GetVendorExtension()),
|
||||
Path: *path,
|
||||
}
|
||||
}
|
||||
|
||||
// We believe the schema is a map, verify and return a new schema
|
||||
func (d *Definitions) parseMap(s *openapi_v2.Schema, path *Path) (Schema, error) {
|
||||
if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object {
|
||||
return nil, newSchemaError(path, "invalid object type")
|
||||
}
|
||||
if s.GetAdditionalProperties().GetSchema() == nil {
|
||||
return nil, newSchemaError(path, "invalid object doesn't have additional properties")
|
||||
}
|
||||
sub, err := d.ParseSchema(s.GetAdditionalProperties().GetSchema(), path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Map{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
SubType: sub,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Definitions) parsePrimitive(s *openapi_v2.Schema, path *Path) (Schema, error) {
|
||||
var t string
|
||||
if len(s.GetType().GetValue()) > 1 {
|
||||
return nil, newSchemaError(path, "primitive can't have more than 1 type")
|
||||
}
|
||||
if len(s.GetType().GetValue()) == 1 {
|
||||
t = s.GetType().GetValue()[0]
|
||||
}
|
||||
switch t {
|
||||
case String:
|
||||
case Number:
|
||||
case Integer:
|
||||
case Boolean:
|
||||
case "": // Some models are completely empty, and can be safely ignored.
|
||||
// Do nothing
|
||||
default:
|
||||
return nil, newSchemaError(path, "Unknown primitive type: %q", t)
|
||||
}
|
||||
return &Primitive{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
Type: t,
|
||||
Format: s.GetFormat(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Definitions) parseArray(s *openapi_v2.Schema, path *Path) (Schema, error) {
|
||||
if len(s.GetType().GetValue()) != 1 {
|
||||
return nil, newSchemaError(path, "array should have exactly one type")
|
||||
}
|
||||
if s.GetType().GetValue()[0] != array {
|
||||
return nil, newSchemaError(path, `array should have type "array"`)
|
||||
}
|
||||
if len(s.GetItems().GetSchema()) != 1 {
|
||||
return nil, newSchemaError(path, "array should have exactly one sub-item")
|
||||
}
|
||||
sub, err := d.ParseSchema(s.GetItems().GetSchema()[0], path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Array{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
SubType: sub,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Definitions) parseKind(s *openapi_v2.Schema, path *Path) (Schema, error) {
|
||||
if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object {
|
||||
return nil, newSchemaError(path, "invalid object type")
|
||||
}
|
||||
if s.GetProperties() == nil {
|
||||
return nil, newSchemaError(path, "object doesn't have properties")
|
||||
}
|
||||
|
||||
fields := map[string]Schema{}
|
||||
|
||||
for _, namedSchema := range s.GetProperties().GetAdditionalProperties() {
|
||||
var err error
|
||||
path := path.FieldPath(namedSchema.GetName())
|
||||
fields[namedSchema.GetName()], err = d.ParseSchema(namedSchema.GetValue(), &path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &Kind{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
RequiredFields: s.GetRequired(),
|
||||
Fields: fields,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ParseSchema creates a walkable Schema from an openapi schema. While
|
||||
// this function is public, it doesn't leak through the interface.
|
||||
func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, error) {
|
||||
if len(s.GetType().GetValue()) == 1 {
|
||||
t := s.GetType().GetValue()[0]
|
||||
switch t {
|
||||
case object:
|
||||
return d.parseMap(s, path)
|
||||
case array:
|
||||
return d.parseArray(s, path)
|
||||
}
|
||||
|
||||
}
|
||||
if s.GetXRef() != "" {
|
||||
return d.parseReference(s, path)
|
||||
}
|
||||
if s.GetProperties() != nil {
|
||||
return d.parseKind(s, path)
|
||||
}
|
||||
return d.parsePrimitive(s, path)
|
||||
}
|
||||
|
||||
// LookupModel is public through the interface of Models. It
|
||||
// returns a visitable schema from the given model name.
|
||||
func (d *Definitions) LookupModel(model string) Schema {
|
||||
return d.models[model]
|
||||
}
|
||||
|
||||
func (d *Definitions) ListModels() []string {
|
||||
models := []string{}
|
||||
|
||||
for model := range d.models {
|
||||
models = append(models, model)
|
||||
}
|
||||
|
||||
sort.Strings(models)
|
||||
return models
|
||||
}
|
||||
|
||||
type Ref struct {
|
||||
BaseSchema
|
||||
|
||||
reference string
|
||||
definitions *Definitions
|
||||
}
|
||||
|
||||
var _ Reference = &Ref{}
|
||||
|
||||
func (r *Ref) Reference() string {
|
||||
return r.reference
|
||||
}
|
||||
|
||||
func (r *Ref) SubSchema() Schema {
|
||||
return r.definitions.models[r.reference]
|
||||
}
|
||||
|
||||
func (r *Ref) Accept(v SchemaVisitor) {
|
||||
v.VisitReference(r)
|
||||
}
|
||||
|
||||
func (r *Ref) GetName() string {
|
||||
return fmt.Sprintf("Reference to %q", r.reference)
|
||||
}
|
251
vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go
generated
vendored
Normal file
251
vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go
generated
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
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 proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Defines openapi types.
|
||||
const (
|
||||
Integer = "integer"
|
||||
Number = "number"
|
||||
String = "string"
|
||||
Boolean = "boolean"
|
||||
|
||||
// These types are private as they should never leak, and are
|
||||
// represented by actual structs.
|
||||
array = "array"
|
||||
object = "object"
|
||||
)
|
||||
|
||||
// Models interface describe a model provider. They can give you the
|
||||
// schema for a specific model.
|
||||
type Models interface {
|
||||
LookupModel(string) Schema
|
||||
ListModels() []string
|
||||
}
|
||||
|
||||
// SchemaVisitor is an interface that you need to implement if you want
|
||||
// to "visit" an openapi schema. A dispatch on the Schema type will call
|
||||
// the appropriate function based on its actual type:
|
||||
// - Array is a list of one and only one given subtype
|
||||
// - Map is a map of string to one and only one given subtype
|
||||
// - Primitive can be string, integer, number and boolean.
|
||||
// - Kind is an object with specific fields mapping to specific types.
|
||||
// - Reference is a link to another definition.
|
||||
type SchemaVisitor interface {
|
||||
VisitArray(*Array)
|
||||
VisitMap(*Map)
|
||||
VisitPrimitive(*Primitive)
|
||||
VisitKind(*Kind)
|
||||
VisitReference(Reference)
|
||||
}
|
||||
|
||||
// Schema is the base definition of an openapi type.
|
||||
type Schema interface {
|
||||
// Giving a visitor here will let you visit the actual type.
|
||||
Accept(SchemaVisitor)
|
||||
|
||||
// Pretty print the name of the type.
|
||||
GetName() string
|
||||
// Describes how to access this field.
|
||||
GetPath() *Path
|
||||
// Describes the field.
|
||||
GetDescription() string
|
||||
// Returns type extensions.
|
||||
GetExtensions() map[string]interface{}
|
||||
}
|
||||
|
||||
// Path helps us keep track of type paths
|
||||
type Path struct {
|
||||
parent *Path
|
||||
key string
|
||||
}
|
||||
|
||||
func NewPath(key string) Path {
|
||||
return Path{key: key}
|
||||
}
|
||||
|
||||
func (p *Path) Get() []string {
|
||||
if p == nil {
|
||||
return []string{}
|
||||
}
|
||||
if p.key == "" {
|
||||
return p.parent.Get()
|
||||
}
|
||||
return append(p.parent.Get(), p.key)
|
||||
}
|
||||
|
||||
func (p *Path) Len() int {
|
||||
return len(p.Get())
|
||||
}
|
||||
|
||||
func (p *Path) String() string {
|
||||
return strings.Join(p.Get(), "")
|
||||
}
|
||||
|
||||
// ArrayPath appends an array index and creates a new path
|
||||
func (p *Path) ArrayPath(i int) Path {
|
||||
return Path{
|
||||
parent: p,
|
||||
key: fmt.Sprintf("[%d]", i),
|
||||
}
|
||||
}
|
||||
|
||||
// FieldPath appends a field name and creates a new path
|
||||
func (p *Path) FieldPath(field string) Path {
|
||||
return Path{
|
||||
parent: p,
|
||||
key: fmt.Sprintf(".%s", field),
|
||||
}
|
||||
}
|
||||
|
||||
// BaseSchema holds data used by each types of schema.
|
||||
type BaseSchema struct {
|
||||
Description string
|
||||
Extensions map[string]interface{}
|
||||
|
||||
Path Path
|
||||
}
|
||||
|
||||
func (b *BaseSchema) GetDescription() string {
|
||||
return b.Description
|
||||
}
|
||||
|
||||
func (b *BaseSchema) GetExtensions() map[string]interface{} {
|
||||
return b.Extensions
|
||||
}
|
||||
|
||||
func (b *BaseSchema) GetPath() *Path {
|
||||
return &b.Path
|
||||
}
|
||||
|
||||
// Array must have all its element of the same `SubType`.
|
||||
type Array struct {
|
||||
BaseSchema
|
||||
|
||||
SubType Schema
|
||||
}
|
||||
|
||||
var _ Schema = &Array{}
|
||||
|
||||
func (a *Array) Accept(v SchemaVisitor) {
|
||||
v.VisitArray(a)
|
||||
}
|
||||
|
||||
func (a *Array) GetName() string {
|
||||
return fmt.Sprintf("Array of %s", a.SubType.GetName())
|
||||
}
|
||||
|
||||
// Kind is a complex object. It can have multiple different
|
||||
// subtypes for each field, as defined in the `Fields` field. Mandatory
|
||||
// fields are listed in `RequiredFields`. The key of the object is
|
||||
// always of type `string`.
|
||||
type Kind struct {
|
||||
BaseSchema
|
||||
|
||||
// Lists names of required fields.
|
||||
RequiredFields []string
|
||||
// Maps field names to types.
|
||||
Fields map[string]Schema
|
||||
}
|
||||
|
||||
var _ Schema = &Kind{}
|
||||
|
||||
func (k *Kind) Accept(v SchemaVisitor) {
|
||||
v.VisitKind(k)
|
||||
}
|
||||
|
||||
func (k *Kind) GetName() string {
|
||||
properties := []string{}
|
||||
for key := range k.Fields {
|
||||
properties = append(properties, key)
|
||||
}
|
||||
return fmt.Sprintf("Kind(%v)", properties)
|
||||
}
|
||||
|
||||
// IsRequired returns true if `field` is a required field for this type.
|
||||
func (k *Kind) IsRequired(field string) bool {
|
||||
for _, f := range k.RequiredFields {
|
||||
if f == field {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Keys returns a alphabetically sorted list of keys.
|
||||
func (k *Kind) Keys() []string {
|
||||
keys := make([]string, 0)
|
||||
for key := range k.Fields {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// Map is an object who values must all be of the same `SubType`.
|
||||
// The key of the object is always of type `string`.
|
||||
type Map struct {
|
||||
BaseSchema
|
||||
|
||||
SubType Schema
|
||||
}
|
||||
|
||||
var _ Schema = &Map{}
|
||||
|
||||
func (m *Map) Accept(v SchemaVisitor) {
|
||||
v.VisitMap(m)
|
||||
}
|
||||
|
||||
func (m *Map) GetName() string {
|
||||
return fmt.Sprintf("Map of %s", m.SubType.GetName())
|
||||
}
|
||||
|
||||
// Primitive is a literal. There can be multiple types of primitives,
|
||||
// and this subtype can be visited through the `subType` field.
|
||||
type Primitive struct {
|
||||
BaseSchema
|
||||
|
||||
// Type of a primitive must be one of: integer, number, string, boolean.
|
||||
Type string
|
||||
Format string
|
||||
}
|
||||
|
||||
var _ Schema = &Primitive{}
|
||||
|
||||
func (p *Primitive) Accept(v SchemaVisitor) {
|
||||
v.VisitPrimitive(p)
|
||||
}
|
||||
|
||||
func (p *Primitive) GetName() string {
|
||||
if p.Format == "" {
|
||||
return p.Type
|
||||
}
|
||||
return fmt.Sprintf("%s (%s)", p.Type, p.Format)
|
||||
}
|
||||
|
||||
// Reference implementation depends on the type of document.
|
||||
type Reference interface {
|
||||
Schema
|
||||
|
||||
Reference() string
|
||||
SubSchema() Schema
|
||||
}
|
Loading…
Reference in New Issue
Block a user