mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
Merge pull request #13523 from roofmonkey/experimental-api-fixes
Experimental api fixes
This commit is contained in:
commit
6698257239
@ -46,6 +46,7 @@ type Interface interface {
|
||||
PersistentVolumesInterface
|
||||
PersistentVolumeClaimsNamespacer
|
||||
ComponentStatusesInterface
|
||||
Experimental() ExperimentalInterface
|
||||
}
|
||||
|
||||
func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface {
|
||||
@ -122,6 +123,7 @@ type APIStatus interface {
|
||||
// Client is the implementation of a Kubernetes client.
|
||||
type Client struct {
|
||||
*RESTClient
|
||||
*ExperimentalClient
|
||||
}
|
||||
|
||||
// ServerVersion retrieves and parses the server's version.
|
||||
@ -192,3 +194,7 @@ func IsTimeout(err error) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Client) Experimental() ExperimentalInterface {
|
||||
return c.ExperimentalClient
|
||||
}
|
||||
|
@ -54,7 +54,6 @@ type Response struct {
|
||||
|
||||
type testClient struct {
|
||||
*Client
|
||||
*ExperimentalClient
|
||||
Request testRequest
|
||||
Response Response
|
||||
Error bool
|
||||
@ -87,16 +86,6 @@ func (c *testClient) Setup() *testClient {
|
||||
Version: version,
|
||||
})
|
||||
}
|
||||
if c.ExperimentalClient == nil {
|
||||
version := c.Version
|
||||
if len(version) == 0 {
|
||||
version = testapi.Version()
|
||||
}
|
||||
c.ExperimentalClient = NewExperimentalOrDie(&Config{
|
||||
Host: c.server.URL,
|
||||
Version: version,
|
||||
})
|
||||
}
|
||||
c.QueryValidator = map[string]func(string, string) bool{}
|
||||
return c
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ func TestListDaemons(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
receivedControllerList, err := c.Setup().Daemons(ns).List(labels.Everything())
|
||||
receivedControllerList, err := c.Setup().Experimental().Daemons(ns).List(labels.Everything())
|
||||
c.Validate(t, receivedControllerList, err)
|
||||
|
||||
}
|
||||
@ -80,14 +80,14 @@ func TestGetDaemon(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
receivedController, err := c.Setup().Daemons(ns).Get("foo")
|
||||
receivedController, err := c.Setup().Experimental().Daemons(ns).Get("foo")
|
||||
c.Validate(t, receivedController, err)
|
||||
}
|
||||
|
||||
func TestGetDaemonWithNoName(t *testing.T) {
|
||||
ns := api.NamespaceDefault
|
||||
c := &testClient{Error: true}
|
||||
receivedPod, err := c.Setup().Daemons(ns).Get("")
|
||||
receivedPod, err := c.Setup().Experimental().Daemons(ns).Get("")
|
||||
if (err != nil) && (err.Error() != nameRequiredError) {
|
||||
t.Errorf("Expected error: %v, but got %v", nameRequiredError, err)
|
||||
}
|
||||
@ -118,7 +118,7 @@ func TestUpdateDaemon(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
receivedController, err := c.Setup().Daemons(ns).Update(requestController)
|
||||
receivedController, err := c.Setup().Experimental().Daemons(ns).Update(requestController)
|
||||
c.Validate(t, receivedController, err)
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ func TestDeleteDaemon(t *testing.T) {
|
||||
Request: testRequest{Method: "DELETE", Path: testapi.ResourcePath(getDCResourceName(), ns, "foo"), Query: buildQueryValues(nil)},
|
||||
Response: Response{StatusCode: 200},
|
||||
}
|
||||
err := c.Setup().Daemons(ns).Delete("foo")
|
||||
err := c.Setup().Experimental().Daemons(ns).Delete("foo")
|
||||
c.Validate(t, nil, err)
|
||||
}
|
||||
|
||||
@ -155,6 +155,6 @@ func TestCreateDaemon(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
receivedController, err := c.Setup().Daemons(ns).Create(requestController)
|
||||
receivedController, err := c.Setup().Experimental().Daemons(ns).Create(requestController)
|
||||
c.Validate(t, receivedController, err)
|
||||
}
|
||||
|
@ -119,9 +119,7 @@ func NewExperimentalOrDie(c *Config) *ExperimentalClient {
|
||||
}
|
||||
|
||||
func setExperimentalDefaults(config *Config) error {
|
||||
if config.Prefix == "" {
|
||||
config.Prefix = "/experimental"
|
||||
}
|
||||
config.Prefix = "/experimental"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
@ -139,7 +139,12 @@ func New(c *Config) (*Client, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Client{client}, nil
|
||||
experimentalConfig := *c
|
||||
experimentalClient, err := NewExperimental(&experimentalConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Client{RESTClient: client, ExperimentalClient: experimentalClient}, nil
|
||||
}
|
||||
|
||||
// MatchesServerVersion queries the server to compares the build version
|
||||
|
@ -49,7 +49,7 @@ func TestHorizontalPodAutoscalerCreate(t *testing.T) {
|
||||
Response: Response{StatusCode: 200, Body: &horizontalPodAutoscaler},
|
||||
}
|
||||
|
||||
response, err := c.Setup().HorizontalPodAutoscalers(ns).Create(&horizontalPodAutoscaler)
|
||||
response, err := c.Setup().Experimental().HorizontalPodAutoscalers(ns).Create(&horizontalPodAutoscaler)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@ -74,7 +74,7 @@ func TestHorizontalPodAutoscalerGet(t *testing.T) {
|
||||
Response: Response{StatusCode: 200, Body: horizontalPodAutoscaler},
|
||||
}
|
||||
|
||||
response, err := c.Setup().HorizontalPodAutoscalers(ns).Get("abc")
|
||||
response, err := c.Setup().Experimental().HorizontalPodAutoscalers(ns).Get("abc")
|
||||
c.Validate(t, response, err)
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ func TestHorizontalPodAutoscalerList(t *testing.T) {
|
||||
},
|
||||
Response: Response{StatusCode: 200, Body: horizontalPodAutoscalerList},
|
||||
}
|
||||
response, err := c.Setup().HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything())
|
||||
response, err := c.Setup().Experimental().HorizontalPodAutoscalers(ns).List(labels.Everything(), fields.Everything())
|
||||
c.Validate(t, response, err)
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ func TestHorizontalPodAutoscalerUpdate(t *testing.T) {
|
||||
Request: testRequest{Method: "PUT", Path: testapi.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "abc"), Query: buildQueryValues(nil)},
|
||||
Response: Response{StatusCode: 200, Body: horizontalPodAutoscaler},
|
||||
}
|
||||
response, err := c.Setup().HorizontalPodAutoscalers(ns).Update(horizontalPodAutoscaler)
|
||||
response, err := c.Setup().Experimental().HorizontalPodAutoscalers(ns).Update(horizontalPodAutoscaler)
|
||||
c.Validate(t, response, err)
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ func TestHorizontalPodAutoscalerDelete(t *testing.T) {
|
||||
Request: testRequest{Method: "DELETE", Path: testapi.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "foo"), Query: buildQueryValues(nil)},
|
||||
Response: Response{StatusCode: 200},
|
||||
}
|
||||
err := c.Setup().HorizontalPodAutoscalers(ns).Delete("foo", nil)
|
||||
err := c.Setup().Experimental().HorizontalPodAutoscalers(ns).Delete("foo", nil)
|
||||
c.Validate(t, nil, err)
|
||||
}
|
||||
|
||||
@ -138,6 +138,6 @@ func TestHorizontalPodAutoscalerWatch(t *testing.T) {
|
||||
Query: url.Values{"resourceVersion": []string{}}},
|
||||
Response: Response{StatusCode: 200},
|
||||
}
|
||||
_, err := c.Setup().HorizontalPodAutoscalers(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), "")
|
||||
_, err := c.Setup().Experimental().HorizontalPodAutoscalers(api.NamespaceAll).Watch(labels.Everything(), fields.Everything(), "")
|
||||
c.Validate(t, nil, err)
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
// FakeDaemons implements DaemonInterface. Meant to be embedded into a struct to get a default
|
||||
// implementation. This makes faking out just the method you want to test easier.
|
||||
type FakeDaemons struct {
|
||||
Fake *Fake
|
||||
Fake *FakeExperimental
|
||||
Namespace string
|
||||
}
|
||||
|
||||
|
@ -171,10 +171,6 @@ func (c *Fake) ReplicationControllers(namespace string) client.ReplicationContro
|
||||
return &FakeReplicationControllers{Fake: c, Namespace: namespace}
|
||||
}
|
||||
|
||||
func (c *Fake) Daemons(namespace string) client.DaemonInterface {
|
||||
return &FakeDaemons{Fake: c, Namespace: namespace}
|
||||
}
|
||||
|
||||
func (c *Fake) Nodes() client.NodeInterface {
|
||||
return &FakeNodes{Fake: c}
|
||||
}
|
||||
@ -219,6 +215,10 @@ func (c *Fake) Namespaces() client.NamespaceInterface {
|
||||
return &FakeNamespaces{Fake: c}
|
||||
}
|
||||
|
||||
func (c *Fake) Experimental() client.ExperimentalInterface {
|
||||
return &FakeExperimental{c}
|
||||
}
|
||||
|
||||
func (c *Fake) ServerVersion() (*version.Info, error) {
|
||||
action := ActionImpl{}
|
||||
action.Verb = "get"
|
||||
@ -241,3 +241,23 @@ func (c *Fake) ServerAPIVersions() (*api.APIVersions, error) {
|
||||
func (c *Fake) ComponentStatuses() client.ComponentStatusInterface {
|
||||
return &FakeComponentStatuses{Fake: c}
|
||||
}
|
||||
|
||||
type FakeExperimental struct {
|
||||
*Fake
|
||||
}
|
||||
|
||||
func (c *FakeExperimental) Daemons(namespace string) client.DaemonInterface {
|
||||
return &FakeDaemons{Fake: c, Namespace: namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExperimental) HorizontalPodAutoscalers(namespace string) client.HorizontalPodAutoscalerInterface {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (c *FakeExperimental) Scales(namespace string) client.ScaleInterface {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (c *FakeExperimental) Deployments(namespace string) client.DeploymentInterface {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
@ -58,12 +58,8 @@ func RunApiVersions(f *cmdutil.Factory, w io.Writer) error {
|
||||
}
|
||||
|
||||
var expAPIVersions *api.APIVersions
|
||||
showExpVersions := false
|
||||
expClient, err := f.ExperimentalClient()
|
||||
if err == nil {
|
||||
expAPIVersions, err = expClient.ServerAPIVersions()
|
||||
showExpVersions = err == nil
|
||||
}
|
||||
expAPIVersions, err = client.Experimental().ServerAPIVersions()
|
||||
showExpVersions := (err == nil)
|
||||
|
||||
fmt.Fprintf(w, "Available Server Api Versions: %#v\n", *apiVersions)
|
||||
if showExpVersions {
|
||||
|
@ -89,28 +89,3 @@ func (c *ClientCache) ClientForVersion(version string) (*client.Client, error) {
|
||||
c.clients[config.Version] = client
|
||||
return client, nil
|
||||
}
|
||||
|
||||
type ExperimentalClientCache struct {
|
||||
loader clientcmd.ClientConfig
|
||||
client *client.ExperimentalClient
|
||||
err error
|
||||
init bool
|
||||
}
|
||||
|
||||
func NewExperimentalClientCache(loader clientcmd.ClientConfig) *ExperimentalClientCache {
|
||||
return &ExperimentalClientCache{loader: loader}
|
||||
}
|
||||
|
||||
func (cc *ExperimentalClientCache) Client() (*client.ExperimentalClient, error) {
|
||||
if cc.init {
|
||||
return cc.client, cc.err
|
||||
}
|
||||
cfg, err := cc.loader.ClientConfig()
|
||||
if err != nil {
|
||||
cc.err = err
|
||||
} else {
|
||||
cc.client, cc.err = client.NewExperimental(cfg)
|
||||
}
|
||||
cc.init = true
|
||||
return cc.client, cc.err
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -57,8 +56,6 @@ type Factory struct {
|
||||
Object func() (meta.RESTMapper, runtime.ObjectTyper)
|
||||
// Returns a client for accessing Kubernetes resources or an error.
|
||||
Client func() (*client.Client, error)
|
||||
// Returns a client for accessing experimental Kubernetes resources or an error.
|
||||
ExperimentalClient func() (*client.ExperimentalClient, error)
|
||||
// Returns a client.Config for accessing the Kubernetes server.
|
||||
ClientConfig func() (*client.Config, error)
|
||||
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
|
||||
@ -110,28 +107,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
}
|
||||
|
||||
clients := NewClientCache(clientConfig)
|
||||
expClients := NewExperimentalClientCache(clientConfig)
|
||||
|
||||
noClientErr := errors.New("could not get client")
|
||||
getBothClients := func(group string, version string) (*client.Client, *client.ExperimentalClient, error) {
|
||||
switch group {
|
||||
case "api":
|
||||
client, err := clients.ClientForVersion(version)
|
||||
return client, nil, err
|
||||
|
||||
case "experimental":
|
||||
client, err := clients.ClientForVersion(version)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
expClient, err := expClients.Client()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return client, expClient, err
|
||||
}
|
||||
return nil, nil, noClientErr
|
||||
}
|
||||
return &Factory{
|
||||
clients: clients,
|
||||
flags: flags,
|
||||
@ -147,30 +123,20 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
Client: func() (*client.Client, error) {
|
||||
return clients.ClientForVersion("")
|
||||
},
|
||||
ExperimentalClient: func() (*client.ExperimentalClient, error) {
|
||||
return expClients.Client()
|
||||
},
|
||||
ClientConfig: func() (*client.Config, error) {
|
||||
return clients.ClientConfigForVersion("")
|
||||
},
|
||||
RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
|
||||
group, err := api.RESTMapper.GroupForResource(mapping.Resource)
|
||||
client, err := clients.ClientForVersion(mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch group {
|
||||
case "api":
|
||||
client, err := clients.ClientForVersion(mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client.RESTClient, nil
|
||||
case "experimental":
|
||||
client, err := expClients.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client.RESTClient, nil
|
||||
return client.ExperimentalClient.RESTClient, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unable to get RESTClient for resource '%s'", mapping.Resource)
|
||||
},
|
||||
@ -179,11 +145,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, expClient, err := getBothClients(group, mapping.APIVersion)
|
||||
client, err := clients.ClientForVersion(mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if describer, ok := kubectl.DescriberFor(mapping.Kind, client, expClient); ok {
|
||||
if describer, ok := kubectl.DescriberFor(group, mapping.Kind, client); ok {
|
||||
return describer, nil
|
||||
}
|
||||
return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind)
|
||||
@ -235,26 +201,18 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
return meta.NewAccessor().Labels(object)
|
||||
},
|
||||
Scaler: func(mapping *meta.RESTMapping) (kubectl.Scaler, error) {
|
||||
group, err := api.RESTMapper.GroupForResource(mapping.Resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, _, err := getBothClients(group, mapping.APIVersion)
|
||||
client, err := clients.ClientForVersion(mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kubectl.ScalerFor(mapping.Kind, kubectl.NewScalerClient(client))
|
||||
},
|
||||
Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) {
|
||||
group, err := api.RESTMapper.GroupForResource(mapping.Resource)
|
||||
client, err := clients.ClientForVersion(mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, expClient, err := getBothClients(group, mapping.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kubectl.ReaperFor(mapping.Kind, client, expClient)
|
||||
return kubectl.ReaperFor(mapping.Kind, client)
|
||||
},
|
||||
Validator: func(validate bool) (validation.Schema, error) {
|
||||
if validate {
|
||||
@ -262,8 +220,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
expClient, _ := expClients.Client()
|
||||
return &clientSwaggerSchema{client, expClient, api.Scheme}, nil
|
||||
return &clientSwaggerSchema{client, client.ExperimentalClient, api.Scheme}, nil
|
||||
}
|
||||
return validation.NullSchema{}, nil
|
||||
},
|
||||
|
@ -82,12 +82,9 @@ func describerMap(c *client.Client) map[string]Describer {
|
||||
return m
|
||||
}
|
||||
|
||||
func expDescriberMap(c *client.Client, exp *client.ExperimentalClient) map[string]Describer {
|
||||
func expDescriberMap(c *client.Client) map[string]Describer {
|
||||
return map[string]Describer{
|
||||
"HorizontalPodAutoscaler": &HorizontalPodAutoscalerDescriber{
|
||||
client: c,
|
||||
experimental: exp,
|
||||
},
|
||||
"HorizontalPodAutoscaler": &HorizontalPodAutoscalerDescriber{c},
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,16 +101,17 @@ func DescribableResources() []string {
|
||||
|
||||
// Describer returns the default describe functions for each of the standard
|
||||
// Kubernetes types.
|
||||
func DescriberFor(kind string, c *client.Client, ec *client.ExperimentalClient) (Describer, bool) {
|
||||
func DescriberFor(group string, kind string, c *client.Client) (Describer, bool) {
|
||||
var f Describer
|
||||
var ok bool
|
||||
|
||||
if c != nil {
|
||||
switch group {
|
||||
case "api":
|
||||
f, ok = describerMap(c)[kind]
|
||||
case "experimental":
|
||||
f, ok = expDescriberMap(c)[kind]
|
||||
}
|
||||
if !ok && c != nil && ec != nil {
|
||||
f, ok = expDescriberMap(c, ec)[kind]
|
||||
}
|
||||
|
||||
return f, ok
|
||||
}
|
||||
|
||||
@ -1153,12 +1151,11 @@ func describeNode(node *api.Node, pods []*api.Pod, events *api.EventList) (strin
|
||||
|
||||
// HorizontalPodAutoscalerDescriber generates information about a horizontal pod autoscaler.
|
||||
type HorizontalPodAutoscalerDescriber struct {
|
||||
client *client.Client
|
||||
experimental *client.ExperimentalClient
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (string, error) {
|
||||
hpa, err := d.experimental.HorizontalPodAutoscalers(namespace).Get(name)
|
||||
hpa, err := d.client.Experimental().HorizontalPodAutoscalers(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func IsNoSuchReaperError(err error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func ReaperFor(kind string, c client.Interface, ec *client.ExperimentalClient) (Reaper, error) {
|
||||
func ReaperFor(kind string, c client.Interface) (Reaper, error) {
|
||||
switch kind {
|
||||
case "ReplicationController":
|
||||
return &ReplicationControllerReaper{c, Interval, Timeout}, nil
|
||||
|
@ -365,7 +365,7 @@ func TestSimpleStop(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
fake := test.fake
|
||||
reaper, err := ReaperFor(test.kind, fake, nil)
|
||||
reaper, err := ReaperFor(test.kind, fake)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v (%s)", err, test.test)
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ func RCFromManifest(fileName string) *api.ReplicationController {
|
||||
|
||||
// StopRC stops the rc via kubectl's stop library
|
||||
func StopRC(rc *api.ReplicationController, restClient *client.Client) error {
|
||||
reaper, err := kubectl.ReaperFor("ReplicationController", restClient, nil)
|
||||
reaper, err := kubectl.ReaperFor("ReplicationController", restClient)
|
||||
if err != nil || reaper == nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user