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

[new module] Added Azure SQL Servers support - cloud/azure/azure_rm_sql_servers #33077

Merged
merged 17 commits into from Dec 13, 2017

Conversation

zikalino
Copy link
Contributor

SUMMARY

Adding support for Azure SQL Servers

ISSUE TYPE
  • New Module Pull Request
COMPONENT NAME

azure_rm_sql_servers

ANSIBLE VERSION
ansible 2.5.0 (devel 125c4b135d) last updated 2017/10/17 07:30:02 (GMT +000)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /ansible/lib/ansible
  executable location = /ansible/bin/ansible
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
ADDITIONAL INFORMATION

@ansibot
Copy link
Contributor

ansibot commented Nov 20, 2017

cc @brusMX
click here for bot help

@ansibot ansibot added affects_2.5 This issue/PR affects Ansible v2.5 azure cloud community_review In order to be merged, this PR must follow the community review workflow. module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. new_module This PR includes a new module. new_plugin This PR includes a new plugin. support:community This issue/PR relates to code supported by the Ansible community. test This PR relates to tests. labels Nov 20, 2017
@ansibot
Copy link
Contributor

ansibot commented Nov 20, 2017

The test ansible-test sanity --test pep8 [?] failed with the following error:

lib/ansible/modules/cloud/azure/azure_rm_sql_servers.py:48:161: E501 line too long (209 > 160 characters)

The test ansible-test sanity --test validate-modules [?] failed with the following errors:

lib/ansible/modules/cloud/azure/azure_rm_sql_servers.py:0:0: E305 DOCUMENTATION.options.identity.suboptions.type.description.0: expected str @ data['options']['identity']['suboptions']['type']['description'][0]. Got {"The identity type. Set this to 'SystemAssigned' in order to automatically create and assign an Azure Active Directory principal for the resource. Possible values include": 'SystemAssigned'}
lib/ansible/modules/cloud/azure/azure_rm_sql_servers.py:0:0: E312 No RETURN provided

click here for bot help

@ansibot ansibot added ci_verified Changes made in this PR are causing tests to fail. needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. and removed community_review In order to be merged, this PR must follow the community review workflow. labels Nov 20, 2017
@bcoca bcoca removed the needs_triage Needs a first human triage before being processed. label Nov 20, 2017
@ansibot ansibot removed the ci_verified Changes made in this PR are causing tests to fail. label Nov 22, 2017
@ansibot
Copy link
Contributor

ansibot commented Nov 22, 2017

@brusMX @devigned @haroldwongms @julienstroheker @jwhitbeck @lmazuel @obsoleted @ozboms @sozercan @tstringer @xscript @yuwzho

As a maintainer of a module in the same namespace this new module has been submitted to, your vote counts for shipits. Please review this module and add shipit if you would like to see it merged.

click here for bot help

@ansibot ansibot added community_review In order to be merged, this PR must follow the community review workflow. and removed needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. labels Nov 22, 2017
@ansibot ansibot added needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. and removed community_review In order to be merged, this PR must follow the community review workflow. labels Nov 22, 2017
@ansibot ansibot added community_review In order to be merged, this PR must follow the community review workflow. and removed needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. labels Nov 22, 2017
Copy link
Contributor

@jborean93 jborean93 left a comment

Choose a reason for hiding this comment

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

Have added some comments, some things we would need to do before merging is

  • Fix up the idempotency, right now it reports a change everytime it runs
  • Expand the tests to validate the module
  • Make the return values more Ansible like

Overall the module works for me and creates a SQL Server which is great. One question I do have more on the Azure side, is it planned to add support for more SQL types, e.g. MySQL and so or is that not supported in Azure or going to be in separate modules?

---
module: azure_rm_sql_server
version_added: "2.5"
short_description: Manage an Server.
Copy link
Contributor

Choose a reason for hiding this comment

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

short_description should not have a ., are you able to expand on this like, Manage a Azure SQL Server?

version_added: "2.5"
short_description: Manage an Server.
description:
- Create, update and delete an instance of Server.
Copy link
Contributor

Choose a reason for hiding this comment

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

SQL

location:
description:
- Resource location.
required: True
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice if this wasn't required and could be derived from the resource group specified.

tags:
description:
- Resource tags.
required: False
Copy link
Contributor

Choose a reason for hiding this comment

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

required: False is the default and is usually omitted.

suboptions:
type:
description:
- "The identity type. Set this to 'SystemAssigned' in order to automatically create and assign an Azure Active Directory principal for th
Copy link
Contributor

Choose a reason for hiding this comment

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

I would argue that SystemAssigned should be the default value if this is not set or can a SQL Server not have an identity? Is there a reason why this is a nested option under the type key? If not can identity just by the type value or do you see there being more options available to identity?

When quoting a value, you can enclose it with C(), e.g. 'SystemAssigned' should be C(SystemAssigned). You can also use I() when referring to option option names.

def exec_module(self, **kwargs):
"""Main module execution method"""

