class UserBundleTests(unittest.TestCase) : def setUp(self): self.con = Connection('http://localhost:8081', 'root', 'root') def test_01_createBundle(self): user_bundle = UserBundle() user_bundle.name = "TestUserBundle" user_bundle.users = [self.con.getUser("alexey.pegov")] user_bundle.groups = [self.con.getGroup("scala-developers"), self.con.getGroup("jira-users")] response = self.con.createBundle(user_bundle) self.assertTrue(response.find( "http://unit-258.labs.intellij.net:8080/charisma/rest/admin/customfield/userBundle/" + user_bundle.name) != -1) def test_02_getBundle(self): user_bundle = self.con.getBundle("user", "TestUserBundle") self.assertEquals(user_bundle.name, "TestUserBundle") user_names = [u.login for u in user_bundle.users] group_names = [u.name for u in user_bundle.groups] self.assertTrue(len(user_names) == 1) self.assertTrue(len(group_names) == 2) self.assertTrue("alexey.pegov" in user_names) self.assertTrue("scala-developers" in group_names) self.assertTrue("jira-users" in group_names) def test_03_getAllBundles(self): bundles = self.con.getAllBundles("user") names = [bundle.name for bundle in bundles] self.assertTrue(len(names) == 3) for name in names : self.assertTrue(name in ["HBR-Assignee", "SP-Assignee", "TestUserBundle"]) def test_04_renameBundle(self): user_bundle = self.con.getBundle("user", "TestUserBundle") self.con.renameBundle(user_bundle, "TestUserBundleNew") self.assertRaises(Exception, self.con.getBundle, "enum", "TestUserBundle") self.con.getBundle("user", "TestUserBundleNew") def test_05_addDeleteValue(self): user_bundle = self.con.getBundle("user", "TestUserBundleNew") new_user = self.con.getUser("alexander.doroshko") self.con.addValueToBundle(user_bundle, new_user) user_bundle = self.con.getBundle("user", "TestUserBundleNew") self.assertEquals(len(user_bundle.users), 2) user_names = [u.login for u in user_bundle.users] self.assertTrue("alexander.doroshko" in user_names) self.assertTrue("alexey.pegov" in user_names) self.con.removeValueFromBundle(user_bundle, new_user) user_names = [u.login for u in self.con.getBundle("user", "TestUserBundleNew").users] self.assertFalse("alexander.doroshko" in user_names) def test_06_deleteBundle(self): user_bundle = self.con.getBundle("user", "TestUserBundleNew") self.con.deleteBundle(user_bundle) self.assertRaises(Exception, self.con.getBundle, "user", "TestEnumBundleNew")
class UserBundleTests(unittest.TestCase) : def setUp(self): self.con = Connection('http://localhost:8081', 'root', 'root') def test_01_createBundle(self): user_bundle = UserBundle() user_bundle.name = "TestUserBundle" user_bundle.users = [self.con.getUser("alexey.pegov")] user_bundle.groups = [self.con.getGroup("scala-developers"), self.con.getGroup("jira-users")] response = self.con.createBundle(user_bundle) self.assertTrue(response.find( "http://unit-258.labs.intellij.net:8080/charisma/rest/admin/customfield/userBundle/" + user_bundle.name) != -1) def test_02_getBundle(self): user_bundle = self.con.getBundle("user", "TestUserBundle") self.assertEquals(user_bundle.name, "TestUserBundle") user_names = [u.login for u in user_bundle.users] group_names = [u.name for u in user_bundle.groups] self.assertTrue(len(user_names) == 1) self.assertTrue(len(group_names) == 2) self.assertTrue("alexey.pegov" in user_names) self.assertTrue("scala-developers" in group_names) self.assertTrue("jira-users" in group_names) def test_03_getAllBundles(self): bundles = self.con.getAllBundles("user") names = [bundle.name for bundle in bundles] self.assertTrue(len(names) == 3) for name in names : self.assertTrue(name in ["HBR-Assignee", "SP-Assignee", "TestUserBundle"]) def test_04_renameBundle(self): user_bundle = self.con.getBundle("user", "TestUserBundle") self.con.renameBundle(user_bundle, "TestUserBundleNew") self.assertRaises(Exception, self.con.getBundle, "enum", "TestUserBundle") self.con.getBundle("user", "TestUserBundleNew") def test_05_addDeleteValue(self): user_bundle = self.con.getBundle("user", "TestUserBundleNew") new_user = self.con.getUser("alexander.doroshko") self.con.addValueToBundle(user_bundle, new_user) user_bundle = self.con.getBundle("user", "TestUserBundleNew") self.assertEquals(len(user_bundle.users), 2) user_names = [u.login for u in user_bundle.users] self.assertTrue("alexander.doroshko" in user_names) self.assertTrue("alexey.pegov" in user_names) self.con.removeValueFromBundle(user_bundle, new_user) user_names = [u.login for u in self.con.getBundle("user", "TestUserBundleNew").users] self.assertFalse("alexander.doroshko" in user_names) def test_06_deleteBundle(self): user_bundle = self.con.getBundle("user", "TestUserBundleNew") self.con.deleteBundle(user_bundle) self.assertRaises(Exception, self.con.getBundle, "user", "TestEnumBundleNew")
class EnumBundleTests(unittest.TestCase): def setUp(self): self.con = Connection('http://localhost:8081', 'root', 'root') def test_01_createBundle(self): enum_bundle = EnumBundle() enum_bundle.name = "TestEnumBundle" enum_bundle.values = [] value_names = ["first", "second", "third"] for vn in value_names: element = EnumField() element.name = vn element.description = vn + " description" enum_bundle.values.append(element) response = self.con.createBundle(enum_bundle) self.assertTrue( response.find( "http://unit-258.labs.intellij.net:8080/charisma/rest/admin/customfield/bundle/" + enum_bundle.name) != -1) def test_02_getBundle(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundle") self.assertEquals(enum_bundle.name, "TestEnumBundle") values = dict({}) for elem in enum_bundle.values: values[elem.name] = elem.description self.assertTrue(len(values.keys()) == 3) for name in ["first", "second", "third"]: self.assertEquals(values[name], name + " description") def test_03_getAllBundles(self): bundles = self.con.getAllBundles("enum") names = [bundle.name for bundle in bundles] self.assertTrue(len(names) == 4) for name in names: self.assertTrue(name in [ "DefaultPriorities", "DefaultTypes", "enum", "TestEnumBundle" ]) def test_04_renameBundle(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundle") self.con.renameBundle(enum_bundle, "TestEnumBundleNew") self.assertRaises(Exception, self.con.getBundle, "enum", "TestEnumBundle") # if there is no such bundle exception will be thrown self.con.getBundle("enum", "TestEnumBundleNew") def test_05_addDeleteValue(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") value = EnumField() value.name = "Added" value.description = "description" self.con.addValueToBundle(enum_bundle, value) enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") self.assertEquals(len(enum_bundle.values), 4) new_value = "" for v in enum_bundle.values: if v.name == "Added": new_value = v self.assertEquals(new_value.description, "description") self.con.removeValueFromBundle(enum_bundle, new_value) enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") self.assertFalse("Added" in [elem.name for elem in enum_bundle.values]) def test_06_deleteBundle(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") self.con.deleteBundle(enum_bundle) self.assertRaises(Exception, self.con.getBundle, "enum", "TestEnumBundleNew")
class EnumBundleTests(unittest.TestCase) : def setUp(self): self.con = Connection('http://localhost:8081', 'root', 'root') def test_01_createBundle(self): enum_bundle = EnumBundle() enum_bundle.name = "TestEnumBundle" enum_bundle.values = [] value_names = ["first", "second", "third"] for vn in value_names : element = EnumField() element.name = vn element.description = vn + " description" enum_bundle.values.append(element) response = self.con.createBundle(enum_bundle) self.assertTrue(response.find("http://unit-258.labs.intellij.net:8080/charisma/rest/admin/customfield/bundle/" + enum_bundle.name) != -1) def test_02_getBundle(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundle") self.assertEquals(enum_bundle.name, "TestEnumBundle") values = dict({}) for elem in enum_bundle.values : values[elem.name] = elem.description self.assertTrue(len(values.keys()) == 3) for name in ["first", "second", "third"] : self.assertEquals(values[name], name + " description") def test_03_getAllBundles(self): bundles = self.con.getAllBundles("enum") names = [bundle.name for bundle in bundles] self.assertTrue(len(names) == 4) for name in names : self.assertTrue(name in ["DefaultPriorities", "DefaultTypes", "enum", "TestEnumBundle"]) def test_04_renameBundle(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundle") self.con.renameBundle(enum_bundle, "TestEnumBundleNew") self.assertRaises(Exception, self.con.getBundle, "enum", "TestEnumBundle") # if there is no such bundle exception will be thrown self.con.getBundle("enum", "TestEnumBundleNew") def test_05_addDeleteValue(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") value = EnumField() value.name = "Added" value.description = "description" self.con.addValueToBundle(enum_bundle, value) enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") self.assertEquals(len(enum_bundle.values), 4) new_value = "" for v in enum_bundle.values : if v.name == "Added" : new_value = v self.assertEquals(new_value.description, "description") self.con.removeValueFromBundle(enum_bundle, new_value) enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") self.assertFalse("Added" in [elem.name for elem in enum_bundle.values]) def test_06_deleteBundle(self): enum_bundle = self.con.getBundle("enum", "TestEnumBundleNew") self.con.deleteBundle(enum_bundle) self.assertRaises(Exception, self.con.getBundle, "enum", "TestEnumBundleNew")
def Main(sendTo, subject, yamlMessage): """ Workflow Zabbix-YouTrack :param sendTo: URL to Youtrack (ex. https://youtrack.example.com) :param subject: subject from Zabbix Action :param yamlMessage: message from Zabbix Action :return: """ # ----- Use below example yamlMessage to debug ----- # yamlMessage = """Name: 'Test Zabbix-YT workflow, ignore it' # Text: 'Agent ping (server:agent.ping()): DOWN (1) ' # Hostname: 'server.exmpale.ru' # Status: "OK" # Severity: "High" # EventID: "96976" # TriggerID: "123456789012" """ messages = yaml.load(yamlMessage) # ----- START Issue parameters ----- # Correspondence between the YouTrackPriority and ZabbixSeverity # Critical >= High # Normal < High ytPriority = 'Normal' if messages['Severity'] == 'Disaster' or messages['Severity'] == 'High': ytPriority = 'Critical' ytName = "{} ZabbixTriggerID::{}".format(messages['Name'], messages['TriggerID']) # ----- END Issue parameters ----- # ----- START Youtrack Issue description ----- # Search link to other issue searchString = "Hostname: '{}'".format(messages['Hostname']) linkToHostIssue = "{youtrack}/issues/{projectname}?q={query}".format( youtrack=sendTo, projectname=YT_PROJECT_NAME, query=urllib.parse.quote(searchString, safe='') ) issueDescription = """ {ytName} ----- {yamlMessage} ----- - [https://zabbix.example.com/zabbix.php?action=dashboard.view Zabbix Dashboard] - Show [{linkToHostIssue} all issue for *this host*] """.format( ytName=ytName, yamlMessage=yamlMessage, linkToHostIssue=linkToHostIssue, ) # ----- END Youtrack Issue description ----- # ----- START Youtrack current week ----- # Create connect to Youtrack API connection = Connection(sendTo, YT_USER, YT_PASSWORD) # Get current week in YT format (Sprint planned) version = connection.getAllBundles('version') for fixVersion in version[0].values: if fixVersion['archived'] == False and fixVersion['released'] == False: fixVersionWeek = fixVersion['name'] break # ----- END Youtrack current week ----- # ----- START Youtrack get or create issue ----- # Get issue if exist # Search for TriggerID createNewIssue = False logger.debug("Get issue with text '{}'".format(messages['TriggerID'])) issue = connection.getIssues(YT_PROJECT_NAME, "ZabbixTriggerID::{}".format(messages['TriggerID']), 0, 1) if len(issue) == 0: createNewIssue = True else: # if issue contains TriggerID in summary, then it's good issue # else create new issue, this is bad issue, not from Zabbix if "ZabbixTriggerID::{}".format(messages['TriggerID']) in issue[0]['summary']: issueId = issue[0]['id'] issue = connection.getIssue(issueId) else: createNewIssue = True # Create new issue if createNewIssue: logger.debug("Create new issue because it is not exist") issue = connection.createIssue(YT_PROJECT_NAME, 'Unassigned', ytName, issueDescription, priority=ytPriority, subsystem=YT_SUBSYSTEM, type=YT_TYPE, ) time.sleep(3) # Parse ID for new issue result = re.search(r'(CM-\d*)', issue[0]['location']) issueId = result.group(0) issue = connection.getIssue(issueId) logger.debug("Issue have id={}".format(issueId)) # Set issue service ExecAndLog(connection, issueId, "Service {}".format(YT_SERVICE)) # Update priority ExecAndLog(connection, issueId, "Priority {}".format(ytPriority)) # ----- END Youtrack get or create issue ----- # ----- START PROBLEM block ------ if messages['Status'] == "PROBLEM": # Issue exist and NOT Hold on, Unnassigned and Estimated time set if issue['State'] != 'Hold on': # Estimated time ExecAndLog(connection, issueId, "Estimated time {}".format(YT_TIME)) # Update fix version ExecAndLog(connection=connection, issueId=issueId, command="Sprint planned {}".format(fixVersionWeek)) # Reopen if Fixed or Verified or Canceled if issue['State'] == 'Fixed' or issue['State'] == 'Verified' or issue['State'] == 'Canceled': # Reopen Issue ExecAndLog(connection, issueId, "State reopen") # Assignee issue ExecAndLog(connection, issueId, command="Assignee Unassigned") # Update summary and description for issue logger.debug("Run command in {issueId}: {command}".format(issueId=issueId, command="""Update summary and description with connection.updateIssue method""" )) connection.updateIssue(issueId=issueId, summary=ytName, description=issueDescription) # Add comment logger.debug("Run command in {issueId}: {command}".format(issueId=issueId, command="""Now is PROBLEM {}""".format( messages['Text']) )) connection.executeCommand(issueId=issueId, command="", comment=YT_COMMENT.format( status=messages['Status'], text=messages['Text']) ) # Send ID to Zabbix: logger.debug("ZABBIX-API: Send Youtrack ID to {}".format(messages['EventID'])) Zbx.event.acknowledge(eventids=messages['EventID'], message="Create Youtrack task") Zbx.event.acknowledge(eventids=messages['EventID'], message="https://youtrack.example.com/issue/{}".format(issueId)) # ----- End PROBLEM block ------ # ----- Start OK block ----- if messages['Status'] == "OK": if issue['State'] == 'Hold on' or issue['State'] == 'Registered': # Cancel if not in work ExecAndLog(connection, issueId, command="State Cancel") # Assignee issue ExecAndLog(connection, issueId, command="Assignee {}".format(YT_ASSIGNEE)) if issue['State'] == 'Fixed': # Verify if Fixed ExecAndLog(connection, issueId, command="State verify") logger.debug("Run command in {issueId}: {command}".format(issueId=issueId, command="""Now is OK {}""".format(messages['Text']) )) connection.executeCommand(issueId=issueId, command="", comment=YT_COMMENT.format( status=messages['Status'], text=messages['Text']) )
def Main(sendTo, subject, yamlMessage): """ Workflow Zabbix-YouTrack :param sendTo: URL to Youtrack (ex. https://youtrack.example.com) :param subject: subject from Zabbix Action :param yamlMessage: message from Zabbix Action :return: """ # ----- Use below example yamlMessage to debug ----- # yamlMessage = """Name: 'Test Zabbix-YT workflow, ignore it' # Text: 'Agent ping (server:agent.ping()): DOWN (1) ' # Hostname: 'server.exmpale.ru' # Status: "OK" # Severity: "High" # EventID: "96976" # TriggerID: "123456789012" """ messages = yaml.load(yamlMessage) # ----- START Issue parameters ----- # Correspondence between the YouTrackPriority and ZabbixSeverity # Critical >= High # Normal < High ytPriority = 'Normal' if messages['Severity'] == 'Disaster' or messages['Severity'] == 'High': ytPriority = 'Critical' ytName = "{} ZabbixTriggerID::{}".format(messages['Name'], messages['TriggerID']) # ----- END Issue parameters ----- # ----- START Youtrack Issue description ----- # Search link to other issue searchString = "Hostname: '{}'".format(messages['Hostname']) linkToHostIssue = "{youtrack}/issues/{projectname}?q={query}".format( youtrack=sendTo, projectname=YT_PROJECT_NAME, query=urllib.parse.quote(searchString, safe='')) issueDescription = """ {ytName} ----- {yamlMessage} ----- - [https://zabbix.example.com/zabbix.php?action=dashboard.view Zabbix Dashboard] - Show [{linkToHostIssue} all issue for *this host*] """.format( ytName=ytName, yamlMessage=yamlMessage, linkToHostIssue=linkToHostIssue, ) # ----- END Youtrack Issue description ----- # ----- START Youtrack current week ----- # Create connect to Youtrack API connection = Connection(sendTo, YT_USER, YT_PASSWORD) # Get current week in YT format (Sprint planned) version = connection.getAllBundles('version') for fixVersion in version[0].values: if fixVersion['archived'] == False and fixVersion['released'] == False: fixVersionWeek = fixVersion['name'] break # ----- END Youtrack current week ----- # ----- START Youtrack get or create issue ----- # Get issue if exist # Search for TriggerID createNewIssue = False logger.debug("Get issue with text '{}'".format(messages['TriggerID'])) issue = connection.getIssues( YT_PROJECT_NAME, "ZabbixTriggerID::{}".format(messages['TriggerID']), 0, 1) if len(issue) == 0: createNewIssue = True else: # if issue contains TriggerID in summary, then it's good issue # else create new issue, this is bad issue, not from Zabbix if "ZabbixTriggerID::{}".format( messages['TriggerID']) in issue[0]['summary']: issueId = issue[0]['id'] issue = connection.getIssue(issueId) else: createNewIssue = True # Create new issue if createNewIssue: logger.debug("Create new issue because it is not exist") issue = connection.createIssue( YT_PROJECT_NAME, 'Unassigned', ytName, issueDescription, priority=ytPriority, subsystem=YT_SUBSYSTEM, type=YT_TYPE, ) time.sleep(3) # Parse ID for new issue result = re.search(r'(CM-\d*)', issue[0]['location']) issueId = result.group(0) issue = connection.getIssue(issueId) logger.debug("Issue have id={}".format(issueId)) # Set issue service ExecAndLog(connection, issueId, "Service {}".format(YT_SERVICE)) # Update priority ExecAndLog(connection, issueId, "Priority {}".format(ytPriority)) # ----- END Youtrack get or create issue ----- # ----- START PROBLEM block ------ if messages['Status'] == "PROBLEM": # Issue exist and NOT Hold on, Unnassigned and Estimated time set if issue['State'] != 'Hold on': # Estimated time ExecAndLog(connection, issueId, "Estimated time {}".format(YT_TIME)) # Update fix version ExecAndLog(connection=connection, issueId=issueId, command="Sprint planned {}".format(fixVersionWeek)) # Reopen if Fixed or Verified or Canceled if issue['State'] == 'Fixed' or issue['State'] == 'Verified' or issue[ 'State'] == 'Canceled': # Reopen Issue ExecAndLog(connection, issueId, "State reopen") # Assignee issue ExecAndLog(connection, issueId, command="Assignee Unassigned") # Update summary and description for issue logger.debug("Run command in {issueId}: {command}".format( issueId=issueId, command= """Update summary and description with connection.updateIssue method""" )) connection.updateIssue(issueId=issueId, summary=ytName, description=issueDescription) # Add comment logger.debug("Run command in {issueId}: {command}".format( issueId=issueId, command="""Now is PROBLEM {}""".format(messages['Text']))) connection.executeCommand(issueId=issueId, command="", comment=YT_COMMENT.format( status=messages['Status'], text=messages['Text'])) # Send ID to Zabbix: logger.debug("ZABBIX-API: Send Youtrack ID to {}".format( messages['EventID'])) Zbx.event.acknowledge(eventids=messages['EventID'], message="Create Youtrack task") Zbx.event.acknowledge( eventids=messages['EventID'], message="https://youtrack.example.com/issue/{}".format(issueId)) # ----- End PROBLEM block ------ # ----- Start OK block ----- if messages['Status'] == "OK": if issue['State'] == 'Hold on' or issue['State'] == 'Registered': # Cancel if not in work ExecAndLog(connection, issueId, command="State Cancel") # Assignee issue ExecAndLog(connection, issueId, command="Assignee {}".format(YT_ASSIGNEE)) if issue['State'] == 'Fixed': # Verify if Fixed ExecAndLog(connection, issueId, command="State verify") logger.debug("Run command in {issueId}: {command}".format( issueId=issueId, command="""Now is OK {}""".format(messages['Text']))) connection.executeCommand(issueId=issueId, command="", comment=YT_COMMENT.format( status=messages['Status'], text=messages['Text']))