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

Complete tags management APIs #1162

Merged
merged 3 commits into from
Jun 25, 2018
Merged

Complete tags management APIs #1162

merged 3 commits into from
Jun 25, 2018

Conversation

jiatongw
Copy link

@jiatongw jiatongw commented Jun 15, 2018

Tags management in govc has 3 steps: 1. Creating tag category. 2. Creating tag. 3.Attaching created tag. This PR is related with the second and last steps.

The tags management issue can be found here #1139

@jiatongw jiatongw changed the title Completed tags management APIs Complete tags management APIs Jun 15, 2018
Copy link
Member

@dougm dougm left a comment

Choose a reason for hiding this comment

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

Looking good @jiatongw
Note that several of my comments apply to all commands.

}

func (cmd *attach) Description() string {
return ` Attach tag to object.
Copy link
Member

Choose a reason for hiding this comment

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

Leading space should be removed.

return "", "", fmt.Errorf("%s not found", managedObj)
case 1:
ref = l[0].Object.Reference()
s := strings.Split(ref.String(), ":")
Copy link
Member

Choose a reason for hiding this comment

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

You can use ref.Type and ref.Value here, rather than splitting the String(). This function could also just return types.ManagedObjectReference instead of the 2 strings.

return "", "", flag.ErrHelp
}
} else {
s := strings.Split(managedObj, ":")
Copy link
Member

Choose a reason for hiding this comment

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

Same comment as above, no need to Split.

)

type attach struct {
*flags.ClientFlag
Copy link
Member

Choose a reason for hiding this comment

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

You can remove this line, since DatacenterFlag already embeds a ClientFlag.

}

func (cmd *attach) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
Copy link
Member

Choose a reason for hiding this comment

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

And remove these 2 ClientFlag lines, as the DatacenterFlag.Register below takes care of this.


func (r getTagName) Write(w io.Writer) error {
for i := range r {
fmt.Fprintln(w, r[i])
Copy link
Member

Choose a reason for hiding this comment

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

Since tags.Tag is a structure rather than just a string, the Write command should use TabWriter to format the output.

Copy link
Member

Choose a reason for hiding this comment

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

Example:

govmomi/govc/role/ls.go

Lines 69 to 75 in b325163

tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
for _, role := range rl {
fmt.Fprintf(tw, "%s\t%s\n", role.Name, role.Info.GetDescription().Summary)
}
return tw.Flush()

return &spec
}

func (c *RestClient) AttachTagToObject(ctx context.Context, tagID string, objID string, objType string) error {
Copy link
Member

Choose a reason for hiding this comment

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

For these methods, instead of tagID and objID as string inputs, can we use 1 input types.ManagedObjectReference instead?

_, _, status, err := c.call(ctx, "POST", fmt.Sprintf("%s?~action=attach", TagAssociationURL), *spec, nil)

if status != http.StatusOK || err != nil {
return fmt.Errorf("Attach tag failed with status code: %d, error message: %s", status, err)
Copy link
Member

Choose a reason for hiding this comment

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

"Error strings should not be capitalized ..." https://github.com/golang/go/wiki/CodeReviewComments#error-strings

}

func (c *RestClient) CreateTag(ctx context.Context, spec *TagCreateSpec) (*string, error) {
stream, _, status, err := c.call(ctx, "POST", TagURL, spec, nil)
Copy link
Member

Choose a reason for hiding this comment

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

We could use the http.MethodPost constant instead of literal "POST", same for the other http methods.

if err != nil {
return err
}
if objs != nil && len(objs) > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

No need to check objs != nil here, len() will return 0 if objs is nil.

if err != nil {
return err
}
fmt.Println(*tag)
Copy link
Author

Choose a reason for hiding this comment

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

The TabWriter function works well with []tags.Tag type. But cannot use to type *tag. (the Writer function inside there is a loop, which cannot range over that type..) Any suggestions? @dougm

Copy link
Member

Choose a reason for hiding this comment

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

No need to use tabwriter when there would only be 1 row, which seems to be the case here. I think you can just do something space delimited like: fmt.Println(tag.ID, tag.Name, tag.Description, tag.OtherField)

Jiatong Wang added 2 commits June 21, 2018 14:46
Add tags/association/ and tags/tags/ folder. Add import packages in main.go. Add two tags helper files to vapi/.
…ant code

Use tabWriter to output a struct, move govc/tags/tags/ files to govc/tags/, remove ClientFlags register and Process() function in which DatecenterFlag is set, use http.Method to replace "GET", "POST", "DELETE", "PATCH" in vapi/tags/ files.
return `Attach tag to object.

Examples:
govc tags.attach ID PATH`
Copy link
Member

Choose a reason for hiding this comment

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

Can you also use example values for the Examples sections? Instead of PATH for example, /dc1/host/cluster1/hostname

}

func (cmd *create) Description() string {
return ` Create tag. This command will output the ID you just created.
Copy link
Member

Choose a reason for hiding this comment

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

Remove leading space. Add newline after summary.

govc/tags/get.go Outdated
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)

for _, item := range t {
fmt.Fprintf(tw, "Name: %s\nID: %s\nDescription: %s\nCategoryID: %s\nUsedBy: %s\n",
Copy link
Member

Choose a reason for hiding this comment

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

There needs to be tab delimiters (\t) for tabwriter. Have a look at the existing govc/*/info.go commands. Speaking of which, this command should probably named tags.info rather than tags.get. You'll see we have many *.info commands that are similar, but we have not commands named get.

govc/tags/get.go Outdated
if err != nil {
return err
}
fmt.Printf("Name: %s\nID: %s\nDescription: %s\nCategoryID: %s\nUsedBy: %s\n",
Copy link
Member

Choose a reason for hiding this comment

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

You can use the same output formatter in this case. For example the code could be changed to only call WriteResult in both cases:

	var result []tags.Tag
	if cmd.name == "" {
		tag, err := c.GetTag(ctx, id)
		if err != nil {
			return err
		}
		result = append(result, tag)
	} else {
		tagSlice, err := c.GetTagByNameForCategory(ctx, cmd.name, id)
		if err != nil {
			return err
		}
		result = getTagName(tagSlice)
	}
	return cmd.WriteResult(result)

fmt.Fprintf(tw, " ID:\t%s\n", item.ID)
fmt.Fprintf(tw, " Description:\t%s\n", item.Description)
fmt.Fprintf(tw, " CategoryID:\t%s\n", item.CategoryID)
fmt.Fprintf(tw, " UsedBy: %s\n", item.UsedBy)
}
Copy link
Author

Choose a reason for hiding this comment

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

Separate fmt.Fprintf() for readable and matching other govc/*/info.go code style

Copy link
Author

@jiatongw jiatongw Jun 22, 2018

Choose a reason for hiding this comment

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

Copy link
Member

@dougm dougm left a comment

Choose a reason for hiding this comment

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

lgtm, thanks @jiatongw

@dougm dougm merged commit 919b728 into vmware:master Jun 25, 2018
@jiatongw jiatongw deleted the tags branch June 25, 2018 17:59
@dougm dougm added this to the 2018.09 milestone Sep 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants