예제 #1
0
 def initialize(self, impl):
     if impl['module-list-file']['path'] in self.hello_message_file:
         LOGGER.info('Parsing a received json file')
         self.feature_set = 'ALL'
         self.os_version = impl['software-version']
         self.software_flavor = impl['software-flavor']
         self.vendor = impl['vendor']
         self.platform = impl['name']
         self.os = impl['os-type']
         self.software_version = impl['software-version']
         self.owner = impl['module-list-file']['owner']
         self.repo = impl['module-list-file']['repository'].split('.')[0]
         self.path = impl['module-list-file']['path']
         self.branch = impl['module-list-file'].get('branch')
         repo = repoutil.RepoUtil(
             '{}{}/{}'.format(github_url, self.owner, self.repo),
             self.logger)
         repo.clone()
         if not self.branch:
             self.branch = 'master'
         self.branch = repo.get_commit_hash(self.branch)
         repo.remove()
         self.platform_data.append({
             'software-flavor': self.software_flavor,
             'platform': self.platform
         })
예제 #2
0
 def _load_yangmodels_repo(self):
     self.repo_owner = 'YangModels'
     self.repo_name = 'yang'
     repo_url = os.path.join(github_url, self.repo_owner, self.repo_name)
     try:
         repo = repoutil.load(self.dir_paths['yang_models'], repo_url)
     except InvalidGitRepositoryError:
         repo = repoutil.RepoUtil(
             repo_url,
             clone_options={'local_dir': self.dir_paths['yang_models']},
             logger=self.logger)
     self.repo = repo
예제 #3
0
    yang_models_url_suffix = config.get('General-Section',
                                        'yang-models-repo-url_suffix')
    temp_dir = config.get('Directory-Section', 'temp')
    LOGGER = log.get_logger('draftPullLocal',
                            log_directory + '/jobs/draft-pull-local.log')
    LOGGER.info('Starting cron job IETF pull request local')

    github_credentials = ''
    if len(username) > 0:
        github_credentials = username + ':' + token + '@'

    # Fork and clone the repository YangModles/yang
    LOGGER.info('Cloning repository')
    reponse = requests.post('https://' + github_credentials +
                            yang_models_url_suffix)
    repo = repoutil.RepoUtil('https://' + token + '@github.com/' + username +
                             '/yang.git')

    repo.clone(config_name, config_email)
    LOGGER.info('Cloning repo to local directory {}'.format(repo.localdir))

    ietf_draft_json = requests.get(ietf_draft_url,
                                   auth=(private_credentials[0],
                                         private_credentials[1])).json()
    response = requests.get(ietf_rfc_url,
                            auth=(private_credentials[0],
                                  private_credentials[1]))
    zfile = open(repo.localdir + '/rfc.tgz', 'wb')
    zfile.write(response.content)
    zfile.close()
    tgz = tarfile.open(repo.localdir + '/rfc.tgz')
    tgz.extractall(repo.localdir + '/standard/ietf/RFC')
