Source code for wry.wsmanResource

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from . import wsmanData
import uuid
import requests
from . import WryDict
from time import sleep


[docs]class wsmanResource(object): ''' Class to represent a resource on a wsman compatible server ''' def __init__(self, target = None, is_ssl = False, username = None, password = None, resource = None, debug = False, showxml = False): ''' Set up this resource @param target: the hostname or IP address of the wsman service @param is_ssl: should we communicate using SSL? @param resource: the identifier of the resource containing the settings we are interested in @param username: the username to log in with @param password: the password to log in with @param debug: enable debugging output @param showxml: enable output of XML transactions ''' if is_ssl: scheme = 'https' else: scheme = 'http' port = wsmanData.AMT_PROTOCOL_PORT_MAP[scheme] self.target = scheme + "://" + target + ":" + str(port) + "/wsman" self.resourceId = resource self.resourceUri = wsmanData.RESOURCE_URIS[self.resourceId] self.resource_methods = wsmanData.RESOURCE_METHODS[resource] self.username = username self.password = password self.debug = debug self.showxml = showxml def etree_to_dict(self, t): d = {t.tag : map(self.etree_to_dict, t.iterchildren())} d.update(('@' + k, v) for k, v in t.attrib.items()) d['text'] = t.text return d
[docs] def request(self, doc = None, params = {}): ''' Send a request to the target and return the response ''' params['uuid'] = uuid.uuid4() if enumerate: doc = doc % params else: doc = doc % params if self.showxml: print("===== Request =====") print(doc) print("===================") for _ in range(wsmanData.CONNECT_RETRIES + 1): try: if self.debug: print("Connecting to %s" % (self.target,)) resp = requests.post( self.target, timeout = (0.1, 5), headers = {'content-type': 'application/soap+xml;charset=UTF-8'}, auth = requests.auth.HTTPDigestAuth(self.username, self.password), data = doc, allow_redirects = False, ) if self.showxml: print("===== Response =====") print(resp.content) print("====================") resp.raise_for_status() return WryDict.WryDict.from_xml(resp.content) except: if self.debug: print("Failed, retrying") sleep(wsmanData.CONNECT_DELAY)
[docs] def get(self, setting = '', **kwargs): ''' Send a get request and return the result @param setting: the setting to get the value of (None for all in this resources) ''' extraHeader = '' if 'headerSelector' in kwargs and 'headerSelectorType' in kwargs: extraHeader = '<wsman:SelectorSet><wsman:Selector Name="%(headerSelectorType)s">%(headerSelector)s</wsman:Selector></wsman:SelectorSet>' % kwargs params = { 'uri': self.target, 'actionUri': wsmanData.ACTIONS_URIS['get'], 'resourceUri': self.resourceUri, 'setting': setting, 'extraHeader': extraHeader, 'body': self.resource_methods['get'] } response = self.request(doc = wsmanData.WS_ENVELOPE, params = params) if len(setting) > 0: response = response[self.resourceId][setting] return response
[docs] def put(self, **kwargs): ''' Get the current values, fill in new values and put back @param **kwargs: zero or more settings to put back to the wsman server ''' current = self.get() for k, v in kwargs.items(): current[self.resourceId][k] = v params = { 'uri': self.target, 'actionUri': wsmanData.ACTIONS_URIS['put'], 'resourceUri': self.resourceUri, 'setting': '', 'extraHeader': '', 'body': current.to_xml } return self.request(doc = wsmanData.WS_ENVELOPE, params = params)
# def delete(self, **kwargs): # ''' # Delete an instance # ''' # params = { # 'uri': self.target, # 'actionUri': ACTIONS_URIS['delete'], # 'resourceUri': self.resourceUri, # 'setting': '', # 'extraHeader': '', # 'body': self.resource_methods['delete'] % kwargs # } # return self.request(doc = WS_ENVELOPE, params = params) # # def Create(self, **kwargs): # ''' # Create an instance # ''' # params = { # 'uri': self.target, # 'actionUri': ACTIONS_URIS['create'], # 'resourceUri': self.resourceUri, # 'setting': '', # 'extraHeader': '', # 'body': self.resource_methods['create'] % kwargs # } # return self.request(doc = WS_ENVELOPE, params = params)
[docs] def enumerate(self, **kwargs): ''' Return all instances of this Resource ''' params = { 'uri': self.target, 'actionUri': wsmanData.ACTIONS_URIS['enumerate'], 'resourceUri': self.resourceUri, 'setting': '', 'extraHeader': '', 'body': self.resource_methods['enumerate'] % kwargs } enum_response = self.request(doc = wsmanData.WS_ENUM_ENVELOPE, params = params) params['enumctx'] = enum_response['EnumerateResponse']['EnumerationContext'] params['actionUri'] = wsmanData.ACTIONS_URIS['pull'] output = WryDict.WryDict({self.resourceId:[]}) while params['enumctx']: data = self.request(doc = wsmanData.WS_PULL_ENVELOPE, params = params) if 'EnumerationContext' not in data['PullResponse']: params['enumctx'] = None output[self.resourceId].append(data['PullResponse']['Items'][self.resourceId]) return output
[docs] def invoke(self, method, **kwargs): ''' Call a method and return the result @param method: the method name to call ''' if method not in self.resource_methods: raise Exception("Method '%s' not defined" % method) extraHeader = '' if 'headerSelector' in kwargs and 'headerSelectorType' in kwargs: extraHeader = '<wsman:SelectorSet><wsman:Selector Name="%(headerSelectorType)s">%(headerSelector)s</wsman:Selector></wsman:SelectorSet>' % kwargs params = { 'uri': self.target, 'actionUri': self.resourceUri + "/" + method, 'resourceUri': self.resourceUri, 'setting': '', 'extraHeader': extraHeader, 'body': self.resource_methods[method] % kwargs } return self.request(doc = wsmanData.WS_ENVELOPE, params = params)