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

Initial commits for integration of HPE OneView resources with Ansible #26026

Merged
merged 19 commits into from Aug 3, 2017

Conversation

fgbulsoni
Copy link
Contributor

@fgbulsoni fgbulsoni commented Jun 22, 2017

SUMMARY

HPE OneView is an infrastructure automation engine built with software intelligence. It streamlines provisioning and lifecycle management across compute, storage and fabric and enables IT staff to control resources programmatically through a unified API.

It is heavily focused on the DevOps workflow and has many integrations already, including an ansible module not integrated into core.

This PR aims to add the OneView base class to be used for all OneView resources, together with the module for managing the HPE OneView FC Network resource: FcNetworkModule and its unit tests.

This resource has the present and absent states which will manage all of its aspects, including creating and updating the resources (using present) and removal of resources (using absent).

ISSUE TYPE
  • New Module Pull Request
COMPONENT NAME

FcNetworkModule

ANSIBLE VERSION
ansible 2.4.0 (devel de4a8b83df) last updated 2017/06/22 18:57:00 (GMT +000)
  config file = None
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/temp/ansible/lib/ansible
  executable location = /home/vagrant/temp/ansible/bin/ansible
  python version = 3.5.3 (default, Jun 22 2017, 17:14:20) [GCC 4.8.4]
ADDITIONAL INFORMATION

Example of usage:

    - name: Create a Fibre Channel Network
      oneview_fc_network:
        config: "{{ config }}"
        state: present
        validate_etag: false
        data:
          name: 'Test FC Network'
          fabricType: 'FabricAttach'
          linkStabilityTime: '30'
          autoLoginRedistribution: True
      delegate_to: localhost
      register: fc_network_1

    - name: Update the Fibre Channel Network changing the attribute autoLoginRedistribution to True
      oneview_fc_network:
        config: "{{ config }}"
        state: present
        data:
          name: 'Test FC Network'
          autoLoginRedistribution: True
          fabricType: 'FabricAttach'
          linkStabilityTime: '30'
      delegate_to: localhost

    - name: Delete the Fibre Channel Network
      oneview_fc_network:
        config: "{{ config }}"
        state: absent
        data: "{{ fc_network_1.ansible_facts.fc_network }}"
      delegate_to: localhost
      register: deleted

@mattclay
Copy link
Member

@fgbulsoni Have you considered mocking hpOneView instead of importing it? That way we're only testing the module, rather than its dependencies.

Here's another PR which is doing that: #25450

@ansibot
Copy link
Contributor

ansibot commented Jun 22, 2017

The test ansible-test compile --python 2.6 failed with the following error:

lib/ansible/module_utils/oneview.py:524:61: SyntaxError: existing_connection_map = {x[SPKeys.ID]: x.copy() for x in resource[SPKeys.CONNECTIONS]}

The test ansible-test sanity --test shebang failed with the following error:

Command "test/sanity/code-smell/shebang.sh" returned exit status 1.
>>> Standard Output
./lib/ansible/module_utils/oneview.py:#!/usr/bin/python
./lib/ansible/utils/module_docs_fragments/oneview.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/oneview_module_loader.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/hpe_test_utils.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/test_oneview_fc_network_facts.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/test_oneview_fc_network.py:#!/usr/bin/python
One or more file(s) listed above have an unexpected shebang.
See test/sanity/code-smell/shebang.sh for the list of acceptable values.

click here for bot help

@ansibot ansibot added affects_2.4 This issue/PR affects Ansible v2.4 c:module_utils/ 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. 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. test_pull_requests labels Jun 22, 2017
@fgbulsoni
Copy link
Contributor Author

Have you considered mocking hpOneView instead of importing it?

Hey @mattclay , thanks for the feedback! I'll look into the PR mentioned and see if I can do the same. :octocat:

@s-hertel s-hertel removed the needs_triage Needs a first human triage before being processed. label Jun 23, 2017
@ansibot
Copy link
Contributor

ansibot commented Jun 26, 2017

The test ansible-test sanity --test shebang failed with the following error:

Command "test/sanity/code-smell/shebang.sh" returned exit status 1.
>>> Standard Output
./lib/ansible/module_utils/oneview.py:#!/usr/bin/python
./lib/ansible/utils/module_docs_fragments/oneview.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/oneview_module_loader.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/hpe_test_utils.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/test_oneview_fc_network_facts.py:#!/usr/bin/python
./test/units/modules/cloud/hpe/test_oneview_fc_network.py:#!/usr/bin/python
One or more file(s) listed above have an unexpected shebang.
See test/sanity/code-smell/shebang.sh for the list of acceptable values.

click here for bot help