예제 #4
0
    def _resolve_imports(self, dependencies: t.List[Dependency],
                         git_commit_hash: str) -> list:
        LOGGER.debug('Resolving imports')
        imports = []
        try:
            imports = self._parsed_yang.search('import')

            for chunk in imports:
                dependency = Dependency()
                dependency.name = chunk.arg
                revisions = chunk.search('revision-date')
                if revisions:
                    dependency.revision = revisions[0].arg
                if dependency.revision:
                    yang_file = self._find_file(dependency.name,
                                                dependency.revision)
                else:
                    yang_file = self._find_file(dependency.name)
                if yang_file is None:
                    dependency.schema = None
                else:
                    try:
                        if os.path.dirname(yang_file) == os.path.dirname(
                                self._path):
                            if self.schema:
                                dependency.schema = '/'.join(
                                    (*self.schema.split('/')[0:-1],
                                     yang_file.split('/')[-1]))
                            else:
                                dependency.schema = None
                        else:
                            if '/yangmodels/yang/' in yang_file:
                                suffix = os.path.abspath(yang_file).split(
                                    '/yangmodels/yang/')[1]
                                # First load/clone YangModels/yang repo
                                owner_name = 'YangModels'
                                repo_name = 'yang'
                                repo_url = os.path.join(
                                    github_url, owner_name, repo_name)
                                try:
                                    repo = repoutil.load(
                                        self.yang_models, repo_url)
                                except InvalidGitRepositoryError:
                                    repo = repoutil.RepoUtil(
                                        repo_url,
                                        clone_options={
                                            'local_dir': self.yang_models
                                        })
                                # Check if repository submodule
                                for submodule in repo.repo.submodules:
                                    if submodule.name in suffix:
                                        repo_url = submodule.url.lower()
                                        repo_dir = os.path.join(
                                            self.yang_models, submodule.name)
                                        repo = repoutil.load(
                                            repo_dir, repo_url)
                                        owner_name = repo.get_repo_owner()
                                        repo_name = repo.get_repo_dir().split(
                                            '.git')[0]
                                        suffix = suffix.replace(
                                            '{}/'.format(submodule.name), '')

                                branch = repo.get_commit_hash(suffix, 'main')

                                dependency.schema = os.path.join(
                                    github_raw, owner_name, repo_name, branch,
                                    suffix)
                            elif git_commit_hash in yang_file:
                                if self.schema:
                                    prefix = self.schema.split(
                                        '/{}/'.format(git_commit_hash))[0]
                                    suffix = os.path.abspath(yang_file).split(
                                        '/{}/'.format(git_commit_hash))[1]
                                    dependency.schema = '{}/master/{}'.format(
                                        prefix, suffix)
                                else:
                                    dependency.schema = None
                    except:
                        LOGGER.exception(
                            'Unable to resolve schema for {}@{}.yang'.format(
                                dependency.name, dependency.revision))
                        dependency.schema = None
                        dependencies.append(dependency)
                dependencies.append(dependency)
        finally:
            return imports
예제 #5
0
    def __init__(self,
                 log_directory,
                 hello_message_file,
                 index,
                 prepare,
                 integrity_checker,
                 api,
                 sdo,
                 json_dir,
                 html_result_dir,
                 save_file_to_dir,
                 private_dir,
                 yang_models_dir,
                 run_integrity=False):
        global LOGGER
        LOGGER = log.get_logger('capability',
                                log_directory + '/parseAndPopulate.log')
        LOGGER.debug('Running constructor')
        self.logger = log.get_logger('repoutil',
                                     log_directory + '/parseAndPopulate.log')
        self.log_directory = log_directory
        self.run_integrity = run_integrity
        self.to = save_file_to_dir
        self.html_result_dir = html_result_dir
        self.json_dir = json_dir
        self.index = index
        self.prepare = prepare
        self.integrity_checker = integrity_checker
        self.parsed_yang = None
        self.api = api
        self.sdo = sdo
        self.yang_models_dir = yang_models_dir
        # Get hello message root
        if 'xml' in hello_message_file:
            try:
                LOGGER.debug('Checking for xml hello message file')
                self.root = ET.parse(hello_message_file).getroot()
            except:
                #try to change & to &amp
                hello_file = fileinput.FileInput(hello_message_file,
                                                 inplace=True)
                for line in hello_file:
                    print(line.replace('&', '&'), end='')
                hello_file.close()
                LOGGER.warning(
                    'Hello message file has & instead of &amp, automatically changing to &amp'
                )
                self.root = ET.parse(hello_message_file).getroot()
        # Split it so we can get vendor, os-type, os-version
        self.split = hello_message_file.split('/')
        self.hello_message_file = hello_message_file

        if self.api and not self.sdo:
            self.platform_data = []
            json_file = open(hello_message_file.split('.xml')[0] + '.json')
            impl = json.load(json_file)
            self.initialize(impl)
            json_file.close()

        if not self.api and not self.sdo:
            if os.path.isfile('/'.join(self.split[:-1]) +
                              '/platform-metadata.json'):
                self.platform_data = []
                json_file = open('/'.join(self.split[:-1]) +
                                 '/platform-metadata.json')
                platforms = json.load(json_file)['platforms']['platform']
                for impl in platforms:
                    self.initialize(impl)
                json_file.close()
            else:
                self.platform_data = []
                LOGGER.debug('Setting metadata concerning whole directory')
                self.owner = 'YangModels'
                self.repo = 'yang'
                repo = repoutil.RepoUtil(
                    '{}{}/{}'.format(github_url, self.owner, self.repo),
                    self.logger)
                repo.clone()
                self.path = None
                self.branch = 'master'
                self.branch = repo.get_commit_hash(self.branch)
                repo.remove()
                self.feature_set = 'ALL'
                self.software_version = self.split[5]
                self.vendor = self.split[3]
                # Solve for os-type
                if 'nx' in self.split[4]:
                    self.os = 'NX-OS'
                    self.platform = self.split[6].split('-')[0]
                elif 'xe' in self.split[4]:
                    self.os = 'IOS-XE'
                    self.platform = self.split[6].split('-')[0]
                elif 'xr' in self.split[4]:
                    self.os = 'IOS-XR'
                    self.platform = self.split[6].split('-')[1]
                else:
                    self.os = 'Unknown'
                    self.platform = 'Unknown'
                self.os_version = self.split[5]
                self.software_flavor = 'ALL'
                self.platform_data.append({
                    'software-flavor': self.software_flavor,
                    'platform': self.platform
                })
            integrity_checker.add_platform('/'.join(self.split[:-2]),
                                           self.platform)

        self.parsed_jsons = None
        if not run_integrity:
            self.parsed_jsons = LoadFiles(private_dir, log_directory)
