Skip to content

Support multi-versioned mgmt SDK#2526

Merged
derekbekoe merged 4 commits intoAzure:api-profile-supportfrom
derekbekoe:mgmt-sdk-support
Mar 21, 2017
Merged

Support multi-versioned mgmt SDK#2526
derekbekoe merged 4 commits intoAzure:api-profile-supportfrom
derekbekoe:mgmt-sdk-support

Conversation

@derekbekoe
Copy link
Copy Markdown
Member

Implemented for azure-mgmt-storage.
Compute, Network, Resources to come in further PRs.

Addresses part of #2408

@derekbekoe
Copy link
Copy Markdown
Member Author

@lmazuel for changes to src/azure-cli-core/azure/cli/core/profiles/_shared.py

requirements.txt Outdated
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This will be removed before merging to master but needed currently as SDK not released.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This will be removed before merging to master but needed currently as SDK not released.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Some example API profiles as non have been published yet.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@lmazuel naming okay here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@derekbekoe so far so good :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Place the class member field in front of any methods.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@troydai done.

@codecov-io
Copy link
Copy Markdown

codecov-io commented Mar 16, 2017

Codecov Report

Merging #2526 into api-profile-support will increase coverage by <.01%.
The diff coverage is 75.83%.

@@                   Coverage Diff                   @@
##           api-profile-support    #2526      +/-   ##
=======================================================
+ Coverage                72.12%   72.13%   +<.01%     
=======================================================
  Files                      364      365       +1     
  Lines                    19829    19915      +86     
  Branches                  2926     2936      +10     
=======================================================
+ Hits                     14301    14365      +64     
- Misses                    4607     4626      +19     
- Partials                   921      924       +3
Impacted Files Coverage Δ
...cli-core/azure/cli/core/commands/client_factory.py 87.17% <100%> (+3.84%) ⬆️
...azure-cli-core/azure/cli/core/commands/__init__.py 80.18% <100%> (+0.49%) ⬆️
...storage/azure/cli/command_modules/storage/_help.py 100% <100%> (ø) ⬆️
...rage/azure/cli/command_modules/storage/_factory.py 85% <100%> (ø) ⬆️
...azure-cli-core/azure/cli/core/profiles/__init__.py 100% <100%> (ø) ⬆️
.../azure/cli/command_modules/storage/custom_nonce.py 54.16% <54.16%> (ø)
...e/azure/cli/command_modules/storage/_validators.py 53.71% <60%> (-0.02%) ⬇️
...torage/azure/cli/command_modules/storage/custom.py 86.23% <60%> (+0.21%) ⬆️
...ure-cli-core/azure/cli/core/commands/parameters.py 72.72% <66.66%> (-0.4%) ⬇️
...c/azure-cli-core/azure/cli/core/profiles/shared.py 72.97% <72.97%> (ø)
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bf1aa3a...c084119. Read the comment docs.

Copy link
Copy Markdown
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.

There are a number of major usability obstacles in this PR that we need to address before we start applying this wholesale to the CLI.

That being said, it's easy for me to backseat drive since you did all the hard work. Now we have a functional starting point on which to improve, so THANK YOU!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not just have a separate argument for resource_type with a default of None? client_type_or_resource_type is not a great name (at least shorten to client_or_resource_type?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why not just have a separate argument for resource_type with a default of None?

One argument is required so adding another argument resource_type=None would not work as client_type would still be required.

I've shortened the name to client_or_resource_type.

Does that work?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would recommend shortening this to "api_version", especially if it's going to be used all over the place (which I suspect it will)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm all for a shorter name. However, a function name better has a verb in it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

A lot of our other methods start with a verb so tempted to stick with the names as they are.

Also, a typical use-case of the method is api_version = get_api_version(resource_type). If I renamed the method, api_version = api_version(resource_type) would cause issues as the method name equals the variable name and api_version would be a very common variable name here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm fine with that, but we need to abstract out the API version as much as possible so we don't have "get_api_version(...)" all over the place.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here--recommend dropping the "get_"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, please add doc comments so we know what "model" and "checked" do. If model is left as None does it return ALL models?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Also, please add doc comments so we know what "model" and "checked" do. If model is left as None does it return ALL models?

Done.

I left the method name the same... see my comment above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead of a pass, couldn't we spell out the error message here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if you pass, this means you get the same stacktrace but typed as APIVersionException (you get the init from your father). If we have no info to add (like an api_version or something) this is ok for me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed by overriding Exception to define my own __str__ error message here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So all of the profiles are statically hard-coded in the CLI? What is the plan to ingest some kind of JSON document that contains this information? I would expect a profiles directory that contains a JSON document for each supported profile (except maybe latest).

If we are decoupled to the point that we can change this implementation without breaking our "get_api_version" and "get_versioned_models" interface then this is fine for now.

Copy link
Copy Markdown
Member

@lmazuel lmazuel Mar 16, 2017

Choose a reason for hiding this comment

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

I totally agree with you @tjprescott , as long as we decouple enough I get the hardcode for now.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

So all of the profiles are statically hard-coded in the CLI?

It would go in a shared package that's used by both the CLI and the Python SDK.

Yes it's decoupled. Everything in the shared.py file will eventually be moved out to a shared package to be used by both the CLI and SDK.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here again, the original is clearly superior to the new. Why not something like:

Encryption, EncryptionServices, EncryptionService = versioned_models(ResourceType.MGMT_STORAGE_STORAGE_ACCOUNTS, 'Encryption', 'EncryptionServices', 'EncryptionService')

This isn't great, but it's closer to the "easy" way and is easily implemented with minor changes. In reality, I would prefer it look like:

Encryption, EncryptionServices, EncryptionService = versioned_models(ResourceType.MGMT_STORAGE_STORAGE_ACCOUNTS)

So that it is, for all intents and purposes, functionally identical to the original while still handling the version stuff, but a solution does not immediately spring to mind for how to accomplish this--however, doing this would solve the ugly syntax of importing the enum for the choice list as well.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Gone with option 1 here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Option 1 is fine for now, but I think before we can really move forward with wholesale implementation, we will need something like option 2.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@tjprescott How would Option 2 be achieved technically?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What is this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The commands that only apply to certain API versions go in this file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this API call not exist in previous versions or is this an example only? This illustrates why I would prefer "api_version" over "get_api_version", but I would actually prefer something that looked like:

cli_generic_update_command(__name__, 'storage account update', 
   mgmt_path + 'get_properties', 
   mgmt_path + 'update', factory, 
   custom_function_op=custom_nonce_path + 'update_storage_account',
   min_api_version='foo', max_api_version='bar') 

Where min and max have defaults. The commands.py files are (in most modules) very straightforward and easy to read, and this preserves that. Adding conditionals makes them more difficult to maintain. Also, by putting this as part of the command, you can see the supported API versions in the command_table metadata. With if statements, you will not have that information.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Will look into this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would also suggest we could make this a follow up issue after the PR is merged.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'll leave this as is for now.
With the min_api_version='foo', max_api_version='bar' suggestion, it doesn't include which resource types the api versions correspond to. Currently, basic if statement logic gives the most flexibility. As I implement this for other modules, a pattern should appear then we can build more support in the CLI as described.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is another example of this syntax not being workable for practical purposes. Everyone is just going to put a string here...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This already looks like a maintenance headache. The differences here are not so profound as to duplicate the basic logic. Only the initialization of StorageAccountCreateParameters is different.

We should investigate having a way of defining and easily getting method signatures for different api versions. Something like:

storage_account_create_sig = {
  'profile1': (resource_group_name, account_name, location, account_type, tags=None),
  'profile2': (resource_group_name, account_name, location, sku, kind, encryption=None, access_tier=None, tags=None)
}

Then you have a way of getting an API specific signature for reflecting on parameters and so forth and you can call into an implementation method by treating those signatures as kwargs.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Will look into this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would suggest this will be a tricket wicket to solve. I'd be fine with merging the PR, creating issues for the rough spots, and then, once those issues are fixed, moving forward with the wholesale implementation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not a huge fan of the multiple return type here (Single Responsability Principle). I would prefer something like:

def get_versioned_models_module(api_profile, resource_type, checked=True):
    api_version = get_api_version(api_profile, resource_type)
    try:
        return get_client_class(resource_type).models(api_version=api_version)
........

def get_versioned_model(api_profile, resource_type, model, checked=True):
     try: 
        return getattr(get_versioned_models_module(api_profile, resource_type), model)
     excpet........

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I have removed the ability to get the full module. So now only get_versioned_model will exist.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The namespace is contradicting itself. If it is shared, it shouldn't be a private namespace.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The shared package will eventually be moved out of the CLI and into a shared package that the CLI and SDK will share.
Changed to remove the underscore for now though.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Add an example in the comments to improve readability.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm all for a shorter name. However, a function name better has a verb in it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Place the class member field in front of any methods.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I second what @tjprescott said. The pattern is way to confusing and unintuitive.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why lambda here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@troydai I could have done this inline as was the case before but since this method is slightly longer, I assigned the lambda to a variable.