@ansibot
Copy link
Contributor

ansibot commented Jun 26, 2017

@robinro
Copy link
Contributor

robinro commented Jun 26, 2017

I don't see how this relates to me.

@fgbulsoni
Copy link
Contributor Author

fgbulsoni commented Jun 26, 2017

I don't see how this relates to me.

Hey @robinro , yeah, not sure what made the bot cc you. Thank you for replying though!

@mattclay , I've added mocks to the hpOneView SDK and now it seems we're hitting an error related to the collections method OrderedDict which we call inside the oneview module_utils file.

Our module does make use of the OrderedDict functionality, but I'm not sure about copying the entire method from collections and mocking it for it to work on Python 2.6, as it will be quite big and I don't feel this will add to the tests. I've also seen that OrderedDict is used by some Junos modules but it is not mocked for their tests, so I'm not entirely sure how to deal with this.

Would you have any suggestion on how to deal with this? Perhaps a way to skip the 2.6 tests since the module will not be compatible with that version?

@fgbulsoni fgbulsoni force-pushed the hpe-oneview/fc-network branch 2 times, most recently from bc7a3ef to 969f94d Compare June 28, 2017 14:13
@ansibot
Copy link
Contributor

ansibot commented Jun 28, 2017

click here for bot help

@fgbulsoni
Copy link
Contributor Author

fgbulsoni commented Jun 28, 2017

I've fixed the unit tests issues regarding OrderedDict and the unit tests for 2.6 should be passing now.

It seems that for some reason I can't pinpoint, the other tests are failing on this command pip install --disable-pip-version-check -c test/runner/requirements/constraints.txt -r test/runner/requirements/sanity.txt coverage junit-xml.

From the logs and running it locally, it appears to fail when trying to install yamllint with this output:

Collecting yamllint
/usr/local/lib/python2.6/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:318: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/security.html#snimissingwarning.
  SNIMissingWarning
/usr/local/lib/python2.6/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:122: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Using cached yamllint-1.8.0-py2.py3-none-any.whl
Collecting pathspec (from yamllint)
  Using cached pathspec-0.5.2.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-omI9Qg/pathspec/setup.py", line 6, in <module>
        from pathspec import __author__, __email__, __license__, __project__, __version__
      File "pathspec/__init__.py", line 33, in <module>
        from .pathspec import PathSpec
      File "pathspec/pathspec.py", line 9, in <module>
        from . import util
      File "pathspec/util.py", line 167
        return {normalize_file(path, separators=separators): path for path in files}
                                                                    ^
    SyntaxError: invalid syntax

I've not added yamllint nor am I sure why is it failing, this looks to me like code that was already in the repo. Any help/ideas here?

@mattclay
Copy link
Member

@fgbulsoni I'm working on a fix now.

@mattclay
Copy link
Member

@fgbulsoni The issue has been resolved. I've restarted CI for this PR.

@ansibot
Copy link
Contributor

ansibot commented Jun 28, 2017

The test ansible-test sanity --test pep8 failed with the following errors:

contrib/inventory/zabbix.py:27:71: W291 trailing whitespace
contrib/inventory/zabbix.py:107:1: E101 indentation contains mixed spaces and tabs
contrib/inventory/zabbix.py:107:1: W191 indentation contains tabs
contrib/inventory/zabbix.py:108:1: E101 indentation contains mixed spaces and tabs
contrib/inventory/zabbix.py:108:26: E201 whitespace after '{'
contrib/inventory/zabbix.py:108:48: E202 whitespace before '}'
contrib/inventory/zabbix.py:114:26: E221 multiple spaces before operator
contrib/inventory/zabbix.py:115:27: E221 multiple spaces before operator
contrib/inventory/zabbix.py:118:18: E221 multiple spaces before operator

click here for bot help

@mattclay
Copy link
Member

These failures are also unrelated. They've been fixed and I'll restart CI again.

@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 Jun 28, 2017
@fgbulsoni
Copy link
Contributor Author

These failures are also unrelated. They've been fixed and I'll restart CI again.

Many thanks for that @mattclay !

Is there anything else that needs to be addressed in this PR or may I wait for it to be merged?

Best regards,
Felipe.

@fgbulsoni
Copy link
Contributor Author

@abadger I believe I've made all of the requested changes.
Would you perhaps be able to review the PR again?

MSG_ALREADY_PRESENT = 'Resource is already present.'
MSG_ALREADY_ABSENT = 'Resource is already absent.'
HPE_ONEVIEW_SDK_REQUIRED = 'HPE OneView Python SDK is required for this module.'
FUTURE_PACKAGE_REQUIRED = 'The Future Python package is required for this module.'
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need this message anymore as the future package is no longer used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ops. True, removing.


