diff --git a/inventory_provider/juniper.py b/inventory_provider/juniper.py index 705509d885918e04576c2ef48bcd4c3683b7a2b4..67f10a027da2c4bb8aa7aba2abad6012f6a66e49 100644 --- a/inventory_provider/juniper.py +++ b/inventory_provider/juniper.py @@ -84,6 +84,7 @@ UNIT_SCHEMA = """<?xml version="1.1" encoding="UTF-8" ?> <xs:complexType name="generic-sequence"> <xs:sequence> <xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + deviceFamily </xs:sequence> <xs:anyAttribute processContents="skip" /> </xs:complexType> @@ -102,7 +103,45 @@ UNIT_SCHEMA = """<?xml version="1.1" encoding="UTF-8" ?> </xs:schema> """ # noqa: E501 +JUNOSSPACE_DEVICES_SCHEMA = """<?xml version="1.1" encoding="UTF-8" ?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:complexType name="junosspace-device"> + <xs:sequence> + <xs:element name="deviceFamily" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="OSVersion" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="platform" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="serialNumber" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="connectionStatus" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="ipAddr" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="managedStatus" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="device-id" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="lsys-count" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="hosting-deviceId" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="authentication-status" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="connection-type" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="name" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="domain-id" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="domain-name" minOccurs="1" maxOccurs="1" type="xs:string" /> + <xs:element name="config-status" minOccurs="1" maxOccurs="1" type="xs:string" /> + </xs:sequence> + <xs:attribute name="href" type="xs:string" /> + <xs:attribute name="uri" type="xs:string" /> + <xs:attribute name="key" type="xs:string" /> + </xs:complexType> + + <xs:element name="devices"> + <xs:complexType> + <xs:sequence> + <xs:element name="device" minOccurs="0" maxOccurs="unbounded" type="junosspace-device" /> + </xs:sequence> + <xs:attribute name="uri" type="xs:string" /> + <xs:attribute name="size" type="xs:string" /> + </xs:complexType> + </xs:element> +</xs:schema> +""" # noqa: E501 def _rpc(hostname, ssh): dev = Device( @@ -229,16 +268,30 @@ def load_routers_from_junosspace(config): :param config: junosspace config element from app config :return: list of dictionaries, each element of which describes a router """ - api_url = config['api'] - if not api_url.endswith('/'): - api_url += '/' + juniper_logger = logging.getLogger(JUNIPER_LOGGER_NAME) + + request_url = config['api'] + if not request_url.endswith('/'): + request_url += '/' + request_url += 'device-management/devices' r = requests.get( - api_url + 'device-management/devices', + request_url, auth=HTTPBasicAuth(config['username'], config['password']), # TODO: seems server doesn't send the full chain # ... add the terena cert locally & reenable cert validateion verify=False ) # TODO: use a proper exception type - assert r.status_code == 200 - return etree.fromstring(r.text.encode('utf-8')) \ No newline at end of file + if r.status_code != 200: + juniper_logger.error("error response from %r" % request_url) + assert False # TODO: use proper exception type + + devices = etree.fromstring(r.text.encode('utf-8')) + schema_doc = etree.XML(JUNOSSPACE_DEVICES_SCHEMA.encode('utf-8')) + schema = etree.XMLSchema(schema_doc) + if not schema.validate(devices): + for e in schema.error_log: + juniper_logger.error("%d.%d: %s" % (e.line, e.column, e.message)) + assert False + + return True