I'm happy to move it to a normal method or back to inline. Thoughts?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

PEP8:
Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.

Yes: def f(x): return 2x
No: f = lambda x: 2
x

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, getattr has a default value parameter, so your lambda is the same as:

getattr(x, 'keys', x)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yes thanks

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

To be honest, this doesn't look good. What if there future API breaks? The control flow will look more and more complex. Should there be different custom command mapped to different version of API modules?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is the only line that's different and changes like this will not happen often.
Not sure if duplicating the whole method for this one change is the right way to go.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree with @derekbekoe. I would rather the API difference be called out explicitly rather than implies through try/except magic, but duplicating a method just duplicates your unfound bugs.

Copy link
Copy Markdown
Member

@lmazuel lmazuel Mar 20, 2017

Choose a reason for hiding this comment

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

I agree to do not duplicate. However, maybe you can try/except keys = [obj.key1, obj.key2] as well with a custom message like "unexpected format" or something. Otherwise here you will get an AtributeError on "key1" if something wrong in one year. Not critical however.

Copy link
Copy Markdown
Member Author

@derekbekoe derekbekoe left a comment

Choose a reason for hiding this comment

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

Started addressing some of the comments

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The shared package will eventually be moved out of the CLI and into a shared package that the CLI and SDK will share.
Changed to remove the underscore for now though.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Why not just have a separate argument for resource_type with a default of None?

One argument is required so adding another argument resource_type=None would not work as client_type would still be required.

I've shortened the name to client_or_resource_type.

Does that work?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

A lot of our other methods start with a verb so tempted to stick with the names as they are.

Also, a typical use-case of the method is api_version = get_api_version(resource_type). If I renamed the method, api_version = api_version(resource_type) would cause issues as the method name equals the variable name and api_version would be a very common variable name here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Also, please add doc comments so we know what "model" and "checked" do. If model is left as None does it return ALL models?

Done.

I left the method name the same... see my comment above.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The commands that only apply to certain API versions go in this file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Will look into this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Will look into this

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is the only line that's different and changes like this will not happen often.
Not sure if duplicating the whole method for this one change is the right way to go.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Will look into this.

@derekbekoe derekbekoe force-pushed the api-profile-support branch from 64da5b4 to bf1aa3a Compare March 17, 2017 22:40
Starting off with mgmt-storage.
Compute, Network, Resources to come in further PRs.
@derekbekoe
Copy link
Copy Markdown
Member Author

cc: @bganapa

@derekbekoe
Copy link
Copy Markdown
Member Author

@lmazuel @tjprescott @troydai Feedback addressed. Please take another look.