from ansible.module_utils import six
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
Copy link
Contributor

Choose a reason for hiding this comment

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

style wise, the ansible imports go below the hpOneView imports.

import abc
import collections
import json
import logging
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need the logging import anymore



class OneViewModuleBase(object):
__metaclass__ = abc.ABCMeta
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh sorry, I should have mentioned, how to specify metaclasses changed between python2 and python3. So there's a helper in six so that you can do this acroos both versions.

from ansible.module_utils.six import with_metaclass
[...]
class OneViewModuleBase(with_metaclass(ABCMeta, object)):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it fine to do it as:

@six.add_metaclass(abc.ABCMeta)
class OneViewModuleBase(object):
    MSG_CREATED = 'Resource created successfully.'
    MSG_UPDATED = 'Resource updated successfully.'

?
Or would that not work? I've seen it used similarly at the crypto module.

else:
return self.resource_absent(resource)

def __present(self, resource):
Copy link
Contributor

Choose a reason for hiding this comment

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

There's still a few of these that are using double-underscore to mark private. We generally do that with single underscore instead.

- def __present(self,  resource):
+ def _present(self,  resource):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ops. Missed that, was a new method that I added and ended up not verifying the underscores. Fixing.

# If both values are null, empty or False it will be considered equal.
elif not resource1[key] and not resource2[key]:
continue
elif isinstance(resource1[key], dict):
Copy link
Contributor

Choose a reason for hiding this comment

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

Use collections.Mapping for dict

…meta class, removed extra underscores on methods and swapped isinstance validations of dict for collections.Mapping
import json
import os
import traceback
from copy import deepcopy
Copy link
Contributor

Choose a reason for hiding this comment

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

No longer need deepcopy


:return: dict: It must return a dictionary with the attributes for the module result,
such as ansible_facts, msg and changed.
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

indentation of the end of the string should match with the beginning (I see this in a few other places as well)

ansible_facts={fact_name: resource}
)

MSG_DIFF_AT_KEY = 'Difference found at key \'{0}\'. '
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be at the top with the other class attributes?

List with all the scope URIs to be added to the resource.
Returns:
A dictionary with the expected arguments for the AnsibleModule.exit_json
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

sphinx docstring formatting was missed for this one

merged_items[item_key] = items_map[item_key].copy()
merged_items[item_key].update(item)
else:
merged_items[item_key] = item.copy()
Copy link
Contributor

Choose a reason for hiding this comment

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

I see that we're still doing copies of the item here twice, once when we enter it into items map at the beginning of hte function and once when we enter it into merged_items here. Is that needed?

…methods from merge_lists and moved MSG that was in the middle of the code to top of the class
@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 Aug 2, 2017

return str(value)

def merge_list_by_key(self, original_list, updated_list, key, ignore_when_null=[]):
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like merge_list_by_key(), _standardize_value(), and _str_sorted() should be moved to be toplevel functions? (They don't make use of self).

# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
Copy link
Contributor

Choose a reason for hiding this comment

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

If you want to, you can change this license header to the short, one line version as shown here: https://github.com/ansible/ansible/blob/devel/docs/docsite/rst/dev_guide/developing_modules_documenting.rst#copyright

I've been trying to move modules to that since modules are copied over the network to the remote machine and so making them smaller can speed that up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, so, in that link I see this short licence:

#!/usr/bin/python
# Copyright (c) 2017 [New Contributor(s)]
# Copyright (c) 2015 [Original Contributor(s)]
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

I'm assuming the oneview_fc_network.py will then have:

#!/usr/bin/python
# Copyright (c) 2016-2017 Hewlett Packard Enterprise Development LP 
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 

Correct? Also, since that licence is GNU and module_utils must be BSD, is there a similar model for BSD?

…cense header in oneview_fc_network.py to short version
@abadger
Copy link
Contributor

abadger commented Aug 2, 2017 via email

@fgbulsoni
Copy link
Contributor Author

Your gplv3 question looks correct. There is none for bsd at this time so you can leave that one alone.

Awesome, thanks. Changes made then, waiting on CI to complete to see if I messed up anywhere.

@abadger abadger merged commit b060d0c into ansible:devel Aug 3, 2017
@abadger
Copy link
Contributor

abadger commented Aug 3, 2017

Merged to devel for 2.4.0. Thanks for the persistence and hard work!

@fgbulsoni
Copy link
Contributor Author

For history purposes, related issue: #28354

@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.4 This issue/PR affects Ansible v2.4 c:module_utils/ cloud community_review In order to be merged, this PR must follow the community review workflow. module This issue/PR relates to a module. 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. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants