class JadeEngine: def __init__(self, config: Config, applications_root_dir: str): self.config = config self.applications_root_dir = applications_root_dir self.dependency_map = DependencyMap(self.config) def explode(self): virtual_servers = find_object_with_type_match( config=self.config, type_matcher=("ltm", "virtual") ) for virtual_server in virtual_servers: objects = self.dependency_map.get_dependencies(virtual_server) objects.add(virtual_server) application_config = Config.from_string("") for obj_id in objects: obj = self.config.fields.get(obj_id) application_config.field_collection.add_data(obj.data, copy=False) application_name = self.config.fields.get(virtual_server).name.replace( os.path.sep, "_" ) dirname = os.path.join(self.applications_root_dir, application_name) os.mkdir(dirname) application_config.build(dirname=dirname)
def test_dependency_custom_comparer(comparer_return, result_length): config_string = """ cm device bigip1 { mirror-ip foo } net self if1 { address bar } """ config = Config.from_string(string=config_string) fake_comparer = MagicMock(return_value=comparer_return) dep = FieldValueToFieldValueDependency( child_types=[("cm", "device")], field_name="mirror-ip", parent_types=[("net", "self")], target_field_name="address", comparer=fake_comparer, ) dep_map = DependencyMap(config, [dep]) fake_comparer.assert_called_with("bar", "foo") assert len(dep_map.forward) == result_length
def test_build_dependencies_map(test_deduplication): config = f""" ltm node /Common/192.168.0.100 {{ address 192.168.0.100 }} ltm monitor tcp /Common/tcp_custom {{ }} ltm pool /Common/test_pool {{ members {{ /Common/192.168.0.100:0 {{ address 192.168.0.100 {"monitor /Common/tcp_custom" if test_deduplication else ""} }} }} monitor /Common/tcp_custom }} """ config = Config.from_string(string=config) dependencies = [ FieldValueToNameDependency( child_types=[("ltm", "pool")], field_name="monitor", parent_types=[("ltm", "monitor")], ), SubCollectionDependency( child_types=[("ltm", "pool")], field_name="members", parent_types=[("ltm", "node")], dependency=FieldValueToFieldValueDependency( field_name="address", target_field_name="address", ), ), ] if test_deduplication: dependencies.append( SubCollectionDependency( child_types=[("ltm", "pool")], field_name="members", parent_types=[("ltm", "monitor")], dependency=FieldValueToNameDependency(field_name="monitor",), ), ) result = DependencyMap(config=config, dependencies=dependencies) pool_id = "ltm pool /Common/test_pool" monitor_id = "ltm monitor tcp /Common/tcp_custom" node_id = "ltm node /Common/192.168.0.100" assert len(result.forward) == 1 assert len(result.reverse) == 2 assert result.forward[pool_id] == {monitor_id, node_id} assert result.reverse[monitor_id] == {pool_id} assert result.reverse[node_id] == {pool_id}
def __init__(self, config: Config, as3_declaration: Dict, as3_ucs_path: str): self.config = config self.as3_declaration = as3_declaration self.as3_ucs_path = as3_ucs_path self.dependency_map = DependencyMap(self.config) self.plugins = load_plugins() self.as3_declaration_pointer = self.as3_declaration if ( self.as3_declaration_pointer and "declaration" in self.as3_declaration_pointer ): self.as3_declaration_pointer = self.as3_declaration_pointer["declaration"]
def generate_dependency_comments( conflict_id: str, dependency_map: DependencyMap, obj_id: Union[str, Iterable[str]], comments: Dict[str, List[str]], ): obj_ids = [obj_id] if isinstance(obj_id, str) else obj_id for obj_id in obj_ids: def generate_comment(parent: str, child: str): comment = "{}: Depends on an object '{}' which requires an action".format( conflict_id, parent ) if comment not in comments[child]: comments[child].append(comment) dependency_map.dfs( func=generate_comment, _map=dependency_map.reverse, obj_id=obj_id )
def test_as3_pem(): bigip_conf_path = os.path.join(AS3_CONFIG_DIR, "bigip-pem.conf") as3_source_path = os.path.join(AS3_CONFIG_DIR, "as3-pem.json") as3_pattern_path = os.path.join(AS3_CONFIG_DIR, "as3-pem-result.json") source_as3 = load_declaration(as3_source_path) pattern_as3 = load_declaration(as3_pattern_path) config = Config.from_conf(bigip_conf_path) mutable_config = deepcopy(config) mutable_as3 = deepcopy(source_as3) as3ucs = As3ucs(mutable_as3) irules = as3ucs.decode_as3_irules() pem_obj = Pem(config, DependencyMap(config, DEFAULT_DEPENDENCIES), source_as3, as3_source_path) pem_obj.adjust_objects(mutable_config, mutable_as3) as3ucs.encode_as3_irules(irules) assert stringify_declaration(pattern_as3) == stringify_declaration( mutable_as3)
def __init__(self, config: Config, applications_root_dir: str): self.config = config self.applications_root_dir = applications_root_dir self.dependency_map = DependencyMap(self.config)
def test_build_dependencies_map_net_module(): config = """ net stp /Common/cist { trunks { trunk_external {} trunk_internal {} } vlans { /Common/virtWire_vlan_4096_1_353 /Common/virtWire_vlan_4096_2_354 } } net interface 1.1 {} net interface 1.2 {} net interface 2.1 {} net interface 2.2 {} net route-domain /Common/0 { vlans { /Common/virtWire_vlan_4096_1_353 /Common/virtWire_vlan_4096_2_354 /Common/virtWire } } net trunk trunk_external { interfaces { 2.1 2.2 } } net trunk trunk_internal { interfaces { 1.1 1.2 } } net vlan /Common/virtWire_vlan_4096_1_353 { interfaces { trunk_external {} } } net vlan /Common/virtWire_vlan_4096_2_354 { interfaces { trunk_internal {} } } net vlan-group /Common/virtWire { members { /Common/virtWire_vlan_4096_1_353 /Common/virtWire_vlan_4096_2_354 } } net fdb vlan /Common/virtWire_vlan_4096_1_353 { } net fdb vlan /Common/virtWire_vlan_4096_2_354 { } """ config = Config.from_string(string=config) result = DependencyMap(config) # assert len(result.forward) == 9 assert result.forward["net vlan-group /Common/virtWire"] == { "net vlan /Common/virtWire_vlan_4096_1_353", "net vlan /Common/virtWire_vlan_4096_2_354", } assert result.forward["net vlan /Common/virtWire_vlan_4096_1_353"] == { "net trunk trunk_external", } assert result.forward["net fdb vlan /Common/virtWire_vlan_4096_1_353"] == { "net vlan /Common/virtWire_vlan_4096_1_353", } assert result.forward["net vlan /Common/virtWire_vlan_4096_2_354"] == { "net trunk trunk_internal", } assert result.forward["net fdb vlan /Common/virtWire_vlan_4096_2_354"] == { "net vlan /Common/virtWire_vlan_4096_2_354", } assert result.forward["net trunk trunk_external"] == { "net interface 2.1", "net interface 2.2", } assert result.forward["net trunk trunk_internal"] == { "net interface 1.1", "net interface 1.2", } assert result.forward["net route-domain /Common/0"] == { "net vlan-group /Common/virtWire", "net vlan /Common/virtWire_vlan_4096_1_353", "net vlan /Common/virtWire_vlan_4096_2_354", } assert result.forward["net stp /Common/cist"] == { "net vlan /Common/virtWire_vlan_4096_1_353", "net vlan /Common/virtWire_vlan_4096_2_354", "net trunk trunk_external", "net trunk trunk_internal", } assert len(result.reverse) == 9 assert result.reverse["net trunk trunk_internal"] == { "net stp /Common/cist", "net vlan /Common/virtWire_vlan_4096_2_354", } assert result.reverse["net trunk trunk_external"] == { "net vlan /Common/virtWire_vlan_4096_1_353", "net stp /Common/cist", } assert result.reverse["net vlan /Common/virtWire_vlan_4096_2_354"] == { "net fdb vlan /Common/virtWire_vlan_4096_2_354", "net vlan-group /Common/virtWire", "net route-domain /Common/0", "net stp /Common/cist", } assert result.reverse["net vlan /Common/virtWire_vlan_4096_1_353"] == { "net fdb vlan /Common/virtWire_vlan_4096_1_353", "net vlan-group /Common/virtWire", "net route-domain /Common/0", "net stp /Common/cist", } assert result.reverse["net vlan-group /Common/virtWire"] == { "net route-domain /Common/0" } assert result.reverse["net interface 1.2"] == {"net trunk trunk_internal"} assert result.reverse["net interface 1.1"] == {"net trunk trunk_internal"} assert result.reverse["net interface 2.2"] == {"net trunk trunk_external"} assert result.reverse["net interface 2.1"] == {"net trunk trunk_external"}