Last active
September 21, 2019 18:17
-
-
Save JnyJny/1e02865d8f1b73d70f5756ad85a62652 to your computer and use it in GitHub Desktop.
Krugg3r's Project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from argparse import ArgumentParser | |
import json | |
import os | |
import requests | |
import sys | |
class ProjectNotFound(Exception): | |
"""Exception raised when a project cannot be located.""" | |
def __init__(self, project): | |
self.project = project | |
def __str__(self): | |
return f"Project not found: {self.project}" | |
class Project: | |
_url = "http://intranet.mycompany.com/v7/api/1.1/" | |
def __init__(self, api_url=None, login=None): | |
""" | |
:param str api_url: optional | |
:param str login: optional | |
""" | |
self.api = api_url or self._url | |
self.login = login or os.environ["USER"] | |
self.password = os.environ["MYPASSWORD"] | |
@property | |
def session(self): | |
"""A requests session. | |
""" | |
try: | |
return self._session | |
except AttributeError: | |
pass | |
self._session = requests.session() | |
return self._session | |
@property | |
def creds(self): | |
"""A dictionary of session credentials necessary to get | |
obtain a cookie. | |
""" | |
try: | |
return self._creds | |
except AttributeError: | |
pass | |
self._creds = { | |
"login": self.login, | |
"connectionType": "Classique", | |
"password": self.password, | |
} | |
return self._creds | |
@property | |
def cookie(self): | |
"""The session cookie as a string. | |
""" | |
try: | |
return self._cookie | |
except AttributeError: | |
pass | |
url = self.api_url + "Authentication.json/LogIn" | |
headers = { | |
"Authorization": "", | |
"ContentType": "application/json; charset=utf-8", | |
} | |
response = self.session.post(url, headers=headers, data=json.dumps(self.creds)) | |
if response.status_code != 200: | |
raise Exception(f"Failed to get cookie: {response}") | |
cookie_dict = response.cookies.get_dict() | |
self._cookie = "; ".join(f"{k}={v}" for k, v in cookie_dict.items()) | |
return self._cookie | |
@property | |
def headers(self): | |
"""A dictionary initially populated with the session cookie.""" | |
try: | |
return self._headers | |
except AttributeError: | |
pass | |
self._headers = {"Cookie": self.cookie} | |
return self._headers | |
def _json(self, endpoint): | |
"""Returns the dictionary of the JSON payload returned for the | |
requested endpoint. | |
:param str endpoint: | |
:return: dict | |
""" | |
url = self.apiurl + endpoint | |
response = requests.get(url, headers=self.headers) | |
return response.json() | |
def search(self, project): | |
"""Returns a dictionary of JSON data from the Project.json/Search | |
endpoint for 'project'. | |
:param [str|int] project: | |
:return: dict | |
""" | |
endpoint = "Project.json/Search?" | |
endpoint += "id_projet={project}" if project.isdigit() else "l_projet={name}" | |
return self._json(endpoint) | |
def project_id_by_name(self, name): | |
"""Returns an integer project identifier for the given project name. | |
:param str name: | |
:return: int | |
""" | |
return self.search(name)["id_projet"] | |
def project_name_by_id(self, identifier): | |
"""Returns a string project name for the given integer project | |
identifier. | |
:param int identifier: | |
:return: str | |
""" | |
return self.search(identifier)["l_projet"] | |
def equipments_client(self, project_id): | |
"""Returns a list of client equipments (??) | |
:param int project_id: | |
:return: list ?? | |
""" | |
return self._json(f"Project.json/{project_id}/Equipment/Client") | |
def equipments_os(self, lbnref): | |
"""Returns the string data for the endpoint: | |
Equipment.json/lbnref/OperatingSystem/View/OperatingSystemCatalog_Name | |
:param ??? lbnref: | |
:return: str | |
""" | |
data = self._json(f"Equipment.json/{lbnref!s}/OperatingSystem/View") | |
return data["OperatingSystemCatalog_Name"] | |
def print_report(client_equipments): | |
"""XXX missing docstring | |
""" | |
vm_count = 0 | |
for equipments in client_equipments: | |
try: | |
vm_name = equipments["Name"] | |
vm_os = project.equipments_os(equipments["Id"]) | |
except KeyError: | |
continue | |
try: | |
vm_inprod = f"IsInProduction = {equipments['IsInProduction']}" | |
except KeyError: | |
vm_inprod = "OS Name not available on idefix" | |
print(f"{vm_name} - {vm_os} - {vm_inprod}") | |
vm_count += 1 | |
print("Nombre de serveurs = {vm_count}") | |
if __name__ == "__main__": | |
parser = ArgumentParser() | |
parser.add_argument("project", help="Project name or identifier") | |
args = parser.parse_args() | |
project = Project() | |
try: | |
project_id = project.search(args.project)["id_projet"] | |
except ProjectNotFound as error: | |
print(error) | |
exit(-1) | |
except KeyboardInterrupt: | |
print("Search for {project} interrupted by user") | |
exit(0) | |
except Exception as error: | |
print(f"Encountered error during search: {error}") | |
exit(-1) | |
# You can make an argument both ways for print_report being a | |
# method in the Project class, but I like to seperate 'business | |
# logic' out of classes since it changes often. | |
print_report(project.equipments_client(project_id)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment