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

Add new command budget to consumption #6024

Merged
merged 13 commits into from
Apr 24, 2018
Merged

Add new command budget to consumption #6024

merged 13 commits into from
Apr 24, 2018

Conversation

bgsky
Copy link
Contributor

@bgsky bgsky commented Apr 5, 2018


This checklist is used to make sure that common guidelines for a pull request are followed.

  • The PR has modified HISTORY.rst describing any customer-facing, functional changes. Note that this does not include changes only to help content. (see Modifying change log).

  • I adhere to the Command Guidelines.

@promptws
Copy link

promptws commented Apr 5, 2018

View a preview at https://prompt.ws/r/Azure/azure-cli/6024
This is an experimental preview for @microsoft users.

@derekbekoe derekbekoe added this to the Sprint 36 (Build) milestone Apr 5, 2018
@@ -2,6 +2,10 @@

Release History
===============
0.3.1
+++++
* Added commands `budget`.
Copy link
Member

Choose a reason for hiding this comment

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

Change to clearer description. Currently, this gives very little information.
Here are some examples from previous releases of the module.
https://docs.microsoft.com/en-us/cli/azure/release-notes-azure-cli?view=azure-cli-latest#consumption
https://docs.microsoft.com/en-us/cli/azure/release-notes-azure-cli?view=azure-cli-latest#consumption-1

return Decimal(string)
except ValueError:
raise ValueError("the value passed cannot be converted to decimal")
return decimal_type
Copy link
Member

Choose a reason for hiding this comment

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

You shouldn't need the wrapper function get_decimal_type.
Just define decimal_type as is then in your param definition, pass the function decimal_type instead of doing get_decimal_type ()

Copy link
Member

Choose a reason for hiding this comment

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

Same with get_datetime_type above.

"""lowercase the time grain for comparison"""
budgetcategory = namespace.category.lower()
if budgetcategory != 'cost' and budgetcategory != 'usage':
raise CLIError("usage error: --parameters.category must be set to either cost or usage")
Copy link
Member

Choose a reason for hiding this comment

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

The param name is --category. User won't know what --parameters.category is.

Copy link
Member

Choose a reason for hiding this comment

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

Additionally, this should be covered by using get_enum_type in the param registration.
https://github.com/Azure/azure-cli/blob/dev/doc/authoring_command_modules/authoring_commands.md#registering-enums

time_grain = namespace.time_grain.lower().strip()

if time_grain != 'annually' and time_grain != 'quarterly' and time_grain != 'monthly':
raise CLIError("usage error: --parameters.time_grain can be 'Annually', 'Quarterly', or 'Monthly'.")
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

Copy link
Member

Choose a reason for hiding this comment

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

raise CLIError("usage error: --parameters.time_grain can be 'Annually', 'Quarterly', or 'Monthly'.")

if namespace.amount < 0:
raise CLIError("usage error: --parameters.amount must be greater than 0")
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

exception_handler=consumption_exception_handler, validator=validate_budget_parameters, client_factory=budget_mgmt_client_factory)

p.custom_command('delete', 'cli_consumption_delete_budget', transform=None,
exception_handler=consumption_exception_handler, client_factory=budget_mgmt_client_factory)
Copy link
Member

Choose a reason for hiding this comment

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

Instead of duplicating exception_handler and client_factory everywhere, you should be able to define them in the command_group and it'll be used for all in the group.

def cli_consumption_list_budgets(client, resource_group_name=None):
if resource_group_name:
return list(client.list_by_resource_group_name(resource_group_name))
return list(client.list())
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 call list() around the SDK calls. The CLI handles this.

@bgsky
Copy link
Contributor Author

bgsky commented Apr 10, 2018

@derekbekoe @tjprescott All comments above are addressed. Please proceed on your side.

Copy link
Member

@tjprescott tjprescott left a comment

Choose a reason for hiding this comment

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

Ditto all of @derekbekoe's comments. Added some of my own.

@@ -34,3 +36,15 @@ def load_arguments(self, _):
cmp.argument('top', options_list=['--top', '-t'], type=int, help='Maximum number of items to return. Value range: 1-1000.')
cmp.argument('start_date', options_list=['--start-date', '-s'], type=get_datetime_type(), help='Start date (YYYY-MM-DD in UTC). If specified, also requires --end-date.')
cmp.argument('end_date', options_list=['--end-date', '-e'], type=get_datetime_type(), help='End date (YYYY-MM-DD in UTC). If specified, also requires --start-date.')