예제 #6
0
    def parse_and_dump_sdo(self):
        repo = None
        if self.api:
            LOGGER.debug('Parsing sdo files sent via API')
            with open(self.json_dir + '/prepare-sdo.json', 'r') as f:
                sdos_json = json.load(f)
            sdos_list = sdos_json['modules']['module']
            for sdo in sdos_list:
                file_name = unicodedata.normalize('NFKD', sdo['source-file']['path'].split('/')[-1]) \
                    .encode('ascii', 'ignore')
                LOGGER.info(
                    'Parsing sdo file sent via API{}'.format(file_name))
                self.owner = sdo['source-file']['owner']
                repo_file_path = sdo['source-file']['path']
                self.repo = sdo['source-file']['repository'].split('.')[0]
                if repo is None:
                    repo = repoutil.RepoUtil(
                        '{}{}/{}'.format(github_url, self.owner, self.repo),
                        self.logger)
                    repo.clone()
                self.branch = sdo['source-file'].get('branch')
                if not self.branch:
                    self.branch = 'master'
                self.branch = repo.get_commit_hash(
                    '/'.join(repo_file_path.split('/')[:-1]), self.branch)
                root = self.owner + '/' + sdo['source-file']['repository'].split('.')[0] + '/' + self.branch + '/' \
                       + '/'.join(repo_file_path.split('/')[:-1])
                root = self.json_dir + '/temp/' + root
                if sys.version_info < (3, 4):
                    root = self.json_dir + '/temp/' \
                           + unicodedata.normalize('NFKD', root).encode('ascii', 'ignore')
                if sys.version_info >= (3, 4):
                    file_name = file_name.decode('utf-8', 'strict')
                if not os.path.isfile(root + '/' + file_name):
                    LOGGER.error(
                        'File {} sent via API was not downloaded'.format(
                            file_name))
                    continue
                if '[1]' not in file_name:
                    try:
                        yang = Modules(self.yang_models_dir,
                                       self.log_directory,
                                       root + '/' + file_name,
                                       self.html_result_dir, self.parsed_jsons,
                                       self.json_dir)
                    except ParseException as e:
                        LOGGER.error(e.msg)
                        continue
                    name = file_name.split('.')[0].split('@')[0]
                    schema = github_raw + self.owner + '/' + self.repo + '/' + self.branch + '/' + repo_file_path
                    yang.parse_all(self.branch, name,
                                   self.prepare.name_revision_organization,
                                   schema, self.to, sdo)
                    self.prepare.add_key_sdo_module(yang)

        else:
            LOGGER.debug('Parsing sdo files from directory')
            for root, subdirs, sdos in os.walk('/'.join(self.split)):
                for file_name in sdos:
                    if '.yang' in file_name and ('vendor' not in root
                                                 or 'odp' not in root):
                        LOGGER.info(
                            'Parsing sdo file from directory {}'.format(
                                file_name))

                        if '[1]' in file_name:
                            LOGGER.warning(
                                'File {} contains [1] it its file name'.format(
                                    file_name))
                        else:
                            try:
                                yang = Modules(self.yang_models_dir,
                                               self.log_directory,
                                               root + '/' + file_name,
                                               self.html_result_dir,
                                               self.parsed_jsons,
                                               self.json_dir)
                            except ParseException as e:
                                LOGGER.error(e.msg)
                                continue
                            name = file_name.split('.')[0].split('@')[0]
                            self.owner = 'YangModels'
                            self.repo = 'yang'
                            if repo is None:
                                repo = repoutil.RepoUtil(
                                    '{}{}/{}'.format(github_url, self.owner,
                                                     self.repo), self.logger)
                                repo.clone()
                            self.branch = 'master'
                            path = root + '/' + file_name
                            abs_path = os.path.abspath(path)
                            if '/yangmodels/yang/' in abs_path:
                                path = abs_path.split('/yangmodels/yang/')[1]
                            else:
                                path = re.split('tmp\/\w*\/', abs_path)[1]
                            self.branch = repo.get_commit_hash(
                                path, self.branch)
                            schema = (github_raw + self.owner + '/' +
                                      self.repo + '/' + self.branch + '/' +
                                      path)
                            yang.parse_all(
                                self.branch, name,
                                self.prepare.name_revision_organization,
                                schema, self.to)
                            self.prepare.add_key_sdo_module(yang)
        repo.remove()
