mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #98194 from julianvmodesto/dry-run-openapi
Cache the OpenAPI schema for kubectl server-side dry run
This commit is contained in:
commit
da85ff10cc
@ -27,17 +27,10 @@ import (
|
||||
"k8s.io/client-go/dynamic"
|
||||
)
|
||||
|
||||
// VerifyDryRun returns nil if a resource group-version-kind supports
|
||||
// server-side dry-run. Otherwise, an error is returned.
|
||||
func VerifyDryRun(gvk schema.GroupVersionKind, dynamicClient dynamic.Interface, discoveryClient discovery.DiscoveryInterface) error {
|
||||
verifier := NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
return verifier.HasSupport(gvk)
|
||||
}
|
||||
|
||||
func NewDryRunVerifier(dynamicClient dynamic.Interface, discoveryClient discovery.DiscoveryInterface) *DryRunVerifier {
|
||||
func NewDryRunVerifier(dynamicClient dynamic.Interface, openAPIGetter discovery.OpenAPISchemaInterface) *DryRunVerifier {
|
||||
return &DryRunVerifier{
|
||||
finder: NewCRDFinder(CRDFromDynamic(dynamicClient)),
|
||||
openAPIGetter: discoveryClient,
|
||||
openAPIGetter: openAPIGetter,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,11 +178,7 @@ func (o *AnnotateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.dryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -218,11 +218,7 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(o.DynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(o.DynamicClient, f.OpenAPIGetter())
|
||||
o.FieldManager = GetApplyFieldManagerFlag(cmd, o.ServerSideApply)
|
||||
|
||||
if o.ForceConflicts && !o.ServerSideApply {
|
||||
|
@ -128,11 +128,7 @@ func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
o.output = cmdutil.GetFlagString(cmd, "output")
|
||||
o.shortOutput = o.output == "name"
|
||||
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
@ -41,6 +42,7 @@ import (
|
||||
sptest "k8s.io/apimachinery/pkg/util/strategicpatch/testing"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/discovery"
|
||||
dynamicfakeclient "k8s.io/client-go/dynamic/fake"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
@ -52,21 +54,38 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
fakeSchema = sptest.Fake{Path: filepath.Join("..", "..", "..", "testdata", "openapi", "swagger.json")}
|
||||
testingOpenAPISchemaFns = []func() (openapi.Resources, error){nil, AlwaysErrorOpenAPISchemaFn, openAPISchemaFn}
|
||||
AlwaysErrorOpenAPISchemaFn = func() (openapi.Resources, error) {
|
||||
return nil, errors.New("cannot get openapi spec")
|
||||
fakeSchema = sptest.Fake{Path: filepath.Join("..", "..", "..", "testdata", "openapi", "swagger.json")}
|
||||
testingOpenAPISchemas = []testOpenAPISchema{{OpenAPIGetter: &fakeSchema}, AlwaysErrorsOpenAPISchema, FakeOpenAPISchema}
|
||||
AlwaysErrorsOpenAPISchema = testOpenAPISchema{
|
||||
OpenAPISchemaFn: func() (openapi.Resources, error) {
|
||||
return nil, errors.New("cannot get openapi spec")
|
||||
},
|
||||
OpenAPIGetter: &alwaysErrorsOpenAPISchema{},
|
||||
}
|
||||
openAPISchemaFn = func() (openapi.Resources, error) {
|
||||
s, err := fakeSchema.OpenAPISchema()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return openapi.NewOpenAPIData(s)
|
||||
FakeOpenAPISchema = testOpenAPISchema{
|
||||
OpenAPISchemaFn: func() (openapi.Resources, error) {
|
||||
s, err := fakeSchema.OpenAPISchema()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return openapi.NewOpenAPIData(s)
|
||||
},
|
||||
OpenAPIGetter: &fakeSchema,
|
||||
}
|
||||
codec = scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
|
||||
)
|
||||
|
||||
type testOpenAPISchema struct {
|
||||
OpenAPISchemaFn func() (openapi.Resources, error)
|
||||
OpenAPIGetter discovery.OpenAPISchemaInterface
|
||||
}
|
||||
|
||||
type alwaysErrorsOpenAPISchema struct{}
|
||||
|
||||
func (o *alwaysErrorsOpenAPISchema) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||
return nil, errors.New("cannot get openapi schema")
|
||||
}
|
||||
|
||||
func TestApplyExtraArgsFail(t *testing.T) {
|
||||
f := cmdtesting.NewTestFactory()
|
||||
defer f.Cleanup()
|
||||
@ -518,7 +537,7 @@ func TestApplyObject(t *testing.T) {
|
||||
nameRC, currentRC := readAndAnnotateReplicationController(t, filenameRC)
|
||||
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply when a local object is specified", func(t *testing.T) {
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
@ -540,7 +559,8 @@ func TestApplyObject(t *testing.T) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -566,7 +586,7 @@ func TestApplyPruneObjects(t *testing.T) {
|
||||
nameRC, currentRC := readAndAnnotateReplicationController(t, filenameRC)
|
||||
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply returns correct output", func(t *testing.T) {
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
@ -588,7 +608,8 @@ func TestApplyPruneObjects(t *testing.T) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -631,7 +652,7 @@ func TestApplyObjectOutput(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply returns correct output", func(t *testing.T) {
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
@ -653,7 +674,8 @@ func TestApplyObjectOutput(t *testing.T) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -680,7 +702,7 @@ func TestApplyRetry(t *testing.T) {
|
||||
nameRC, currentRC := readAndAnnotateReplicationController(t, filenameRC)
|
||||
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply retries on conflict error", func(t *testing.T) {
|
||||
firstPatch := true
|
||||
retry := false
|
||||
@ -714,7 +736,8 @@ func TestApplyRetry(t *testing.T) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -860,7 +883,7 @@ func testApplyMultipleObjects(t *testing.T, asList bool) {
|
||||
nameSVC, currentSVC := readAndAnnotateService(t, filenameSVC)
|
||||
pathSVC := "/namespaces/test/services/" + nameSVC
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply on multiple objects", func(t *testing.T) {
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
@ -889,7 +912,8 @@ func testApplyMultipleObjects(t *testing.T, asList bool) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -941,7 +965,7 @@ func TestApplyNULLPreservation(t *testing.T) {
|
||||
verifiedPatch := false
|
||||
deploymentBytes := readDeploymentFromFile(t, filenameDeployObjServerside)
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply preserves NULL fields", func(t *testing.T) {
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
@ -984,7 +1008,8 @@ func TestApplyNULLPreservation(t *testing.T) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -1016,7 +1041,7 @@ func TestUnstructuredApply(t *testing.T) {
|
||||
|
||||
verifiedPatch := false
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply works correctly with unstructured objects", func(t *testing.T) {
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
@ -1050,7 +1075,8 @@ func TestUnstructuredApply(t *testing.T) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -1084,7 +1110,7 @@ func TestUnstructuredIdempotentApply(t *testing.T) {
|
||||
}
|
||||
path := "/namespaces/test/widgets/widget"
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test repeated apply operations on an unstructured object", func(t *testing.T) {
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
defer tf.Cleanup()
|
||||
@ -1115,7 +1141,8 @@ func TestUnstructuredIdempotentApply(t *testing.T) {
|
||||
}
|
||||
}),
|
||||
}
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.ClientConfigVal = cmdtesting.DefaultClientConfig()
|
||||
|
||||
ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
@ -1275,7 +1302,7 @@ func TestForceApply(t *testing.T) {
|
||||
"post": 1,
|
||||
}
|
||||
|
||||
for _, fn := range testingOpenAPISchemaFns {
|
||||
for _, testingOpenAPISchema := range testingOpenAPISchemas {
|
||||
t.Run("test apply with --force", func(t *testing.T) {
|
||||
deleted := false
|
||||
isScaledDownToZero := false
|
||||
@ -1357,7 +1384,8 @@ func TestForceApply(t *testing.T) {
|
||||
}
|
||||
fakeDynamicClient := dynamicfakeclient.NewSimpleDynamicClient(scheme)
|
||||
tf.FakeDynamicClient = fakeDynamicClient
|
||||
tf.OpenAPISchemaFunc = fn
|
||||
tf.OpenAPISchemaFunc = testingOpenAPISchema.OpenAPISchemaFn
|
||||
tf.FakeOpenAPIGetter = testingOpenAPISchema.OpenAPIGetter
|
||||
tf.Client = tf.UnstructuredClient
|
||||
tf.ClientConfigVal = &restclient.Config{}
|
||||
|
||||
|
@ -147,7 +147,7 @@ func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
o.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
|
||||
o.builder = f.NewBuilder()
|
||||
o.scaleKindResolver = scale.NewDiscoveryScaleKindResolver(discoveryClient)
|
||||
|
@ -206,11 +206,7 @@ func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
if err != nil {
|
||||
@ -387,11 +383,7 @@ func (o *CreateSubcommandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
|
||||
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
@ -131,11 +131,7 @@ func (o *ClusterRoleBindingOptions) Complete(f cmdutil.Factory, cmd *cobra.Comma
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -151,11 +151,7 @@ func (o *CreateCronJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
if err != nil {
|
||||
|
@ -156,11 +156,7 @@ func (o *CreateDeploymentOptions) Complete(f cmdutil.Factory, cmd *cobra.Command
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -62,7 +62,7 @@ var (
|
||||
Create an ingress with the specified name.`))
|
||||
|
||||
ingressExample = templates.Examples(i18n.T(`
|
||||
# Create a single ingress called 'simple' that directs requests to foo.com/bar to svc
|
||||
# Create a single ingress called 'simple' that directs requests to foo.com/bar to svc
|
||||
# svc1:8080 with a tls secret "my-cert"
|
||||
kubectl create ingress simple --rule="foo.com/bar=svc1:8080,tls=my-cert"
|
||||
|
||||
@ -75,7 +75,7 @@ var (
|
||||
--annotation ingress.annotation2=bla
|
||||
|
||||
# Create an ingress with the same host and multiple paths
|
||||
kubectl create ingress multipath --class=default \
|
||||
kubectl create ingress multipath --class=default \
|
||||
--rule="foo.com/=svc:port" \
|
||||
--rule="foo.com/admin/=svcadmin:portadmin"
|
||||
|
||||
@ -88,11 +88,11 @@ var (
|
||||
kubectl create ingress ingtls --class=default \
|
||||
--rule="foo.com/=svc:https,tls" \
|
||||
--rule="foo.com/path/subpath*=othersvc:8080"
|
||||
|
||||
|
||||
# Create an ingress with TLS enabled using a specific secret and pathType as Prefix
|
||||
kubectl create ingress ingsecret --class=default \
|
||||
--rule="foo.com/*=svc:8080,tls=secret1"
|
||||
|
||||
|
||||
# Create an ingress with a default backend
|
||||
kubectl create ingress ingdefault --class=default \
|
||||
--default-backend=defaultsvc:http \
|
||||
@ -198,11 +198,7 @@ func (o *CreateIngressOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -146,11 +146,7 @@ func (o *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
if err != nil {
|
||||
|
@ -138,11 +138,7 @@ func (o *PriorityClassOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -136,11 +136,7 @@ func (o *QuotaOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []strin
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resourcecli.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resourcecli.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
|
@ -250,11 +250,7 @@ func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
o.OutputFormat = cmdutil.GetFlagString(cmd, "output")
|
||||
o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
|
||||
|
||||
|
@ -140,11 +140,7 @@ func (o *RoleBindingOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicCient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicCient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
if err != nil {
|
||||
|
@ -118,11 +118,7 @@ func (o *ServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -128,11 +128,7 @@ func (o *ServiceAccountOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
|
@ -188,11 +188,7 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Co
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
if len(o.Raw) == 0 {
|
||||
r := f.NewBuilder().
|
||||
|
@ -487,7 +487,7 @@ func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(o.DynamicClient, o.DiscoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(o.DynamicClient, f.OpenAPIGetter())
|
||||
|
||||
o.CmdNamespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
|
@ -222,11 +222,7 @@ func (o *DrainCmdOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.drainer.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.drainer.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
if o.drainer.Client, err = f.KubernetesClientSet(); err != nil {
|
||||
return err
|
||||
|
@ -178,11 +178,7 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -175,11 +175,7 @@ func (o *LabelOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.dryRunStrategy)
|
||||
o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
|
||||
|
@ -167,11 +167,7 @@ func (o *PatchOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -156,11 +156,7 @@ func (o *ReplaceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -114,11 +114,7 @@ func (o *UndoOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
if o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace(); err != nil {
|
||||
return err
|
||||
|
@ -226,11 +226,7 @@ func (o *RunOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
attachFlag := cmd.Flags().Lookup("attach")
|
||||
if !attachFlag.Changed && o.Interactive {
|
||||
|
@ -157,11 +157,7 @@ func (o *ScaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
o.namespace, o.enforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
|
||||
if err != nil {
|
||||
|
@ -229,11 +229,7 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.dryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -149,11 +149,7 @@ func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
o.Output = cmdutil.GetFlagString(cmd, "output")
|
||||
o.ResolveImage = resolveImageFunc
|
||||
|
||||
|
@ -161,11 +161,7 @@ func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, ar
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -140,11 +140,7 @@ func (o *SetSelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
o.resources, o.selector, err = getResourcesAndSelector(args)
|
||||
if err != nil {
|
||||
|
@ -142,11 +142,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.dryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
o.output = cmdutil.GetFlagString(cmd, "output")
|
||||
o.updatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn
|
||||
|
||||
|
@ -132,11 +132,7 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
|
@ -147,11 +147,7 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
discoveryClient, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, discoveryClient)
|
||||
o.DryRunVerifier = resource.NewDryRunVerifier(dynamicClient, f.OpenAPIGetter())
|
||||
cmdutil.PrintFlagsWithDryRunStrategy(o.PrintFlags, o.DryRunStrategy)
|
||||
|
||||
// retrieves resource and taint args from args
|
||||
|
@ -50,6 +50,8 @@ import (
|
||||
"k8s.io/kubectl/pkg/util/openapi"
|
||||
openapitesting "k8s.io/kubectl/pkg/util/openapi/testing"
|
||||
"k8s.io/kubectl/pkg/validation"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
)
|
||||
|
||||
// InternalType is the schema for internal type
|
||||
@ -398,6 +400,7 @@ type TestFactory struct {
|
||||
|
||||
UnstructuredClientForMappingFunc resource.FakeClientFunc
|
||||
OpenAPISchemaFunc func() (openapi.Resources, error)
|
||||
FakeOpenAPIGetter discovery.OpenAPISchemaInterface
|
||||
}
|
||||
|
||||
// NewTestFactory returns an initialized TestFactory instance
|
||||
@ -502,6 +505,23 @@ func (f *TestFactory) OpenAPISchema() (openapi.Resources, error) {
|
||||
return openapitesting.EmptyResources{}, nil
|
||||
}
|
||||
|
||||
type EmptyOpenAPI struct{}
|
||||
|
||||
func (EmptyOpenAPI) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||
return &openapi_v2.Document{}, nil
|
||||
}
|
||||
|
||||
func (f *TestFactory) OpenAPIGetter() discovery.OpenAPISchemaInterface {
|
||||
if f.FakeOpenAPIGetter != nil {
|
||||
return f.FakeOpenAPIGetter
|
||||
}
|
||||
client, err := f.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return EmptyOpenAPI{}
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// NewBuilder returns an initialized resource.Builder instance
|
||||
func (f *TestFactory) NewBuilder() *resource.Builder {
|
||||
return resource.NewFakeBuilder(
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
@ -61,6 +62,8 @@ type Factory interface {
|
||||
|
||||
// Returns a schema that can validate objects stored on disk.
|
||||
Validator(validate bool) (validation.Schema, error)
|
||||
// OpenAPISchema returns the schema openapi schema definition
|
||||
// OpenAPISchema returns the parsed openapi schema definition
|
||||
OpenAPISchema() (openapi.Resources, error)
|
||||
// OpenAPIGetter returns a getter for the openapi schema document
|
||||
OpenAPIGetter() discovery.OpenAPISchemaInterface
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ limitations under the License.
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@ -38,20 +39,17 @@ import (
|
||||
type factoryImpl struct {
|
||||
clientGetter genericclioptions.RESTClientGetter
|
||||
|
||||
// openAPIGetter loads and caches openapi specs
|
||||
openAPIGetter openAPIGetter
|
||||
}
|
||||
|
||||
type openAPIGetter struct {
|
||||
once sync.Once
|
||||
getter openapi.Getter
|
||||
// Caches OpenAPI document and parsed resources
|
||||
openAPIParser *openapi.CachedOpenAPIParser
|
||||
openAPIGetter *openapi.CachedOpenAPIGetter
|
||||
parser sync.Once
|
||||
getter sync.Once
|
||||
}
|
||||
|
||||
func NewFactory(clientGetter genericclioptions.RESTClientGetter) Factory {
|
||||
if clientGetter == nil {
|
||||
panic("attempt to instantiate client_access_factory with nil clientGetter")
|
||||
}
|
||||
|
||||
f := &factoryImpl{
|
||||
clientGetter: clientGetter,
|
||||
}
|
||||
@ -159,19 +157,32 @@ func (f *factoryImpl) Validator(validate bool) (validation.Schema, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// OpenAPISchema returns metadata and structural information about Kubernetes object definitions.
|
||||
// OpenAPISchema returns metadata and structural information about
|
||||
// Kubernetes object definitions.
|
||||
func (f *factoryImpl) OpenAPISchema() (openapi.Resources, error) {
|
||||
discovery, err := f.clientGetter.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
openAPIGetter := f.OpenAPIGetter()
|
||||
if openAPIGetter == nil {
|
||||
return nil, errors.New("no openapi getter")
|
||||
}
|
||||
|
||||
// Lazily initialize the OpenAPIGetter once
|
||||
f.openAPIGetter.once.Do(func() {
|
||||
// Create the caching OpenAPIGetter
|
||||
f.openAPIGetter.getter = openapi.NewOpenAPIGetter(discovery)
|
||||
// Lazily initialize the OpenAPIParser once
|
||||
f.parser.Do(func() {
|
||||
// Create the caching OpenAPIParser
|
||||
f.openAPIParser = openapi.NewOpenAPIParser(f.OpenAPIGetter())
|
||||
})
|
||||
|
||||
// Delegate to the OpenAPIGetter
|
||||
return f.openAPIGetter.getter.Get()
|
||||
// Delegate to the OpenAPIPArser
|
||||
return f.openAPIParser.Parse()
|
||||
}
|
||||
|
||||
func (f *factoryImpl) OpenAPIGetter() discovery.OpenAPISchemaInterface {
|
||||
discovery, err := f.clientGetter.ToDiscoveryClient()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
f.getter.Do(func() {
|
||||
f.openAPIGetter = openapi.NewOpenAPIGetter(discovery)
|
||||
})
|
||||
|
||||
return f.openAPIGetter
|
||||
}
|
||||
|
@ -19,47 +19,64 @@ package openapi
|
||||
import (
|
||||
"sync"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
"k8s.io/client-go/discovery"
|
||||
)
|
||||
|
||||
// synchronizedOpenAPIGetter fetches the openapi schema once and then caches it in memory
|
||||
type synchronizedOpenAPIGetter struct {
|
||||
// CachedOpenAPIGetter fetches the openapi schema once and then caches it in memory
|
||||
type CachedOpenAPIGetter struct {
|
||||
openAPIClient discovery.OpenAPISchemaInterface
|
||||
|
||||
// Cached results
|
||||
sync.Once
|
||||
openAPISchema Resources
|
||||
openAPISchema *openapi_v2.Document
|
||||
err error
|
||||
|
||||
openAPIClient discovery.OpenAPISchemaInterface
|
||||
}
|
||||
|
||||
var _ Getter = &synchronizedOpenAPIGetter{}
|
||||
|
||||
// Getter is an interface for fetching openapi specs and parsing them into an Resources struct
|
||||
type Getter interface {
|
||||
// OpenAPIData returns the parsed OpenAPIData
|
||||
Get() (Resources, error)
|
||||
}
|
||||
var _ discovery.OpenAPISchemaInterface = &CachedOpenAPIGetter{}
|
||||
|
||||
// NewOpenAPIGetter returns an object to return OpenAPIDatas which reads
|
||||
// from a server, and then stores in memory for subsequent invocations
|
||||
func NewOpenAPIGetter(openAPIClient discovery.OpenAPISchemaInterface) Getter {
|
||||
return &synchronizedOpenAPIGetter{
|
||||
func NewOpenAPIGetter(openAPIClient discovery.OpenAPISchemaInterface) *CachedOpenAPIGetter {
|
||||
return &CachedOpenAPIGetter{
|
||||
openAPIClient: openAPIClient,
|
||||
}
|
||||
}
|
||||
|
||||
// Resources implements Getter
|
||||
func (g *synchronizedOpenAPIGetter) Get() (Resources, error) {
|
||||
// OpenAPISchema implements OpenAPISchemaInterface.
|
||||
func (g *CachedOpenAPIGetter) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||
g.Do(func() {
|
||||
s, err := g.openAPIClient.OpenAPISchema()
|
||||
if err != nil {
|
||||
g.err = err
|
||||
return
|
||||
}
|
||||
|
||||
g.openAPISchema, g.err = NewOpenAPIData(s)
|
||||
g.openAPISchema, g.err = g.openAPIClient.OpenAPISchema()
|
||||
})
|
||||
|
||||
// Return the save result
|
||||
// Return the saved result.
|
||||
return g.openAPISchema, g.err
|
||||
}
|
||||
|
||||
type CachedOpenAPIParser struct {
|
||||
openAPIClient discovery.OpenAPISchemaInterface
|
||||
|
||||
// Cached results
|
||||
sync.Once
|
||||
openAPIResources Resources
|
||||
err error
|
||||
}
|
||||
|
||||
func NewOpenAPIParser(openAPIClient discovery.OpenAPISchemaInterface) *CachedOpenAPIParser {
|
||||
return &CachedOpenAPIParser{
|
||||
openAPIClient: openAPIClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *CachedOpenAPIParser) Parse() (Resources, error) {
|
||||
p.Do(func() {
|
||||
oapi, err := p.openAPIClient.OpenAPISchema()
|
||||
if err != nil {
|
||||
p.err = err
|
||||
return
|
||||
}
|
||||
p.openAPIResources, p.err = NewOpenAPIData(oapi)
|
||||
})
|
||||
|
||||
return p.openAPIResources, p.err
|
||||
}
|
||||
|
@ -40,12 +40,12 @@ func (f *FakeCounter) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||
|
||||
var _ = Describe("Getting the Resources", func() {
|
||||
var client FakeCounter
|
||||
var instance openapi.Getter
|
||||
var instance *openapi.CachedOpenAPIParser
|
||||
var expectedData openapi.Resources
|
||||
|
||||
BeforeEach(func() {
|
||||
client = FakeCounter{}
|
||||
instance = openapi.NewOpenAPIGetter(&client)
|
||||
instance = openapi.NewOpenAPIParser(openapi.NewOpenAPIGetter(&client))
|
||||
var err error
|
||||
expectedData, err = openapi.NewOpenAPIData(nil)
|
||||
Expect(err).To(BeNil())
|
||||
@ -55,12 +55,12 @@ var _ = Describe("Getting the Resources", func() {
|
||||
It("should return the same data for multiple calls", func() {
|
||||
Expect(client.Calls).To(Equal(0))
|
||||
|
||||
result, err := instance.Get()
|
||||
result, err := instance.Parse()
|
||||
Expect(err).To(BeNil())
|
||||
Expect(result).To(Equal(expectedData))
|
||||
Expect(client.Calls).To(Equal(1))
|
||||
|
||||
result, err = instance.Get()
|
||||
result, err = instance.Parse()
|
||||
Expect(err).To(BeNil())
|
||||
Expect(result).To(Equal(expectedData))
|
||||
// No additional client calls expected
|
||||
@ -73,11 +73,11 @@ var _ = Describe("Getting the Resources", func() {
|
||||
Expect(client.Calls).To(Equal(0))
|
||||
|
||||
client.Err = fmt.Errorf("expected error")
|
||||
_, err := instance.Get()
|
||||
_, err := instance.Parse()
|
||||
Expect(err).To(Equal(client.Err))
|
||||
Expect(client.Calls).To(Equal(1))
|
||||
|
||||
_, err = instance.Get()
|
||||
_, err = instance.Parse()
|
||||
Expect(err).To(Equal(client.Err))
|
||||
// No additional client calls expected
|
||||
Expect(client.Calls).To(Equal(1))
|
||||
|
Loading…
Reference in New Issue
Block a user