with self.argument_context('consumption budget') as cb:
cb.argument('resource_group_name', options_list='--resource-group-name', type=str, help='Resource group of the budget.')
Copy link
Member

Choose a reason for hiding this comment

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

This is overriding the global resource group aliasing, but shouldn't.


with self.argument_context('consumption budget') as cb:
cb.argument('resource_group_name', options_list='--resource-group-name', type=str, help='Resource group of the budget.')
cb.argument('budget_name', options_list='--budget-name', type=str, help='Name of a budget.')
Copy link
Member

Choose a reason for hiding this comment

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

Options list is not required here. Type is not required.

with self.argument_context('consumption budget') as cb:
cb.argument('resource_group_name', options_list='--resource-group-name', type=str, help='Resource group of the budget.')
cb.argument('budget_name', options_list='--budget-name', type=str, help='Name of a budget.')
cb.argument('category', options_list=['--category', '-c'], type=str, help='Category of the budget can be cost or usage.')
Copy link
Member

Choose a reason for hiding this comment

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

Should be enum type. Type kwarg not required.

cb.argument('budget_name', options_list='--budget-name', type=str, help='Name of a budget.')
cb.argument('category', options_list=['--category', '-c'], type=str, help='Category of the budget can be cost or usage.')
cb.argument('amount', options_list=['--amount', '-a'], type=get_decimal_type(), help='Amount of a budget.')
cb.argument('time_grain', options_list='--time-grain', type=str, help='Time grain of the budget can be monthly, quarterly, or annually.')
Copy link
Member

Choose a reason for hiding this comment

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

Options list not required. Type not required. Should be enum type...

cb.argument('time_grain', options_list='--time-grain', type=str, help='Time grain of the budget can be monthly, quarterly, or annually.')
cb.argument('start_date', options_list=['--start-date', '-s'], type=get_datetime_type(), help='Start date (YYYY-MM-DD in UTC) of time period of a budget.')
cb.argument('end_date', options_list=['--end-date', '-e'], type=get_datetime_type(), help='End date (YYYY-MM-DD in UTC) of time period of a budget.')
cb.argument('resource_groups', options_list='--resource-groups', nargs='+', help='Space-separated list of resource groups to filter on.')
Copy link
Member

Choose a reason for hiding this comment

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

Options list not required. These filter type arguments should have arg_group='Filter' so they stand out in help. Right now, you'll have

--resource-group -g  The "resource group"
--resource-groups     Resources groups to filter on

You might also consider making the property name something like "--filter-groups" or something. Right now, --resource-group and --resource-groups would be easy to confuse.

cb.argument('start_date', options_list=['--start-date', '-s'], type=get_datetime_type(), help='Start date (YYYY-MM-DD in UTC) of time period of a budget.')
cb.argument('end_date', options_list=['--end-date', '-e'], type=get_datetime_type(), help='End date (YYYY-MM-DD in UTC) of time period of a budget.')
cb.argument('resource_groups', options_list='--resource-groups', nargs='+', help='Space-separated list of resource groups to filter on.')
cb.argument('resources', options_list='--resources', nargs='+', help='Space-separated list of resource instances to filter on.')
Copy link
Member

Choose a reason for hiding this comment

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

Options list not required.

cb.argument('end_date', options_list=['--end-date', '-e'], type=get_datetime_type(), help='End date (YYYY-MM-DD in UTC) of time period of a budget.')
cb.argument('resource_groups', options_list='--resource-groups', nargs='+', help='Space-separated list of resource groups to filter on.')
cb.argument('resources', options_list='--resources', nargs='+', help='Space-separated list of resource instances to filter on.')
cb.argument('meters', options_list='--meters', nargs='+', help='Space-separated list of meters to filter on. Required if category is usage.')
Copy link
Member

Choose a reason for hiding this comment

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

Options list not required. What are meters?

exception_handler=consumption_exception_handler, validator=validate_budget_parameters, client_factory=budget_mgmt_client_factory)