예제 #7
0
        process = subprocess.Popen(['python', '../runYANGallstats/runYANGallstats.py', '--rootdir',
                                    yang_models + '/standard/mef/src/model/standard', '--removedup', 'True'],
                                   stdout=subprocess.PIPE)
        out, err = process.communicate()
        process_data(out, sdo_list, yang_models + '/standard/mef/src/model/standard', 'MEF standard')

        process = subprocess.Popen(['python', '../runYANGallstats/runYANGallstats.py', '--rootdir',
                                    yang_models + '/standard/mef/src/model/draft', '--removedup', 'True'],
                                   stdout=subprocess.PIPE)
        out, err = process.communicate()
        process_data(out, sdo_list, yang_models + '/standard/mef/src/model/draft', 'MEF draft')

        # Openconfig is from different repo that s why we need models in github zero
        LOGGER.info('Cloning the repo')
        repo = repoutil.RepoUtil('https://github.com/openconfig/public')
        repo.clone(config_name, config_email)

        process = subprocess.Popen(['python', '../runYANGallstats/runYANGallstats.py', '--rootdir',
                                    repo.localdir + '/release/models', '--removedup', 'True'], stdout=subprocess.PIPE)
        out, err = process.communicate()
        process_data(out, sdo_list, repo.localdir + '/release/models', 'openconfig')
        repo.remove()

        context = {'table_sdo': sdo_list,
                   'table_vendor': vendor_list,
                   'num_yang_files_vendor': vendor_modules,
                   'num_yang_files_vendor_ndp': vendor_modules_ndp,
                   'num_yang_files_standard': standard_modules,
                   'num_yang_files_standard_ndp': standard_modules_ndp,
                   'num_parsed_files': all_modules_data,