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

Compute V2: implement server tags filtering support #1759

Merged
merged 1 commit into from
Oct 25, 2019

Conversation

Fedosin
Copy link
Contributor

@Fedosin Fedosin commented Oct 23, 2019

Server tags support was added in Nova API since 2.26, so we can implement it here as well.

For #1669

Links to the line numbers/files in the OpenStack source code that support the
code in this PR:

https://github.com/openstack/nova/blob/3b54979ae02cc74bcf215713c16916bbf4131443/nova/api/openstack/compute/schemas/servers.py#L645-L651
https://docs.openstack.org/api-ref/compute/?expanded=list-servers-detail,show-server-details-detail#list-servers

@coveralls
Copy link

coveralls commented Oct 23, 2019

Coverage Status

Coverage increased (+0.3%) to 77.2% when pulling 775d353 on Fedosin:server_tags into 96d83b9 on gophercloud:master.

@theopenlab-ci
Copy link

theopenlab-ci bot commented Oct 23, 2019

Build failed.

@theopenlab-ci
Copy link

theopenlab-ci bot commented Oct 23, 2019

Build succeeded.

@jtopjian
Copy link
Contributor

@Fedosin Thank you for submitting this. The referenced issue #1669 has been closed, but I'm OK with re-opening it for this PR. However, there are a few things that need worked out.

Per our contributor tutorial we need to see links to the actual API service implementation of listing tags, not just documentation. To save some time, here's the needed information.

Next, you are adding a field of Tags to the servers.Server result struct. Since tags was added in a microversion, it needs to be handled separately. We already have support for extracting tags here. Please see our documentation on microversions for more details. It would be best if this was reverted.

@ozerovandrei on that note, I believe this can be removed since we already have this functionality in the servers' microversions.go file. I can open a PR to fix this and then this PR can be rebased once that's done.

On the core topic of this PR, the additions to the ListOpts is correct and follows our microversion guidelines. We're not able to use omitempty with ListOpts, so the current implementation is fine.

I'll open a PR to fix the tags extension and then this PR can be rebased. Once that's done, this should be ready to go.

Please let me know if anyone has any questions.

@ozerovandrei ozerovandrei mentioned this pull request Oct 24, 2019
8 tasks
Copy link
Contributor

@jtopjian jtopjian left a comment

Choose a reason for hiding this comment

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

@Fedosin Thank you again for your work on this.

I've merged #1760 which resolves the issues I previously mentioned.

Please see the above comments and discussion and let me know if you have any questions.

}

serverWithTags := serverWithTagsExt{}
serverWithTags := servers.Server{}
Copy link
Contributor

Choose a reason for hiding this comment

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

Per other comments, please revert this change and rebase. After the rebase, I believe this file can go unmodified. Let me know if you have any questions.

NotTags []string `q:"not-tags"`

// NotTagsAny filters on specific server tags. At least one of the tags must be absent for the server.
NotTagsAny []string `q:"not-tags-any"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Just one nit with these in-line comments: can you add:

// This requires the client to be set to microversion 2.26 or later.

To each field?


// Tags is a list of server tags. Tags are arbitrarily defined strings
// attached to a server.
Tags []string `json:"tags"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Per the other comments/discussion, please revert this as there's already a way to achieve this. Let me know if you have any questions with the current implementation, though.

@Fedosin Fedosin force-pushed the server_tags branch 2 times, most recently from 3cd51a5 to 385867a Compare October 24, 2019 15:46
@Fedosin
Copy link
Contributor Author

Fedosin commented Oct 24, 2019

I made this as an extension to ListOpts, plus added a test.
We can always avoid making the extension and put these parameters directly in ListOpts, but as you said it doesn't comply with the rules.

@jtopjian
Copy link
Contributor

We can always avoid making the extension and put these parameters directly in ListOpts

I'm so sorry for the confusion. Adding the parameters directly in ListOpts is the right solution. This is outlined under the "New Request Fields" section in the microversions doc, but it is terribly confusing.

There are three forms of an API amendment/extension that we try to deal with:

  1. New API functionality that is added via an extension.

Nova used to have more well-defined/first-class extensions but collapsed them all into the core code, but other services (such as Neutron) still have a concept of extensions. So between that and the existing openstack/compute/v2/extensions packages, new API features that don't modify the existing request and response bodies are considered an extension.

  1. New response fields that were amended via a microversion

These go under microversions.go in a way that doesn't modify the API response. The reason for this is because of Go's concept of a "zero-value".

We could add the field Tags to the servers.Server struct, but there is no way of determining if the server response doesn't support tags or if there are no tags in the response body. For "tags" specifically, this isn't a huge deal, but there might be other fields where this distinction is important.

So we use the concept of composing new structs and the developer can add their own conditional logic on when they want to do this, with the thinking that the developer will know when they need to support a microversion and when the response should have a microversion-amended response.

  1. New request options that were amended via a microversion

Because we have control over how the request body is sent, we can omit fields that are sent in a request body. So it's possible for us to support microversion amendments in-line of the original structs and functions in the requests.go files.

It would be great if we could do this for responses, but as mentioned above, the zero-value makes it indeterminable, so that's why there's the extra work involved.

You can see some other examples of existing microversion amendments here:

Long story short, the way you originally had the ListOpts is correct. Just add an in-line comment that it requires the client to be set to a specific microversion. If no tag options are specified, their default value is an empty string and it won't be sent in the request body.

Adding the fields to ListOpts is the only change needed to add the functionality you want, so the PR can be trimmed to just that.

I'm really sorry about the confusion and the extra work you put in because of it.

@theopenlab-ci
Copy link

theopenlab-ci bot commented Oct 24, 2019

Build failed.

Server tags filtering support was added in Nova API since 2.26,
so we can implement it here as well.

This patch adds new filters `tags`, `tags-any`, `not-tags`, `not-tags-any`
to server list options.
@theopenlab-ci
Copy link

theopenlab-ci bot commented Oct 25, 2019

Build failed.

@jtopjian
Copy link
Contributor

recheck

@theopenlab-ci
Copy link

theopenlab-ci bot commented Oct 25, 2019

Build failed.

@jtopjian
Copy link
Contributor

The test failures are not related to this PR.

Copy link
Contributor

@jtopjian jtopjian left a comment

Choose a reason for hiding this comment

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

LGTM - thank you so much for your patience.

@jtopjian jtopjian merged commit ac31aca into gophercloud:master Oct 25, 2019
@Fedosin
Copy link
Contributor Author

Fedosin commented Oct 25, 2019

My pleasure :) thanks for your support!

Fedosin added a commit to Fedosin/installer that referenced this pull request Jun 29, 2020
Now to delete servers we first get a list of all available servers
from Nova, and then we iterate through them to find those with
required metadata. In the case of a large number of servers, this
can take a very long time.

Fortunately gophercloud introduced filtering by tags, so we can
start using this feature to get only servers with the required tag.
gophercloud/gophercloud#1759
Fedosin added a commit to Fedosin/installer that referenced this pull request Jul 1, 2020
Now to delete servers we first get a list of all available servers
from Nova, and then we iterate through them to find those with
required metadata. In the case of a large number of servers, this
can take a very long time.

Fortunately gophercloud introduced filtering by tags, so we can
start using this feature to get only servers with the required tag.
gophercloud/gophercloud#1759
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants