-
Notifications
You must be signed in to change notification settings - Fork 382
Improve kubectl get experience for service catalog resources #2091
Improve kubectl get experience for service catalog resources #2091
Conversation
0befdfe
to
a2bed79
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a promising start, but I'm not sure of kubectl column naming conventions. A more fundamental question is what information to show for ServiceInstance
re request and matched service/plan and all the different ways you can request a service/plan.
[]metav1beta1.TableColumnDefinition{ | ||
{Name: "Name", Type: "string", Format: "name"}, | ||
{Name: "Instance", Type: "string"}, | ||
{Name: "Secret", Type: "string"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be SecretName
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I've changed this to Secret-Name
so it gets printed as SECRET-NAME
, but I think a simple SECRET
is perfectly fine. This is just the column header.
TableConvertor: tableconvertor.NewTableConvertor( | ||
[]metav1beta1.TableColumnDefinition{ | ||
{Name: "Name", Type: "string", Format: "name"}, | ||
{Name: "External name", Type: "string"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this should be ExternalName
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to External-Name
so it gets printed as EXTERNAL-NAME
(otherwise, it would be printed as EXTERNALNAME
).
{Name: "External name", Type: "string"}, | ||
{Name: "Broker", Type: "string"}, | ||
{Name: "Bindable", Type: "bool"}, | ||
{Name: "Plan updatable", Type: "bool"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm - reading these, I'm not certain what the naming convention is for kubectl columns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They use two different forms:
Cluster-IP
,OS-Image
,Kernel-Version
,Container-Runtime
, ...Node Selector
,Last Schedule
,Access Modes
,Reclaim Policy
[]metav1beta1.TableColumnDefinition{ | ||
{Name: "Name", Type: "string", Format: "name"}, | ||
{Name: "External name", Type: "string"}, | ||
{Name: "Broker", Type: "string"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be ClusterServiceBrokerName
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be the printed name, correct? I thought the point of tweaking the default printing was to get closer to what svcat does (and a huge part of that is making our field names shorter and more intuitive). What's wrong with just Broker
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the value of calling the column CLUSTER-SERVICE-BROKER-NAME
, as it just makes the output unnecessarily wide:
NAME EXTERNAL-NAME CLUSTER-SERVICE-BROKER-NAME BINDABLE PLAN-UPDATABLE AGE
4f6e6cf6-ffdd-425f-a2c7-3c9258ad2468 user-provided-service ups-broker true true 12m
5f6e6cf6-ffdd-425f-a2c7-3c9258ad2468 user-provided-service-single-plan ups-broker true true 12m
8a6229d4-239e-4790-ba1f-8367004d0473 user-provided-service-with-schemas ups-broker true true 12m
TableConvertor: tableconvertor.NewTableConvertor( | ||
[]metav1beta1.TableColumnDefinition{ | ||
{Name: "Name", Type: "string", Format: "name"}, | ||
{Name: "Class", Type: "string"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should think about how we want to differentiate ns/cluster scoped classes/plans and requested vs. matched service/plan here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest not differentiating for now and just printing both cluster and ns-scoped classes/plans in the same column. I definitely don't want to see two different columns for this, as that would make the output too wide.
But we could add a prefix to the values in the column (e.g. csc/class-name
for clusterserviceclasses and sc/class-name
for serviceclasses)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, a couple of us talked about what this should look like in svcat at the last F2F, here are notes:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about it more, I would much rather prefer that we display the namespace (and leave it empty for cluster level resources) than use the prefixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't like the short prefixes idea either. But I also don't like displaying the namespace, since a ServiceInstance never references a ServiceClass/Plan in a different namespace. It's either the same namespace as the ServiceInstance or no namespace.
Actually, I've just remembered that in core k8s, a RoleBinding
can reference either a ClusterRole
or a namespaced Role
. This is how kubectl prints the reference:
$ kubectl get rolebinding -o wide
NAME AGE ROLE USERS ...
test 1m Role/my-namespaced-role foo
test2 2s ClusterRole/my-cluster-role foo
So, to be consistent, we need to prefix with ServiceClass/
and ClusterServiceClass/
.
Here are the new outputs (these include the changes requested by @pmorie):
|
LGTM. This only takes effect if the kubeclient is of a specific version right? Is that 1.10 or 1.11? And older clients get the older, non friendly output? |
@jboyd01 yeah, the client needs to support server-side printing. Looks like this is only enabled by default in kubectl 1.11. In 1.10 you need to enable it explicitly with |
Due to a bug in our travis file, this PR must be rebased in order to get the Travis CI build to run for this PR. |
d3ec96c
to
a5ab712
Compare
Rebased. |
a5ab712
to
5f39bc0
Compare
{Name: "Status", Type: "string"}, | ||
{Name: "Age", Type: "string"}, | ||
}, | ||
func(obj runtime.Object, m metav1.Object, name, age string) ([]interface{}, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've got a bunch of logic just like this in the svcat cli too. Maybe we can consolidate in a follow-on issue?
{Name: "Name", Type: "string", Format: "name"}, | ||
{Name: "External-Name", Type: "string"}, | ||
{Name: "Broker", Type: "string"}, | ||
{Name: "Bindable", Type: "bool"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bindable and plan-updatable aren't great candidates to promote to columns. Maybe I'm missing a use case but that's never information I'm looking for. Description seems more useful to promote up, that's what we display in the svcat cli.
TableConvertor: tableconvertor.NewTableConvertor( | ||
[]metav1beta1.TableColumnDefinition{ | ||
{Name: "Name", Type: "string", Format: "name"}, | ||
{Name: "Class", Type: "string"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After thinking about it more, I would much rather prefer that we display the namespace (and leave it empty for cluster level resources) than use the prefixes.
instance := obj.(*servicecatalog.ServiceInstance) | ||
cells := []interface{}{ | ||
name, | ||
instance.Spec.GetSpecifiedServiceClass(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, @eriknelson 's first pass on this resulted in two separate functions being created: one for cluster level classes/plans and another for namespaced. We spoke at the time about a follow-on PR that consolidated the two when being used by the svcat CLI so that we don't need awkward if/else statements because our helpers aren't helpful enough.
Just wanted you to be aware that this won't work the way you expect right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carolynvs Thanks. Looks like we still don't have a function like GetSpecifiedClusterServiceClassOrServiceClass()
, so I created one myself. I've named it GetSpecifiedClass()
(and GetSpecifiedPlan()
) for now. Any better ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind. I'll throw that function out, since I no longer need it. I'll let someone else deal with the pain of naming these two methods :)
5f39bc0
to
9c6c9fa
Compare
/retest |
@luksa looks like this needs a rebase and updating, seeing unit test failures now. |
ded0b59
to
a26eca5
Compare
Instead of using custom-columns in OpenAPI schema, this commit adds server-side column printing by registering TableConvertors.
a26eca5
to
892ce28
Compare
This is what the ServiceInstance columns look like after my latest changes:
This is now consistent with
Not sure how I feel about the duplication (ServiceClass & ServicePlan). We could maybe omit the prefix in the |
@luksa In svcat I added a namespace column to the output so that if it's set, you know it's a ServicePlan, and if it's empty its a ClusterServicePlan. Maybe something like that would help? |
@carolynvs Not sure if we're talking about the same thing. There are two different problems (I'll focus only on classes here to keep things simple; the same rules should apply to plans):
The first problem only applies to svcat. There's no such problem in kubectl, since you use two different commands ( Because a ServiceInstance can only reference a ServiceClass in the same namespace or a ClusterServiceClass, we only need to show whether the referenced class is namespaced or not. If it is, it's obviously in the same namespace as the instance. I don't like using a
BTW: I don't see
But it does print out both namespaced and global classes:
|
Thanks for the clarification! Yes I was mixing up two different things. FYI, svcat hasn't been updated all the way through to support namespaced brokers. So any weirdness, is just because we aren't done yet. 😀 |
@carolynvs :) So, what's your opinion about prefixing just the So, this is what I'm suggesting:
|
I think that is solid, consistent and understandable. |
892ce28
to
ce86709
Compare
@carolynvs Thanks. Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
I am officially awarding you 1 MILLION ✨ internet points for getting this through. THANK YOU! ❤️
I agree with #2091 (review) - a lot of work to get this in, it will make a great difference to those using kubectl vs svcat. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jboyd01 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Travis failed with this: Verify that vendor/ is in sync with Gopkg.lockdocker run --security-opt label:disable --rm -v /home/travis/build/kubernetes-incubator/service-catalog:/go/src/github.com/kubernetes-incubator/service-catalog -v /home/travis/build/kubernetes-incubator/service-catalog/.cache:/root/.cache/ -v /home/travis/build/kubernetes-incubator/service-catalog/.pkg:/go/pkg --env AZURE_STORAGE_CONNECTION_STRING scbuildimage build/verify-vendor.sh I've restarted the job. |
hmm, different failure this time: Step 3/12 : RUN curl -sSL -o /usr/local/bin/dep https://github.com/golang/dep/releases/download/$DEP_VERSION/dep-linux-amd64 && chmod +x /usr/local/bin/dep restarted again |
travis, travis, travis... Running full build |
Instead of using custom-columns in OpenAPI schema, this commit adds
server-side column printing by registering TableConvertors.