Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update reaper, scaler, describer for GroupKind #17798

Merged
merged 1 commit into from
Nov 30, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions contrib/completions/bash/kubectl
Expand Up @@ -330,7 +330,12 @@ _kubectl_describe()

must_have_one_flag=()
must_have_one_noun=()
must_have_one_noun+=("daemonset")
must_have_one_noun+=("deployment")
must_have_one_noun+=("endpoints")
must_have_one_noun+=("horizontalpodautoscaler")
must_have_one_noun+=("ingress")
must_have_one_noun+=("job")
must_have_one_noun+=("limitrange")
must_have_one_noun+=("namespace")
must_have_one_noun+=("node")
Expand Down
5 changes: 5 additions & 0 deletions pkg/api/register.go
Expand Up @@ -27,6 +27,11 @@ var Scheme = runtime.NewScheme()
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: "", Version: ""}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

func init() {
Scheme.AddKnownTypes(SchemeGroupVersion,
&Pod{},
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/componentconfig/register.go
Expand Up @@ -28,6 +28,11 @@ func init() {
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: "componentconfig", Version: ""}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

func addKnownTypes() {
// TODO this will get cleaned up with the scheme types are fixed
api.Scheme.AddKnownTypes(SchemeGroupVersion,
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/extensions/register.go
Expand Up @@ -24,6 +24,11 @@ import (
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: "extensions", Version: ""}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

func init() {
// Register the API.
addKnownTypes()
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/metrics/register.go
Expand Up @@ -29,6 +29,11 @@ func init() {
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: "metrics", Version: ""}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

// Adds the list of known types to api.Scheme.
func addKnownTypes() {
// TODO this will get cleaned up with the scheme types are fixed
Expand Down
10 changes: 3 additions & 7 deletions pkg/kubectl/cmd/util/factory.go
Expand Up @@ -172,15 +172,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
return nil, fmt.Errorf("unable to get RESTClient for resource '%s'", mapping.Resource)
},
Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) {
gvk, err := api.RESTMapper.KindFor(mapping.Resource)
if err != nil {
return nil, err
}
client, err := clients.ClientForVersion(mapping.GroupVersionKind.GroupVersion().String())
if err != nil {
return nil, err
}
if describer, ok := kubectl.DescriberFor(gvk.Group, mapping.GroupVersionKind.Kind, client); ok {
if describer, ok := kubectl.DescriberFor(mapping.GroupVersionKind.GroupKind(), client); ok {
return describer, nil
}
return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind)
Expand Down Expand Up @@ -257,14 +253,14 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
if err != nil {
return nil, err
}
return kubectl.ScalerFor(mapping.GroupVersionKind.Kind, client)
return kubectl.ScalerFor(mapping.GroupVersionKind.GroupKind(), client)
},
Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) {
client, err := clients.ClientForVersion(mapping.GroupVersionKind.GroupVersion().String())
if err != nil {
return nil, err
}
return kubectl.ReaperFor(mapping.GroupVersionKind.Kind, client)
return kubectl.ReaperFor(mapping.GroupVersionKind.GroupKind(), client)
},
Validator: func(validate bool, cacheDir string) (validation.Schema, error) {
if validate {
Expand Down
61 changes: 25 additions & 36 deletions pkg/kubectl/describe.go
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fieldpath"
Expand Down Expand Up @@ -66,58 +67,46 @@ func (e ErrNoDescriber) Error() string {
return fmt.Sprintf("no describer has been defined for %v", e.Types)
}

func describerMap(c *client.Client) map[string]Describer {
m := map[string]Describer{
"Pod": &PodDescriber{c},
"ReplicationController": &ReplicationControllerDescriber{c},
"Secret": &SecretDescriber{c},
"Service": &ServiceDescriber{c},
"ServiceAccount": &ServiceAccountDescriber{c},
"Node": &NodeDescriber{c},
"LimitRange": &LimitRangeDescriber{c},
"ResourceQuota": &ResourceQuotaDescriber{c},
"PersistentVolume": &PersistentVolumeDescriber{c},
"PersistentVolumeClaim": &PersistentVolumeClaimDescriber{c},
"Namespace": &NamespaceDescriber{c},
"Endpoints": &EndpointsDescriber{c},
func describerMap(c *client.Client) map[unversioned.GroupKind]Describer {
m := map[unversioned.GroupKind]Describer{
api.Kind("Pod"): &PodDescriber{c},
api.Kind("ReplicationController"): &ReplicationControllerDescriber{c},
api.Kind("Secret"): &SecretDescriber{c},
api.Kind("Service"): &ServiceDescriber{c},
api.Kind("ServiceAccount"): &ServiceAccountDescriber{c},
api.Kind("Node"): &NodeDescriber{c},
api.Kind("LimitRange"): &LimitRangeDescriber{c},
api.Kind("ResourceQuota"): &ResourceQuotaDescriber{c},
api.Kind("PersistentVolume"): &PersistentVolumeDescriber{c},
api.Kind("PersistentVolumeClaim"): &PersistentVolumeClaimDescriber{c},
api.Kind("Namespace"): &NamespaceDescriber{c},
api.Kind("Endpoints"): &EndpointsDescriber{c},

extensions.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
extensions.Kind("DaemonSet"): &DaemonSetDescriber{c},
extensions.Kind("Job"): &JobDescriber{c},
extensions.Kind("Deployment"): &DeploymentDescriber{c},
extensions.Kind("Ingress"): &IngressDescriber{c},
}
return m
}

func expDescriberMap(c *client.Client) map[string]Describer {
return map[string]Describer{
"HorizontalPodAutoscaler": &HorizontalPodAutoscalerDescriber{c},
"DaemonSet": &DaemonSetDescriber{c},
"Job": &JobDescriber{c},
"Deployment": &DeploymentDescriber{c},
"Ingress": &IngressDescriber{c},
}
return m
}

// List of all resource types we can describe
func DescribableResources() []string {
keys := make([]string, 0)

for k := range describerMap(nil) {
resource := strings.ToLower(k)
resource := strings.ToLower(k.Kind)
keys = append(keys, resource)
}
return keys
}

// Describer returns the default describe functions for each of the standard
// Kubernetes types.
func DescriberFor(group string, kind string, c *client.Client) (Describer, bool) {
var f Describer
var ok bool

switch group {
case "":
f, ok = describerMap(c)[kind]
case "extensions":
f, ok = expDescriberMap(c)[kind]
}

func DescriberFor(kind unversioned.GroupKind, c *client.Client) (Describer, bool) {
f, ok := describerMap(c)[kind]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return describerMap(c)[kind]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return describerMap(c)[kind]

That won't compile. the value, ok return is some sort of special cased thing. When done with a return, its just the value

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😥

return f, ok
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl/rolling_updater.go
Expand Up @@ -342,7 +342,7 @@ func (r *RollingUpdater) scaleDown(newRc, oldRc *api.ReplicationController, desi

// scalerScaleAndWait scales a controller using a Scaler and a real client.
func (r *RollingUpdater) scaleAndWaitWithScaler(rc *api.ReplicationController, retry *RetryParams, wait *RetryParams) (*api.ReplicationController, error) {
scaler, err := ScalerFor("ReplicationController", r.c)
scaler, err := ScalerFor(api.Kind("ReplicationController"), r.c)
if err != nil {
return nil, fmt.Errorf("Couldn't make scaler: %s", err)
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/kubectl/scale.go
Expand Up @@ -23,6 +23,7 @@ import (

"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/util/wait"
Expand All @@ -39,13 +40,13 @@ type Scaler interface {
ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) error
}

func ScalerFor(kind string, c client.Interface) (Scaler, error) {
func ScalerFor(kind unversioned.GroupKind, c client.Interface) (Scaler, error) {
switch kind {
case "ReplicationController":
case api.Kind("ReplicationController"):
return &ReplicationControllerScaler{c}, nil
case "Job":
case extensions.Kind("Job"):
return &JobScaler{c.Extensions()}, nil
case "Deployment":
case extensions.Kind("Deployment"):
return &DeploymentScaler{c.Extensions()}, nil
}
return nil, fmt.Errorf("no scaler has been implemented for %q", kind)
Expand Down
26 changes: 16 additions & 10 deletions pkg/kubectl/stop.go
Expand Up @@ -23,6 +23,7 @@ import (

"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fields"
Expand All @@ -45,30 +46,35 @@ type Reaper interface {
}

type NoSuchReaperError struct {
kind string
kind unversioned.GroupKind
}

func (n *NoSuchReaperError) Error() string {
return fmt.Sprintf("no reaper has been implemented for %q", n.kind)
return fmt.Sprintf("no reaper has been implemented for %v", n.kind)
}

func IsNoSuchReaperError(err error) bool {
_, ok := err.(*NoSuchReaperError)
return ok
}

func ReaperFor(kind string, c client.Interface) (Reaper, error) {
func ReaperFor(kind unversioned.GroupKind, c client.Interface) (Reaper, error) {
switch kind {
case "ReplicationController":
case api.Kind("ReplicationController"):
return &ReplicationControllerReaper{c, Interval, Timeout}, nil
case "DaemonSet":

case extensions.Kind("DaemonSet"):
return &DaemonSetReaper{c, Interval, Timeout}, nil
case "Pod":

case api.Kind("Pod"):
return &PodReaper{c}, nil
case "Service":

case api.Kind("Service"):
return &ServiceReaper{c}, nil
case "Job":

case extensions.Kind("Job"):
return &JobReaper{c, Interval, Timeout}, nil

}
return nil, &NoSuchReaperError{kind}
}
Expand Down Expand Up @@ -120,7 +126,7 @@ func getOverlappingControllers(c client.ReplicationControllerInterface, rc *api.

func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
rc := reaper.ReplicationControllers(namespace)
scaler, err := ScalerFor("ReplicationController", *reaper)
scaler, err := ScalerFor(api.Kind("ReplicationController"), *reaper)
if err != nil {
return err
}
Expand Down Expand Up @@ -224,7 +230,7 @@ func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duratio
func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
jobs := reaper.Extensions().Jobs(namespace)
pods := reaper.Pods(namespace)
scaler, err := ScalerFor("Job", *reaper)
scaler, err := ScalerFor(extensions.Kind("Job"), *reaper)
if err != nil {
return err
}
Expand Down
11 changes: 6 additions & 5 deletions pkg/kubectl/stop_test.go
Expand Up @@ -24,6 +24,7 @@ import (
"time"

"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
Expand Down Expand Up @@ -424,7 +425,7 @@ func (c *reaperFake) Services(namespace string) client.ServiceInterface {
func TestSimpleStop(t *testing.T) {
tests := []struct {
fake *reaperFake
kind string
kind unversioned.GroupKind
actions []testclient.Action
expectError bool
test string
Expand All @@ -433,7 +434,7 @@ func TestSimpleStop(t *testing.T) {
fake: &reaperFake{
Fake: &testclient.Fake{},
},
kind: "Pod",
kind: api.Kind("Pod"),
actions: []testclient.Action{
testclient.NewGetAction("pods", api.NamespaceDefault, "foo"),
testclient.NewDeleteAction("pods", api.NamespaceDefault, "foo"),
Expand All @@ -445,7 +446,7 @@ func TestSimpleStop(t *testing.T) {
fake: &reaperFake{
Fake: &testclient.Fake{},
},
kind: "Service",
kind: api.Kind("Service"),
actions: []testclient.Action{
testclient.NewGetAction("services", api.NamespaceDefault, "foo"),
testclient.NewDeleteAction("services", api.NamespaceDefault, "foo"),
Expand All @@ -458,7 +459,7 @@ func TestSimpleStop(t *testing.T) {
Fake: &testclient.Fake{},
noSuchPod: true,
},
kind: "Pod",
kind: api.Kind("Pod"),
actions: []testclient.Action{},
expectError: true,
test: "stop pod fails, no pod",
Expand All @@ -468,7 +469,7 @@ func TestSimpleStop(t *testing.T) {
Fake: &testclient.Fake{},
noDeleteService: true,
},
kind: "Service",
kind: api.Kind("Service"),
actions: []testclient.Action{
testclient.NewGetAction("services", api.NamespaceDefault, "foo"),
},
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/daemon_set.go
Expand Up @@ -98,7 +98,7 @@ var _ = Describe("Daemon set", func() {
Expect(err).NotTo(HaveOccurred())
defer func() {
Logf("Check that reaper kills all daemon pods for %s", dsName)
dsReaper, err := kubectl.ReaperFor("DaemonSet", c)
dsReaper, err := kubectl.ReaperFor(extensions.Kind("DaemonSet"), c)
Expect(err).NotTo(HaveOccurred())
err = dsReaper.Stop(ns, dsName, 0, nil)
Expect(err).NotTo(HaveOccurred())
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/job.go
Expand Up @@ -124,7 +124,7 @@ var _ = Describe("Job", func() {
Expect(err).NotTo(HaveOccurred())

By("scale job up")
scaler, err := kubectl.ScalerFor("Job", f.Client)
scaler, err := kubectl.ScalerFor(extensions.Kind("Job"), f.Client)
Expect(err).NotTo(HaveOccurred())
waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute)
waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute)
Expand All @@ -149,7 +149,7 @@ var _ = Describe("Job", func() {
Expect(err).NotTo(HaveOccurred())

By("scale job down")
scaler, err := kubectl.ScalerFor("Job", f.Client)
scaler, err := kubectl.ScalerFor(extensions.Kind("Job"), f.Client)
Expect(err).NotTo(HaveOccurred())
waitForScale := kubectl.NewRetryParams(5*time.Second, 1*time.Minute)
waitForReplicas := kubectl.NewRetryParams(5*time.Second, 5*time.Minute)
Expand All @@ -172,7 +172,7 @@ var _ = Describe("Job", func() {
Expect(err).NotTo(HaveOccurred())

By("scale job down")
reaper, err := kubectl.ReaperFor("Job", f.Client)
reaper, err := kubectl.ReaperFor(extensions.Kind("Job"), f.Client)
Expect(err).NotTo(HaveOccurred())
timeout := 1 * time.Minute
err = reaper.Stop(f.Namespace.Name, job.Name, timeout, api.NewDeleteOptions(0))
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/util.go
Expand Up @@ -1710,7 +1710,7 @@ func getNodeEvents(c *client.Client, nodeName string) []api.Event {

func ScaleRC(c *client.Client, ns, name string, size uint, wait bool) error {
By(fmt.Sprintf("Scaling replication controller %s in namespace %s to %d", name, ns, size))
scaler, err := kubectl.ScalerFor("ReplicationController", c)
scaler, err := kubectl.ScalerFor(api.Kind("ReplicationController"), c)
if err != nil {
return err
}
Expand Down