for key in list(self.module_arg_spec.keys()) + ['tags']:
Copy link
Contributor

Choose a reason for hiding this comment

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

Have a look at azure_rm_virtualmachine to see how to do this, you usually set the parameter as None in the init and these are populated in AzureRMModuleBase for you.

else:
self.log("Server instance already exists")
if self.state == 'absent':
self.delete_servers()
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't be run in check mode.

self.results['changed'] = True
self.log("Server instance deleted")
elif self.state == 'present':
self.log("Need to check if Server instance has to be deleted or may be updated")
Copy link
Contributor

Choose a reason for hiding this comment

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

You need some code to check if the server actually needs updating, right now the module is reporting a change when running it twice which is not idempotent.

self.results['state'] = self.create_update_servers()
self.results['changed'] = True
else:
self.results['state'] = response
Copy link
Contributor

Choose a reason for hiding this comment

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

We should look at changing the return values, see my note in the documentation portion.

@@ -0,0 +1,13 @@
- name: Create Servers
Copy link
Contributor

Choose a reason for hiding this comment

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

I know you were saying you were having issues trying to get this to run but we should also look at expanding these tests a lot more, usually we look at performing 3 tasks per action, e.g. 3 tasks for creating a server, 3 tasks for modifying a server and 3 tasks for removing a server. The 3 tasks per action should follow;

  • Run the task in check mode and check that the server wasn't actually created
  • Run the task normally and check that the server was created as expected
  • Run the task again (idempotent) and check that a change wasn't reported

@zikalino
Copy link
Contributor Author

ready_for_review

@zikalino
Copy link
Contributor Author

@jborean93 please check the module again, i think it's ready for merging.

Copy link
Contributor

@jborean93 jborean93 left a comment

Choose a reason for hiding this comment

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

I couldn't really test this as I came across the error

fatal: [127.0.0.1]: FAILED! => {"changed": false, "msg": "Error creating the SQL Server instance: Azure Error: InvalidRequestContent\nMessage: The request content was invalid and could not be deserialized: 'Required property 'type' not found in JSON. Path 'identity', line 1, position 44.'."}

A few things to note;

  • The tests need to be activated by adding the alias I mentioned in the comment (that should have picked up the error I recieved)
  • The tests need to be expanded to cover a check mode, normal and idempotent tests of the actions create, update, and delete scenarios
  • I'm not sure if the tags are actually supported, I was unable to test it but couldn't find anything that really seem to check and set them
  • The location is still required, it fails if you don't set it

description:
- The name of the server.
required: True
tags:
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm pretty sure you don't need the tags as you are extending the azure_tags documentation below.

def exec_module(self, **kwargs):
"""Main module execution method"""

for key in list(self.module_arg_spec.keys()) + ['tags']:
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the point of this whole block, AzureRMModuleBase should be setting self.x based on the module_arg_spec

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well, i have tried and it doesn't work as expected, so i have to leave it for now...

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, will try and debug and find out what is happening, it should just work.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok I see my mistake, most modules just have

for key in list(self.module_arg_spec.keys()) + ['tags']:
    setattr(self, key, kwargs[key])

Is there a reason why you have all these if statements as the above should be enough for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, these attributes are sticked into objects padded to Azure SDK, so treated in different way

self.mgmt_client = self.get_mgmt_svc_client(SqlManagementClient,
base_url=self._cloud_environment.endpoints.resource_manager)

try:
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for a try/except here as azure_rm_common handles a missing source group

except CloudError:
self.fail('resource group {0} not found'.format(self.resource_group))

if not ("location" in self.parameters):
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't seem to be working, I got The error was: msrest.exceptions.ValidationError: Parameter 'Server.location' can not be None in an error which means this musn't work. Try doing;

if self.location is None:
    self.location = resource_group.location

self.parameters = dict()
self.parameters['identity'] = dict()

self.results = dict(changed=False, state=dict())
Copy link
Contributor

Choose a reason for hiding this comment

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

state doesn't need to be there.

self.results['changed'] = True
else:
self.results['changed'] = old_response.__ne__(response)
self.results.update(response)
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of updating the results object here with the response and then removing the unneeded ones below, just set the results you want manually.

self.log("Creation / Update done")
elif self.to_do == Actions.Delete:
self.log("SQL Server instance deleted")
self.delete_sqlserver()
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to not run when in check mode

self.results['changed'] = True
else:
self.log("SQL Server instance unchanged")
self.results['state'] = old_response
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't be returned, it should be the same values that you set in add or update.

@@ -0,0 +1,2 @@
cloud/azure
destructive
Copy link
Contributor

Choose a reason for hiding this comment

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

You will need to add posix/ci/cloud/group2/azure to this list so the tests actually run in CI

@ansibot ansibot added needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. and removed community_review In order to be merged, this PR must follow the community review workflow. labels Dec 12, 2017
@zikalino
Copy link
Contributor Author

@jborean93 I have made all necessary updates, seems like test can't run as Microsoft.Sql namespace has to be added.

