1#!/usr/bin/env python
2
3r"""
4See redfish_plus class prolog below for details.
5"""
6
7from redfish.rest.v1 import HttpClient
8import gen_print as gp
9
10
11def valid_http_status_code(status, valid_status_codes):
12    r"""
13    Raise exception if status is not found in the valid_status_codes list.
14
15    Description of argument(s):
16    status                          An HTTP status code (e.g. 200, 400, etc.).
17    valid_status_codes              A list of status codes that the caller
18                                    considers acceptable.  If this is a null
19                                    list, then any status code is considered
20                                    acceptable.  Note that for the convenience
21                                    of the caller, valid_status_codes may be
22                                    either a python list or a string which can
23                                    be evaluated to become a python list (e.g.
24                                    "[200]").
25    """
26
27    if type(valid_status_codes) is not list:
28        valid_status_codes = eval(valid_status_codes)
29    if len(valid_status_codes) == 0:
30        return
31    if status in valid_status_codes:
32        return
33
34    message = "The HTTP status code was not valid:\n"
35    message += gp.sprint_vars(status, valid_status_codes)
36    raise ValueError(message)
37
38
39class redfish_plus(HttpClient):
40    r"""
41    redfish_plus is a wrapper for redfish rest that provides the following
42    benefits vs. using redfish directly:
43
44    For rest_request functions (e.g. get, put, post, etc.):
45        - Function-call logging to stdout.
46        - Automatic valid_status_codes processing (i.e. an exception will be
47          raised if the rest response status code is not as expected.
48        - Easily used from robot programs.
49    """
50
51    ROBOT_LIBRARY_SCOPE = 'TEST SUITE'
52
53    def rest_request(self, func, *args, **kwargs):
54        r"""
55        Perform redfish rest request and return response.
56
57        This function provides the following additional functionality.
58        - The calling function's call line is logged to standard out (provided
59          that global variable "quiet" is not set).
60        - The caller may include a valid_status_codes argument.
61
62        Description of argument(s):
63        func                        A reference to the parent class function
64                                    which is to be called (e.g. get, put,
65                                    etc.).
66        args                        This is passed directly to the function
67                                    referenced by the func argument (see the
68                                    documentation for the corresponding
69                                    redfish HttpClient method for details).
70        kwargs                      This is passed directly to the function
71                                    referenced by the func argument (see the
72                                    documentation for the corresponding
73                                    redfish HttpClient method for details)
74                                    with the following exception:  If kwargs
75                                    contains a valid_status_codes key, it will
76                                    be removed from kwargs and processed by
77                                    this function.  This allows the caller to
78                                    indicate what rest status codes are
79                                    acceptable.  The default value is [200].
80                                    See the valid_http_status_code function
81                                    above for details.
82
83        Example uses:
84
85        From a python program:
86
87        response =
88        bmc_redfish.get("/redfish/v1/Managers/bmc/EthernetInterfaces", [200,
89        201])
90
91        If this call to the get method generates a response.status equal to
92        anything other than 200 or 201, an exception will be raised.
93
94        From a robot program:
95
96        BMC_Redfish.logout
97        ${response}=  BMC_Redfish.Get
98        /redfish/v1/Managers/bmc/EthernetInterfaces  valid_status_codes=[401]
99
100        As part of a robot test, the programmer has logged out to verify that
101        the get request will generate a status code of 401 (i.e.
102        "Unauthorized").
103        """
104        gp.qprint_executing(stack_frame_ix=3, style=gp.func_line_style_short)
105        valid_status_codes = kwargs.pop('valid_status_codes', [200])
106        response = func(*args, **kwargs)
107        valid_http_status_code(response.status, valid_status_codes)
108        return response
109
110    # Define rest function wrappers.
111    def get(self, *args, **kwargs):
112        return self.rest_request(super(redfish_plus, self).get, *args,
113                                 **kwargs)
114
115    def head(self, *args, **kwargs):
116        return self.rest_request(super(redfish_plus, self).head, *args,
117                                 **kwargs)
118
119    def post(self, *args, **kwargs):
120        return self.rest_request(super(redfish_plus, self).post, *args,
121                                 **kwargs)
122
123    def put(self, *args, **kwargs):
124        return self.rest_request(super(redfish_plus, self).put, *args,
125                                 **kwargs)
126
127    def patch(self, *args, **kwargs):
128        return self.rest_request(super(redfish_plus, self).patch, *args,
129                                 **kwargs)
130
131    def delete(self, *args, **kwargs):
132        return self.rest_request(super(redfish_plus, self).delete, *args,
133                                 **kwargs)
134
135    def __del__(self):
136        del self
137