CiscoUcs/imcsdk

View on GitHub
docker/README.rst

Summary

Maintainability
Test Coverage
Containerized imcsdk for CIMC 3.0 using Docker
==============================================

The new CIMC version 3.0 needs:

-  TLS 1.2
-  Python2 version >= 2.7.9  or  Python3 version >= 3.2
-  OpenSSL version >= 1.0.1

https://github.com/CiscoUcs/imcsdk/blob/master/docs/imcsdk_ug.rst#getting-started

RHEL ships with Python 2.7.5 as the system Python version:

::

        # cat /etc/redhat-release
        Red Hat Enterprise Linux Server release 7.2 (Maipo)

        # python -V
        Python 2.7.5


CentOS also ships with Python 2.7.5 as the system Python version:

::

        # cat /etc/centos-release
        CentOS Linux release 7.3.1611 (Core)

        # python -V
        Python 2.7.5


Upgrading system Python in RHEL and CentOS from Python 2.7.5 to Python  >= 2.7.9 breaks a lot of packages like pip, yum, ansible, OpenStack packages, etc.

Upgrading system OpenSSL to version >= 1.0.1 may break VPN client and SSL.  Apple MacOS sierra ships with OpenSSL 0.9.8 and will not even allow the user to upgrade OpenSSL.

Production/staging/ops testbeds may not even allow us to upgrade system Python and system OpenSSL as it may break other packages/features.

Hence, the best approach is to containerize imcsdk using Docker with all the required dependencies/packages needed to programmatically interact with CIMC 3.0.

The container must have the following packages needed for CIMC 3.0:

