0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
2 # |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
3 # Authors: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
4 # BenoƮt Allard <benoit.allard@greenbone.net> |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
5 # |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
6 # Copyright: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
7 # Copyright (C) 2014 Greenbone Networks GmbH |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
8 # |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
9 # This program is free software; you can redistribute it and/or |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
10 # modify it under the terms of the GNU General Public License |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
11 # as published by the Free Software Foundation; either version 2 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
12 # of the License, or (at your option) any later version. |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
13 # |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
14 # This program is distributed in the hope that it will be useful, |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
17 # GNU General Public License for more details. |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
18 # |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
19 # You should have received a copy of the GNU General Public License |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
20 # along with this program; if not, write to the Free Software |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
21 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
22 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
23 """\ |
26
|
24 Product Tree Objects related to CVRF Documents |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
25 """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
26 |
26
|
27 from .common import ValidationError |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
28 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
29 class CVRFProductTree(object): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
30 def __init__(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
31 # All the branches, they can be order with their `parent` attribute |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
32 self._branches = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
33 self._groups = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
34 self._relationships = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
35 self._products = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
36 self._groups = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
37 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
38 def addProduct(self, product): |
15
|
39 """ Add to the product list """ |
|
40 self._products.append(product) |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
41 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
42 def addRelationship(self, rel): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
43 self._relationships.append(rel) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
44 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
45 def addGroup(self, group): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
46 self._groups.append(group) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
47 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
48 def getProductForID(self, productid): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
49 for product in self._products: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
50 if product._productid == productid: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
51 return product |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
52 raise KeyError(productid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
53 |
43
|
54 def getProductForCPE(self, cpe): |
|
55 for product in self._products: |
|
56 if product._cpe == cpe: |
|
57 return product |
|
58 raise KeyError(cpe) |
|
59 |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
60 def getGroupForID(self, groupid): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
61 for group in self._groups: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
62 if group._groupid == groupid: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
63 return group |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
64 raise KeyError(groupid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
65 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
66 def decomposeProduct(self, productid): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
67 """ In case of product defined as a relationship (product X installed |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
68 on OS Y), this gives us the following tuple: (OS, product). """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
69 product = self.getProductForID(productid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
70 parent = product._parent |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
71 if parent is None: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
72 return (None, None) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
73 if not isinstance(parent, CVRFRelationship): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
74 return (None, None) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
75 relationtype = parent._relationtype.replace(' ', '').lower() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
76 if relationtype not in ('defaultcomponentof', 'installedon'): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
77 return (None, None) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
78 return ( |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
79 self.getProductForID(parent._relatestoproductreference), |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
80 self.getProductForID(parent._productreference) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
81 ) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
82 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
83 def getBranch(self, path): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
84 if len(path) == 0: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
85 return self |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
86 branches = self._branches |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
87 node = None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
88 for idx in path: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
89 node = branches[idx] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
90 branches = node._childs |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
91 return node |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
92 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
93 def getBranches(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
94 for branch in self._branches: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
95 yield branch |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
96 for sub_branch in branch.getBranches(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
97 yield sub_branch |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
98 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
99 def getPath(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
100 return () |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
101 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
102 def getNameOfRelationship(self, relationship): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
103 if relationship is None: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
104 return '' |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
105 return ' '.join((self.getProductForID(relationship._productreference)._name, 'as', |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
106 relationship._relationtype.lower(), |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
107 self.getProductForID(relationship._relatestoproductreference)._name)) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
108 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
109 def getOrphanedBranches(self, product=None): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
110 """ The branches that could accept `product` as Product Definition """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
111 white_list = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
112 if product is not None: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
113 white_list = [product._parent] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
114 for branch in self.getBranches(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
115 if (branch in white_list) or branch.isOrphaned(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
116 yield branch |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
117 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
118 def getNotTerminalBranches(self, b2=None): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
119 """\ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
120 The branches that could accept `b2` as new sub-branches |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
121 Note that b2 and all its sub-branches cannot be listed |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
122 """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
123 black_list = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
124 if b2 is not None: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
125 black_list = [b2] + list(b2.getBranches()) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
126 for branch in self.getBranches(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
127 if branch in black_list: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
128 continue |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
129 if branch._product is None: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
130 yield branch |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
131 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
132 def getOrphanedRelationships(self, product=None): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
133 """ The relationships that need a product defninition """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
134 white_list = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
135 if product is not None: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
136 white_list = [product.getCurrentRelationship()] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
137 for i, relationship in enumerate(self._relationships): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
138 if (relationship in white_list) or relationship.isOrphaned(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
139 yield (i, relationship) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
140 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
141 def nbProducts(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
142 """ Amount of 'raw' Products """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
143 return len([p for p in self._products if p._parent is self]) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
144 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
145 def validate(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
146 for branch in self._branches: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
147 branch.validate() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
148 productids = set() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
149 for product in self._products: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
150 product.validate() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
151 if product._productid in productids: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
152 raise ValidationError('Each ProductID must be unique (%s)' % product._productid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
153 productids.add(product._productid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
154 for relationship in self._relationships: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
155 relationship.validate() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
156 for productid in (relationship._productreference, |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
157 relationship._relatestoproductreference): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
158 if productid not in productids: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
159 raise ValidationError('ProductID %s is unknown' % productid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
160 groupids = set() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
161 for group in self._groups: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
162 group.validate() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
163 if group._groupid in groupids: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
164 raise ValidationError('Duplicated GroupID: %s' % group._groupid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
165 groupids.add(group._groupid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
166 for productid in group._productids: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
167 if productid not in productids: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
168 raise ValidationError('ProductID %s is unknown' % productid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
169 return productids, groupids |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
170 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
171 def __str__(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
172 return 'Products: %s' % '\n'.join(str(p) for p in self._products) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
173 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
174 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
175 class CVRFProductBranch(object): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
176 TYPES = ('Vendor', 'Product Family', 'Product Name', 'Product Version', |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
177 'Patch Level', 'Service Pack', 'Architecture', 'Language', |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
178 'Legacy', 'Specification') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
179 def __init__(self, _type, name, parentbranch): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
180 self._type = _type |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
181 self._name = name |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
182 self._childs = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
183 self._product = None |
15
|
184 self.link(parentbranch) |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
185 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
186 def getParent(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
187 return self._parentbranch |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
188 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
189 def getPath(self, string=False): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
190 """ return the path to that branch element as a tuple """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
191 if self.isRoot(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
192 for i, b in enumerate(self._parentbranch._branches): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
193 if b is self: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
194 if string: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
195 return '%d' % i |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
196 return (i, ) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
197 else: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
198 for i, b in enumerate(self._parentbranch._childs): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
199 if b is self: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
200 if string: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
201 return '/'.join([self._parentbranch.getPath(string), '%d' % i]) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
202 return self._parentbranch.getPath(string) + (i,) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
203 if string: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
204 return '' |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
205 return () |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
206 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
207 def getTree(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
208 """ this returns a list of tuples (type, name) leading to here""" |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
209 if self.isRoot(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
210 return [(self._type, self._name)] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
211 return self._parentbranch.getTree() + [(self._type, self._name)] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
212 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
213 def getName(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
214 return ' / '.join("%s: %s" % (type_, name) for type_, name in self.getTree()) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
215 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
216 def getParentPath(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
217 """ return as string the path to the parent """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
218 return '/'.join('%s' % p for p in self.getPath()[:-1]) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
219 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
220 def isRoot(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
221 return isinstance(self._parentbranch, CVRFProductTree) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
222 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
223 def isOrphaned(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
224 """ Has no childs and no product """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
225 return len(self._childs) == 0 and (self._product is None) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
226 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
227 def getBranches(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
228 for branch in self._childs: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
229 yield branch |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
230 for sub_branch in branch.getBranches(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
231 yield sub_branch |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
232 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
233 def unlink(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
234 """ Unset our _parent, and remove us from the _parent._childs """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
235 if self.isRoot(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
236 self.getParent()._branches.remove(self) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
237 else: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
238 self.getParent()._childs.remove(self) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
239 self._parentbranch = None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
240 |
15
|
241 def link(self, parent): |
|
242 """ Actually, only set the parent """ |
|
243 self._parentbranch = parent |
|
244 if self.isRoot(): |
|
245 parent._branches.append(self) |
|
246 else: |
|
247 parent._childs.append(self) |
|
248 |
|
249 |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
250 def validate(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
251 if not self._type: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
252 raise ValidationError('A Branch must have a Type') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
253 if self._type not in self.TYPES: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
254 raise ValidationError('A Branch Type must be one of %s' % ', '.join(self.TYPES)) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
255 if not self._name: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
256 raise ValidationError('A Branch must have a Name') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
257 for branch in self._childs: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
258 branch.validate() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
259 if self.isOrphaned(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
260 raise ValidationError('A Branch must have at least a sub-product or sub-branches') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
261 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
262 def __str__(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
263 return "%s: %s" % (self._type, self._name) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
264 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
265 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
266 class CVRFFullProductName(object): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
267 def __init__(self, productid, name, parent, cpe=None): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
268 self._productid = productid |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
269 self._name = name |
15
|
270 self._cpe = cpe |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
271 # Can be None (directly under the tree), a ProductBranch, or a |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
272 # Relationship |
15
|
273 self.link(parent) |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
274 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
275 def isRoot(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
276 return isinstance(self._parent, CVRFProductTree) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
277 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
278 def isRelationship(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
279 return isinstance(self._parent, CVRFRelationship) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
280 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
281 def getTree(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
282 if not isinstance(self._parent, CVRFProductBranch): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
283 return [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
284 return self._parent.getTree() |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
285 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
286 def getParentPath(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
287 if self.isRoot() or self.isRelationship(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
288 return '' |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
289 return self._parent.getPath(True) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
290 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
291 def getCurrentRelationship(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
292 if self.isRelationship(): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
293 return self._parent |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
294 return None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
295 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
296 def unlink(self): |
15
|
297 """ Unset our _parent, and remove us from the _parent._childs |
|
298 We are still in the product list. |
|
299 """ |
|
300 if not self.isRoot(): |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
301 self._parent._product = None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
302 self._parent = None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
303 |
15
|
304 def link(self, parent): |
|
305 self._parent = parent |
|
306 if not self.isRoot(): |
|
307 parent._product = self |
|
308 |
0
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
309 def validate(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
310 if not self._productid: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
311 raise ValidationError('A Product must have a ProductID') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
312 if not self._name: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
313 raise ValidationError('A Product must have a Name') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
314 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
315 def __str__(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
316 return "%s (%s)" % (self._productid, self._name) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
317 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
318 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
319 class CVRFRelationship(object): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
320 TYPES = ('Default Component Of', 'Optional Component Of', |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
321 'External Component Of', 'Installed On', 'Installed With') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
322 def __init__(self, productref, reltype, relatestoproductref): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
323 self._productreference = productref |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
324 self._relationtype = reltype |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
325 self._relatestoproductreference = relatestoproductref |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
326 self._product = None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
327 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
328 def getParent(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
329 """ All parent element of a FullProductName should implement that |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
330 method """ |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
331 return None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
332 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
333 def isOrphaned(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
334 return self._product is None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
335 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
336 def validate(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
337 if not self._productreference: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
338 raise ValidationError('A Relationship must have a Product Reference') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
339 if not self._relationtype: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
340 raise ValidationError('A Relationship must have a Relation Type') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
341 if self._relationtype not in self.TYPES: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
342 raise ValidationError('Relation Type must be one of %s' % ', '.join(self.TYPES)) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
343 if not self._relatestoproductreference: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
344 raise ValidationError('A Relationship must have a "Relates To product Reference"') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
345 if self._productreference == self._relatestoproductreference: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
346 raise ValidationError('A Relationship cannot reference twice the same Product') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
347 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
348 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
349 class CVRFGroup(object): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
350 def __init__(self, groupid): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
351 self._groupid = groupid |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
352 self._description = None |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
353 self._productids = [] |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
354 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
355 def setDescription(self, description): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
356 self._description = description |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
357 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
358 def addProductID(self, productid): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
359 self._productids.append(productid) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
360 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
361 def getTitle(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
362 if self._description: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
363 return "%s (%d products)" % (self._description, len(self._productids)) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
364 return "#%s (%d products)" % (self._groupid, len(self._productids)) |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
365 |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
366 def validate(self): |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
367 if not self._groupid: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
368 raise ValidationError('A Group must have a GroupID') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
369 if not self._productids or len(self._productids) < 2: |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
370 raise ValidationError('A Group must contain at least two products') |
Benoît Allard <benoit.allard@greenbone.net>
parents:
diff
changeset
|
371 |