Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

# -*- coding: utf-8 -*- 

# Copyright: (c) 2022, XLAB Steampunk <steampunk@xlab.si> 

# 

# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 

 

from __future__ import absolute_import, division, print_function 

 

__metaclass__ = type 

 

import re 

 

 

REL_TABLE = "cmdb_rel_ci" 

# sysparm_fields to be used when querying REL_TABLE. Uses dot-walking 

# notation to extract fields from linked tables in a single REST API call. 

# https://docs.servicenow.com/bundle/rome-application-development/page/integrate/inbound-rest/concept/c_RESTAPI.html#d1168970e439 

REL_FIELDS = set( 

( 

"sys_id", 

"type.name", 

"parent.sys_id", 

"parent.name", 

"parent.sys_class_name", 

"child.sys_id", 

"child.name", 

"child.sys_class_name", 

) 

) 

 

# Similar as above but for sysparm_query 

REL_QUERY = None 

 

 

def _extend_records_with_groups(records, groups): 

for record in records: 

sys_id = record.get("sys_id") 

sys_id_groups = groups.get(sys_id, set()) 

record["relationship_groups"] = sys_id_groups 

 

return records 

 

 

def _extract_ci_rel_type(type_name): 

# type_name is of form "Parent description::Child description". 

# Return the value of form (Parent_description, Child_description). 

type_name = type_name or "__" 

type_name = re.sub(r"\s|:", "_", type_name) 

ci_rel_type = tuple(type_name.split("__")) 

 

return ci_rel_type 

 

 

def _extract_parent_relation(rel_record): 

sys_id = rel_record.get("parent.sys_id", "") 

ci_name = rel_record.get("child.name", "") 

ci_class = rel_record.get("child.sys_class_name", "") 

type_name = rel_record.get("type.name", "") 

ci_rel_type = _extract_ci_rel_type(type_name)[1] 

 

return sys_id, ci_name, ci_class, ci_rel_type 

 

 

def _extract_child_relation(rel_record): 

sys_id = rel_record.get("child.sys_id", "") 

ci_name = rel_record.get("parent.name", "") 

ci_class = rel_record.get("parent.sys_class_name", "") 

type_name = rel_record.get("type.name", "") 

ci_rel_type = _extract_ci_rel_type(type_name)[0] 

 

return sys_id, ci_name, ci_class, ci_rel_type 

 

 

def _relations_to_groups(rel_records): 

groups = dict() 

 

extract_relation = dict( 

parent=_extract_parent_relation, child=_extract_child_relation 

) 

 

for rel_record in rel_records or list(): 

for target in ("child", "parent"): 

t_extr_rel = extract_relation[target] 

sys_id, ci_name, ci_class, ci_rel_type = t_extr_rel(rel_record) 

 

if sys_id and ci_name and ci_rel_type and ci_class: 

rel_group = "{0}_{1}".format(ci_name, ci_rel_type) 

 

items = groups.setdefault(sys_id, set()) 

items.add(rel_group) 

 

return groups 

 

 

def enhance_records_with_rel_groups(records, rel_records): 

groups = _relations_to_groups(rel_records) 

records = _extend_records_with_groups(records, groups) 

 

return records