-  ``Python 2.7.13`` (Python >= 2.7.9 is needed for CIMC 3.0)
-  ``pip`` with Python 2.7.13
-  ``OpenSSL 1.0.1``
-  Cisco's Python ``imcsdk`` library (https://github.com/CiscoUcs/imcsdk)
-  DMTF's Python ``RedFish`` library (``python-redfish-library`` in https://github.com/DMTF/python-redfish-library)
-  ``epel-release`` and latest ``Ansible`` (if the user wants to automate anything with CIMC 3.0)
-  Python ``requests`` library needed to interact with RedFish URIs ``/redfish/v1/*``

Download the ``Dockerfile`` in this directory to your host.

Install Docker on the RHEL/CentOS/MacOS host.  Ubuntu host has not been tested as the above container is a CentOS image currently.

**RHEL**   - https://docs.docker.com/engine/installation/linux/rhel/

**CentOS** - https://docs.docker.com/engine/installation/linux/centos/

**MacOS**  - https://docs.docker.com/docker-for-mac/install/

After installing and starting the Docker daemon on the host, go to the directory that contains the downloaded ``Dockerfile`` and build the ``centos-cimc-3.0`` container.  This takes 15-20 minutes.

::

        cd <path to downloaded Dockerfile>
        docker build --rm -t centos-cimc-3.0 .


Remove unwanted intermediate containers:

::

        docker images | grep '<none>' | awk '{print $3}' | xargs docker rmi -f


Check the built image of the container ``centos-cimc-3.0``:

::

        $ docker images
        REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
        centos-cimc-3.0                               latest              2e353ccfbc24        About an hour ago   1.08 GB
        centos                                        latest              a8493f5f50ff        3 weeks ago         192 MB


Run/start the built container:

::

        docker run --hostname cimc-3.0 --name cimc-3.0 -d centos-cimc-3.0


Check the started running container ``cimc-3.0``:

::

        $ docker ps -a
        CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
        9df66e090529        2e353ccfbc24        "sleep infinity"    2 minutes ago      Up 2 minutes                           cimc-3.0


Enter inside the container to start interacting with CIMC 3.0 from inside the container:

::

        $ docker exec -it cimc-3.0 /bin/bash
        [root@cimc-3 /]#


Once inside the container, make sure that all the packages needed for CIMC 3.0 are installed in the container.

::

        [root@cimc-3 /]# python2.7.13 -V
        Python 2.7.13

        [root@cimc-3 /]# openssl version
        OpenSSL 1.0.1e-fips 11 Feb 2013

        [root@cimc-3 /]# pip list | grep 'imcsdk\|redfish\|requests'
        imcsdk (0.9.3.1)
        redfish (1.0.0)
        requests (2.13.0)

        [root@cimc-3 /]# ansible --version
        ansible 2.3.0.0

        [root@cimc-3 /]# curl --version
        curl 7.29.0


Test if ``imcsdk`` APIs work with CIMC 3.0 inside the container.  Below, we use imcsdk to get the BIOS settings and the inventory of the UCS server with CIMC 3.0.

::

        [root@cimc-3 /]# python2.7.13
        Python 2.7.13 (default, Apr 19 2017, 20:05:12)
        [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
        Type "help", "copyright", "credits" or "license" for more information.
        >>>
        >>> import imcsdk
        >>> from imcsdk.imchandle import ImcHandle
        >>> from imcsdk.apis.server.inventory import inventory_get
        >>> imcsdk.__version__
        '0.9.3.1'

        >>> handle = ImcHandle("10.18.253.253", "admin", "SomePassword")
        >>> handle.login()
        True

        >>> handle.version._ImcVersion__version
        '3.0(1c)'

        >>> bios_settings = handle.query_dn('sys/rack-unit-1/bios/bios-settings')
        >>> bios_settings.__dict__
        {'status': None, 'dn': 'sys/rack-unit-1/bios/bios-settings', '_ManagedObject__xtra_props': {}, '_ManagedObject__parent_dn': 'sys/rack-unit-1/bios', '_dirty_mask': 0, '_handle': <imcsdk.imchandle.ImcHandle object at 0x7f799136ec90>, '_child': [], '_ManagedObject__xtra_props_dirty_mask': 1, '_ManagedObject__status': None, 'rn': 'bios-settings', '_ManagedObject__parent_mo': None, '_class_id': 'BiosSettings', 'child_action': None}

        >>> inventory_get(handle=handle)
        {'10.18.253.253': {'vic': [{'dn': 'sys/rack-unit-1/adaptor-MLOM', 'vendor': 'Cisco Systems Inc', 'model': 'UCSC-MLOM-CSC-02', 'pci_slot': 'MLOM', 'id': 'MLOM', 'serial': 'FCH20477D4X'}], 'vHBAs': [], 'tpm': [{'dn': 'sys/rack-unit-1/board/tpm', 'model': 'NA', 'vendor': 'NA', 'serial': 'NA', 'tpm_revision': 'NA'}

        >>> (Press CTRL+D to exit)
        [root@cimc-3 /]# exit


Test if Python's ``requests`` library works with **RedFish** URIs with CIMC 3.0 inside the container.

Below, we use Python's ``requests`` library with **RedFish** URIs (``/redfish/v1/*``) to get the model number, serial number and BIOS version of the UCS server with CIMC 3.0.

::

        [root@cimc-3 /]# python2.7.13
        Python 2.7.13 (default, Apr 19 2017, 20:05:12)
        [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
        Type "help", "copyright", "credits" or "license" for more information.
        >>>
        >>> import json
        >>> import requests
        >>> ro = requests.get("https://10.18.253.253/redfish/v1/Systems", verify=False, auth=("admin", "SomePassword"))
        >>> ro
        <Response [200]>

        >>> ro_json = ro.json()
        >>> uri = "https://10.18.253.253" + ro_json['Members'][0]['@odata.id']
        >>> ro = requests.get(uri, verify=False, auth=("admin", "SomePassword"))
        >>> ro
        <Response [200]>

        >>> ro_json = ro.json()
        >>> ro_json['Model']
        u'UCS C220 M4S'

        >>> ro_json['SerialNumber']
        u'FCH2047V0LJ'

        >>> ro_json['BiosVersion']
        u'C220M4.3.0.1b.0.1201161639'

        >>> (Press CTRL+D to exit)
        [root@cimc-3 /]# exit


Test if we can use ``curl`` to get objects from RedFish URIs inside the container.

::

        [root@cimc-3 /]# curl --insecure -u admin:SomePassword https://10.18.253.253/redfish/v1
        {
          "Chassis":{
            "@odata.id":"/redfish/v1/Chassis"
          },
          "@odata.id":"/redfish/v1/",
          "JSONSchemas":{
            "@odata.id":"/redfish/v1/JSONSchemas"
          },
          "RedfishVersion":"1.0.0",
          "EventService":{
            "@odata.id":"/redfish/v1/EventService"
          },
          "Systems":{
            "@odata.id":"/redfish/v1/Systems"
          },
          "Description":"Root Service",
          "Name":"Cisco RESTful Root Service",
          "Links":{
            "Sessions":{
              "@odata.id":"/redfish/v1/SessionService/Sessions"
            }
          },
          "TaskService":{
            "@odata.id":"/redfish/v1/TaskService"
          },
          "Managers":{
            "@odata.id":"/redfish/v1/Managers"
          },
          "@odata.type":"#ServiceRoot.1.0.0.ServiceRoot",
          "SessionService":{
            "@odata.id":"/redfish/v1/SessionService"
          },
          "@odata.context":"/redfish/v1/$metadata#ServiceRoot",
          "Id":"RootService",
          "AccountService":{
            "@odata.id":"/redfish/v1/AccountService"
          },
          "MessageRegistry":{
            "@odata.id":"/redfish/v1/MessageRegistry"
          }
        }

        [root@cimc-3 /]# curl --insecure -u admin:SomePassword https://10.18.253.253/redfish/v1/Systems
        {
          "Members":[{
              "@odata.id":"/redfish/v1/Systems/FCH2047V0LJ"
            }],
          "Description":"Collection of Computer Systems",
          "@odata.type":"#Cisco_ComputerSystemCollection",
          "@odata.id":"/redfish/v1/Systems",
          "Members@odata.count":1,
          "Name":"Computer System Collection",
          "@odata.context":"/redfish/v1/$metadata#Systems"
        }

        [root@cimc-3 /]# curl --insecure -u admin:SomePassword https://10.18.253.253/redfish/v1/Systems/FCH2047V0LJ
        {
          "SerialNumber":"FCH2047V0LJ",
          "Boot":{
            "BootSourceOverrideEnabled":"Disabled",
            "BootSourceOverrideTarget":"None"
          },
          "Id":"FCH2047V0LJ",
          "AssetTag":"Unknown",
          "PowerState":"Off",
          "SystemType":"Physical",
          "ProcessorSummary":{
            "Model":"Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz",
            "Count":2
          },
          "HostName":"C220-FCH2047V0LJ",
          "MemorySummary":{
            "TotalSystemMemoryGiB":256,
            "State":{
              "HealthRollup":"OK",
              "Health":"OK"
            }
          },
          "Processors":{
            "@odata.id":"/redfish/v1/Systems/FCH2047V0LJ/Processors"
          },
          "Description":"",
          "Links":{
            "CooledBy":["/redfish/v1/Chassis/1/Thermal"],
            "Chassis":["/redfish/v1/Chassis/1"],
            "PoweredBy":["/redfish/v1/Chassis/1/Power"],
            "ManagedBy":["/redfish/v1/Managers/CIMC"]
          },
          "SimpleStorage":{
            "@odata.id":"/redfish/v1/Systems/FCH2047V0LJ/SimpleStorage"
          },
          "UUID":"5236D4DC-04B3-4864-8A96-22C481844E0A",
          "Status":{
            "State":"Enabled",
            "Health":"Warning"
          },
          "BiosVersion":"C220M4.3.0.1b.0.1201161639",
          "Name":"UCS C220 M4S",
          "LogServices":{
            "@odata.id":"/redfish/v1/Systems/FCH2047V0LJ/LogServices"
          },
          "Actions":{
            "#System.Reset":{
              "Target":"/redfish/v1/Systems/FCH2047V0LJ/Actions/System.Reset",
              "ResetType@Redfish.AllowableValues":["On","ForceOff","GracefulShutdown","ForceRestart","Nmi"]
            }
          },
          "@odata.context":"/redfish/v1/$metadata#Systems/Members/$entity",
          "@odata.type":"#Cisco_ComputerSystem",
          "@odata.id":"/redfish/v1/Systems/FCH2047V0LJ",
          "Manufacturer":"Cisco Systems",
          "IndicatorLED":"Off",
          "Model":"UCS C220 M4S",
          "EthernetInterfaces":{
            "@odata.id":"/redfish/v1/Systems/FCH2047V0LJ/EthernetInterfaces"
          }
        }

        [root@cimc-3 /]# exit


Links about RedFish:

-  https://www.dmtf.org/standards/redfish
-  http://redfish.dmtf.org
-  RedFish API spec - http://redfish.dmtf.org/schemas/DSP0266_1.1.html
-  Redfish Schema Index - http://redfish.dmtf.org/redfish/schema_index

If the container ``cimc-3.0`` is not needed, stop and remove it:

::

        docker stop cimc-3.0 && docker rm cimc-3.0


If the image ``centos-cimc-3.0`` is not needed, remove it:

::

        docker rmi centos-cimc-3.0
        docker rmi centos


After the Docker image ``centos-cimc-3.0`` is built from the downloaded ``Dockerfile``, it can be tagged (``docker tag``), pushed to any registry (``docker push``), pulled from the registry (``docker pull``), run/started (``docker run``), and used to programmatically interact with CIMC 3.0.