""" Patch the unversioned mgmt operations to include the appropriate API version for the
resource type in question.
e.g. Converts azure.mgmt.storage.operations.storage_accounts_operations to
azure.mgmt.storage.v_2016_12_01.operations.storage_accounts_operations
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

detail: typo in the doc it's v2016

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

thanks. fixed.

Copy link
Copy Markdown
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.

I'm fine with merging this and then opening bugs against the usability issues that can be solved in a focused way.

@derekbekoe
Copy link
Copy Markdown
Member Author

@troydai look good to you?

@derekbekoe derekbekoe merged this pull request into Azure:api-profile-support Mar 21, 2017
@derekbekoe derekbekoe deleted the mgmt-sdk-support branch March 21, 2017 16:36
derekbekoe added a commit that referenced this pull request Mar 21, 2017
* Support multi-versioned mgmt SDK

Starting off with mgmt-storage.
Compute, Network, Resources to come in further PRs.

* Address code review feedback

* fix typo

* Change transform keys result back to short lambda using getattr
derekbekoe added a commit to derekbekoe/azure-cli that referenced this pull request Mar 27, 2017
* Support multi-versioned mgmt SDK

Starting off with mgmt-storage.
Compute, Network, Resources to come in further PRs.

* Address code review feedback

* fix typo

* Change transform keys result back to short lambda using getattr
derekbekoe added a commit that referenced this pull request Apr 4, 2017
* Support multi-versioned mgmt SDK

Starting off with mgmt-storage.
Compute, Network, Resources to come in further PRs.

* Address code review feedback

* fix typo

* Change transform keys result back to short lambda using getattr
derekbekoe added a commit that referenced this pull request Apr 7, 2017
* Support multi-versioned mgmt SDK

Starting off with mgmt-storage.
Compute, Network, Resources to come in further PRs.

* Address code review feedback

* fix typo

* Change transform keys result back to short lambda using getattr
derekbekoe added a commit that referenced this pull request Apr 7, 2017
* Support multi-versioned mgmt SDK

Starting off with mgmt-storage.
Compute, Network, Resources to come in further PRs.

* Address code review feedback

* fix typo

* Change transform keys result back to short lambda using getattr
derekbekoe added a commit that referenced this pull request Apr 10, 2017
* Support multi-versioned mgmt SDK

Starting off with mgmt-storage.
Compute, Network, Resources to come in further PRs.

* Address code review feedback

* fix typo

* Change transform keys result back to short lambda using getattr
derekbekoe added a commit that referenced this pull request Apr 11, 2017
- Use published SDKs available on PyPI now
- Loading versioned models for network and resources, object model initialization changes for 2015-* profile (#2812)
- Custom ca certs - Setting Requests_ca_bundle environment variable (#2813)
- changes for 2015-* profile to work against azure stack  (#2794)
- Loading versioned Resources client and versioned models in VM
- Updating the supported api-versions for the 2015-example profile
- Fixing network, compute sdk load errors for 2015-* profiles (+5 squashed commit)
- Support multi-API versioned Storage dataplane SDK (#2796)
- Support multi-versioned mgmt SDK (#2526)
- Fix token "management" endpoint is being used in the place of "activeDirectoryResourceId" (#2410)
- Add profile switching params and profile listing command (#2398)
- Use ARM 'resource manager' endpoint if ASM 'management' endpoint not set
@derekbekoe derekbekoe mentioned this pull request Apr 11, 2017
3 tasks
derekbekoe added a commit that referenced this pull request Apr 13, 2017
- Use published SDKs available on PyPI now
- Loading versioned models for network and resources, object model initialization changes for 2015-* profile (#2812)
- Custom ca certs - Setting Requests_ca_bundle environment variable (#2813)
- changes for 2015-* profile to work against azure stack  (#2794)
- Loading versioned Resources client and versioned models in VM
- Updating the supported api-versions for the 2015-example profile
- Fixing network, compute sdk load errors for 2015-* profiles (+5 squashed commit)
- Support multi-API versioned Storage dataplane SDK (#2796)
- Support multi-versioned mgmt SDK (#2526)
- Fix token "management" endpoint is being used in the place of "activeDirectoryResourceId" (#2410)
- Add profile switching params and profile listing command (#2398)
- Use ARM 'resource manager' endpoint if ASM 'management' endpoint not set
derekbekoe added a commit that referenced this pull request Apr 14, 2017
* API Profile Support

- Use published SDKs available on PyPI now
- Loading versioned models for network and resources, object model initialization changes for 2015-* profile (#2812)
- Custom ca certs - Setting Requests_ca_bundle environment variable (#2813)
- changes for 2015-* profile to work against azure stack  (#2794)
- Loading versioned Resources client and versioned models in VM
- Updating the supported api-versions for the 2015-example profile
- Fixing network, compute sdk load errors for 2015-* profiles (+5 squashed commit)
- Support multi-API versioned Storage dataplane SDK (#2796)
- Support multi-versioned mgmt SDK (#2526)
- Fix token "management" endpoint is being used in the place of "activeDirectoryResourceId" (#2410)
- Add profile switching params and profile listing command (#2398)
- Use ARM 'resource manager' endpoint if ASM 'management' endpoint not set

* Address code review feedback

Fix pylint and pep8 (+7 squashed commits)
Squashed commits:
[f1d4d52] Refactor to use joint method
[f43785a] Use generic method to get versioned SDK attributes
[2100dd2] Add log debug if enum default not found
[5767f41] Add single_placement_group back in for vmss
[05ca8bc] Revert a test change. It has been fixed in master.
[cdf4211] Simplify str override method
[281c755] Clarify use of getattr

* Fix patching the operation versions

* Fix wrong import

* Rename shared to _shared

* Add message to cloud debug message

* Remove public method ‘get_versioned_sdk_path’ from azure.cli.core.profiles

* Remove unused import

* Use setattr

* Add API version comparisons

* Add method docs

* Fix failing test
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.

7 participants