p.custom_command('delete', 'cli_consumption_delete_budget', transform=None,
exception_handler=consumption_exception_handler, client_factory=budget_mgmt_client_factory)
Copy link
Member

Choose a reason for hiding this comment

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

The default values of validator and transform are None, so you can (and should) omit those.

@bgsky
Copy link
Contributor Author

bgsky commented Apr 10, 2018

@derekbekoe @tjprescott Resolved comments from both of you. Please refer to the latest iteration and proceed.

@derekbekoe
Copy link
Member

@tjprescott Can you take a look and review also?

Copy link
Member

@tjprescott tjprescott left a comment

Choose a reason for hiding this comment

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

Overall looks much better. Still a few small issues.



def load_arguments(self, _):
with self.argument_context('consumption usage') as c:
c.argument('top', options_list=['--top', '-t'], type=int, help='Maximum number of items to return. Value range: 1-1000.')
c.argument('include_additional_properties', options_list=['--include-additional-properties', '-a'], action='store_true', help='Include additional properties in the usages.')
c.argument('include_meter_details', options_list=['--include-meter-details', '-m'], action='store_true', help='Include meter details in the usages.')
c.argument('start_date', options_list=['--start-date', '-s'], type=get_datetime_type(), help='Start date (YYYY-MM-DD in UTC). If specified, also requires --end-date.')
c.argument('end_date', options_list=['--end-date', '-e'], type=get_datetime_type(), help='End date (YYYY-MM-DD in UTC). If specified, also requires --start-date.')
c.argument('start_date', options_list=['--start-date', '-s'], type=datetime_type, help='Start date (YYYY-MM-DD in UTC). If specified, also requires --end-date.')
Copy link
Member

Choose a reason for hiding this comment

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

Consider using the get_datetime_type method from azure.cli.core.commands.parameters. They are methods because you have to parameterize, but the intention will be to standardize date handling using these configurable methods. Try it on one command and let me know whether it fits your scenario.


with self.argument_context('consumption budget') as cb:
cb.argument('budget_name', help='Name of a budget.')
cb.argument('category', arg_type=get_enum_type(['cost', 'usage']), help='Category of the budget can be cost or usage.')
Copy link
Member

Choose a reason for hiding this comment

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

Why are these enums not in your SDK?

cb.argument('time_grain', arg_type=get_enum_type(['monthly', 'quarterly', 'annually']), help='Time grain of the budget can be monthly, quarterly, or annually.')
cb.argument('start_date', options_list=['--start-date', '-s'], type=datetime_type, help='Start date (YYYY-MM-DD in UTC) of time period of a budget.')
cb.argument('end_date', options_list=['--end-date', '-e'], type=datetime_type, help='End date (YYYY-MM-DD in UTC) of time period of a budget.')
cb.argument('resource_groups', options_list='--resource-group-filter', nargs='+', help='Space-separated list of resource groups to filter on.')
Copy link
Member

Choose a reason for hiding this comment

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

This is fine, but you should still add arg_group='Filter' to these so they are grouped together in help.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

raise ValueError("Input '{}' not valid. Valid example: 2017-02-11T23:59:59Z".format(string))
return datetime_type
accepted_date_formats = ['%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%dT%H:%MZ', '%Y-%m-%dT%HZ', '%Y-%m-%d']
for form in accepted_date_formats:
Copy link
Member

Choose a reason for hiding this comment

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

Try the version and core. If you feel it doesn't support you scenarios, let me know so I can improve it.

raise CLIError("usage error: --category must be set to either cost or usage")
time_grain = namespace.time_grain.lower().strip()
if time_grain != 'annually' and time_grain != 'quarterly' and time_grain != 'monthly':
raise CLIError("usage error: --time_grain can be 'Annually', 'Quarterly', or 'Monthly'.")
Copy link
Member

Choose a reason for hiding this comment

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

These enums should not be validated in code at all. That's why you register them as enums. The CLI handles all of that. Validating the amount is fine though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed validation on category and time grain

@bgsky
Copy link
Contributor Author

bgsky commented Apr 24, 2018

@tjprescott get_datetime_type method got errors when running test cases. Will prefer to keep original datetime_type.

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.

4 participants