Skip to content

辞書型を解析#

import re
import yaml
from pprint import pprint
from collections.abc import Iterable



def extract_topology_info(file_path):
    topology_result = {}
    # YAMLファイルからtopology_resultを取得
    with open(file_path, 'r') as file:
        yaml_dict = yaml.safe_load(file)
        # 'devices'セクションを取得
        devices_section = yaml_dict['devices']
        # 'topology'セクションを取得
        topology_section = yaml_dict['topology']

        for device, details in topology_section.items():
            interfaces = details['interfaces']
            topology_result[device] = {interface['link']: name for name, interface in interfaces.items()}
        # 'devices'セクションからホスト名を追加
        for hostname, details in devices_section.items():
            alias = details['alias']
            topology_result[alias]['hostname'] = hostname

    return topology_result


def replace_template_variables(data,testnumber, variables):
    for key, value in data.items():
        if isinstance(value, dict):
            replace_template_variables(value,testnumber, variables)
        else:
            # Step 1: Replacing the pattern with the value from procedure_vars_dict
            for var_key, var_value in variables.items():
                value = value.replace(f"%{{vars_{testnumber}.nodes.{var_key}}}", var_value)
            # Step 2: Replacing the remaining pattern
            for var_key, var_value in variables.items():
                value = value.replace(f"%VARIABLES{{runtime.testbed.devices[{var_value}].name}}", var_value)
            data[key] = value
            # Additional Step: Replacing other variables such as '%VARIABLES{DUT_if1}'
            for var_key, var_value in variables.items():
                value = value.replace(f"%VARIABLES{{{var_key}}}", var_value)
                data[key] = value


def find_key(data, target_key, results=None):
    if results is None:
        results = []
    if isinstance(data, dict):
        for key, value in data.items():
            if key == target_key:
                results.append(value)
            find_key(value, target_key, results)
    elif isinstance(data, Iterable) and not isinstance(data, str):
        for item in data:
            find_key(item, target_key, results)
    return results



file_path = 'testbed_topology_mylab_copy.yaml'
topology_result = extract_topology_info(file_path)


trigger_datafile_path = 'trigger_datafile_copy2.yaml'
testnumber = '003-001-009'
testnumber_under = re.sub('-','_',testnumber)
#YAMLファイルからvars_003_006_001セクションを解析
with open(trigger_datafile_path, 'r') as file:
    trigger_yaml_dict = yaml.safe_load(file)

vars_section = trigger_yaml_dict[f'vars_{testnumber_under}']
test_sections_section = trigger_yaml_dict.get(f'TriggerBlitz_tc{testnumber}', {}).get('test_sections', {})
nodes = vars_section['nodes']
links = vars_section['links']

# nodes 変数の変換
transformed_nodes = {}
for variable_name, node_alias in nodes.items():
    if node_alias == 'IXIA':
        continue
    transformed_nodes[variable_name] = topology_result[node_alias]['hostname']
# links 変数の変換
transformed_links = {}
configure_by_jinja2_data = {}
procedure_dict = {}

for section in test_sections_section:
    for step_name, step_details in section.items():
        # 変数定義セクションの解析
        if 'init_configuration' in step_name:
            for step_detail in step_details:
                if 'api' in step_detail and step_detail['api'].get('function') == 'get_single_interface':
                    arguments = step_detail['api']['arguments']
                    device_var = arguments['device'].split('.')[-1].strip('}')
                    link_var = arguments['link_name'].split('.')[-1].strip('}')
                    device_alias = vars_section['nodes'][device_var]
                    link_alias = vars_section['links'][link_var]
                    if 'save' in step_detail['api']:
                        for save_item in step_detail['api']['save']:
                            variable_name = save_item['variable_name']
                            # Transforming variable_name based on topology_result
                            transformed_value = topology_result[device_alias][link_alias]
                            transformed_links[variable_name] = transformed_value
                if 'api' in step_detail and step_detail['api'].get('function') == 'configure_by_jinja2':
                    template_name = step_detail['api']['arguments'].pop('template_name')
                    templates_dir = step_detail['api']['arguments'].pop('templates_dir') # templates_dir は特に使用しない予定
                    configure_by_jinja2_data[template_name] = step_detail['api']['arguments']

        else:
            # 試験手順部分を抽出する処理
            procedure_dict[step_name] = []
            execute_blocks = [(execute_block['device'],execute_block['command']) for execute_block in find_key(step_details, 'execute')]
            configure_blocks = [(configure_block['device'],configure_block['command']) for configure_block in find_key(step_details, 'configure')]
            tgn_blocks = find_key(step_details, 'tgn') # TODO:

            if tgn_blocks != []:
                pprint(tgn_blocks)

            if execute_blocks != []:
                for i in execute_blocks:
                    procedure_dict[step_name].append(i)
            if configure_blocks != []:
                for i in configure_blocks:
                    procedure_dict[step_name].append(i)


# topology_result
# transformed_nodes
# transformed_links
procedure_vars_dict = {**transformed_nodes, **transformed_links}
replace_template_variables(configure_by_jinja2_data, testnumber_under,procedure_vars_dict)
# 'dev_IXIA': '%VARIABLES{runtime.testbed.devices[%{vars_003_001_009.nodes.IXIA}].name}', を編集するように
pprint(configure_by_jinja2_data)