Error creating the SQL Server instance: Azure Error: MissingSubscriptionRegistration\nMessage: The subscription is not registered to use namespace 'Microsoft.Sql'. See https://aka.ms/rps-not-found for how to register subscriptions.\nException Details:\n\tError Code: MissingSubscriptionRegistration\n\tMessage: The subscription is not registered to use namespace 'Microsoft.Sql'. See https://aka.ms/rps-not-found for how to register subscriptions.\n\tTarget: Microsoft.Sql

@jborean93
Copy link
Contributor

jborean93 commented Dec 12, 2017

Looks like the tests are failing because we aren't authorised in CI, will see if @mattclay can help.

Edit: just saw your post :)

@jborean93
Copy link
Contributor

jborean93 commented Dec 12, 2017

@zikalino once we get the tests running we need to look at expanding the tests, there is at least 1 issue I can find that the tests should have picked up if we had some more tests. Let me know if you are confused as to what I am asking for, I'm happy to discuss it further over IRC as it would be good to get this merged today so you can update your other PR's with the changes you made here.

@zikalino
Copy link
Contributor Author

@jborean do you mean taking location from resource group? this could be difficult. some resources can't be created in particular location (I believe i couldn't create SQL server in the same location as the one where default rg is created).

@jborean93
Copy link
Contributor

@zikalino, for the location part I see the benefit in being able to set the location independently to override the resource group but most modules seem to have it as an optional value and if not set explicitly it is derived from the resource group location.

What I am talking about is expanding the tests from just the create, update, delete tasks to test each scenario under check mode, normal and an idempotent task. In the end it would look similar to

- name: create sql server (check)
  azure_rm_sqlserver:
    ...
  register: create_server_check

- name: check if server exists (check)
  ... ? use a facts module if possible
  register: create_server_result_check

- name: assert create sql server results (check)
  assert:
    that:
    - create_server_check is changed
    - create_server_check.exists == False

- name: create sql server
  azure_rm_sqlserver:
    ...
  register: create_server

- name: check if server exists
  ... ? use a facts module if possible
  register: create_server_result

- name: assert create sql server results
  assert:
    that:
    - create_server is changed
    - create_server.exists == True

- name: create sql server (idempotent)
  azure_rm_sqlserver:
    ...
  register: create_server_again

- name: assert create sql server results (idempotent)
  assert:
    that:
    - not create_server_again is changed

This would be repeated again for updating a SQL server and then finally again for removing a SQL server.

@jborean93
Copy link
Contributor

@zikalino, the Microsoft.SQL resource has been registered and the tests are now running.

@zikalino
Copy link
Contributor Author

@jborean93 seems now tests are passing. should i still add more tests to this pr? or is it ok to merge, and i could expand tests when adding facts module?

@jborean93
Copy link
Contributor

jborean93 commented Dec 12, 2017

I think we should still continue to add the extra tests just without that second step of checking the results with a fact module for now (should still come back and expand once a facts module is in). We can still do some assertions on the results of just the task itself.

Do you know how to run tests locally?

@zikalino
Copy link
Contributor Author

@jborean93 I have more tests for check_mode and also delete unexisting sql server test (which i moved to front, as delete after delete seems a bit unstable -- second delete may get invalid information that resource still exists)

@jborean93
Copy link
Contributor

Looks better, we still need a test for each action again to ensure that no changes are recorded (idempotent).

@zikalino
Copy link
Contributor Author

@jborean93 how about now? added 2 more tests

Copy link
Contributor

@jborean93 jborean93 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, left some comments on some tests, only thing remaining is to delete the instance again right at the end for idempotency checks

- output.changed
- output.state == 'Ready'

- name: Create again instance of SQL Server -- check mode
Copy link
Contributor

@jborean93 jborean93 Dec 13, 2017

Choose a reason for hiding this comment

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

Delete this one, you only need to run the check mode test for a scenario once

random_postfix: "{{ 1000 | random }}"
run_once: yes

- name: Delete unexisting instance of SQL Server -- check mode
Copy link
Contributor

Choose a reason for hiding this comment

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

Take away this test

that:
- output.changed == false

- name: Delete unexisting instance of SQL Server
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't need this test as you should be starting with a random resource group so no SQL server would exist anyway

@zikalino
Copy link
Contributor Author

shipit

@jborean93 jborean93 merged commit eb5ffa0 into ansible:devel Dec 13, 2017
@jborean93
Copy link
Contributor

Awesome @zikalino, are you able to raise a PR to add this module to the changelog for 2.5 https://github.com/ansible/ansible/blob/devel/CHANGELOG.md. We try to keep things in alphabetical order in each section.

@zikalino zikalino deleted the module-azure-rm-sql-servers branch December 13, 2017 04:31
@ansible ansible locked and limited conversation to collaborators Apr 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.5 This issue/PR affects Ansible v2.5 azure cloud module This issue/PR relates to a module. needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. new_module This PR includes a new module. new_plugin This PR includes a new plugin. support:community This issue/PR relates to code supported by the Ansible community. test This PR relates to tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants