mirror of http://localhost:9400/cloud/cms
				
				
				
			
							parent
							
								
									81a72b882a
								
							
						
					
					
						commit
						bc84ad79d5
					
				@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					from . import plugins, secure, auth
 | 
				
			||||||
@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					import typer
 | 
				
			||||||
 | 
					from typing_extensions import Annotated
 | 
				
			||||||
 | 
					from typing import Optional
 | 
				
			||||||
 | 
					from typing import Tuple
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					import plugin_ix as px
 | 
				
			||||||
 | 
					from enum import Enum
 | 
				
			||||||
 | 
					import pandas as pd
 | 
				
			||||||
 | 
					from rich.table import Table
 | 
				
			||||||
 | 
					from rich import print
 | 
				
			||||||
 | 
					import uuid
 | 
				
			||||||
 | 
					import cms
 | 
				
			||||||
 | 
					import requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FAILED = '[ [red] \u2717 [/red] ]'
 | 
				
			||||||
 | 
					PASSED = '[ [green] \u2713 [/green] ]'
 | 
				
			||||||
 | 
					cli = typer.Typer()
 | 
				
			||||||
 | 
					@cli.command(name="set")
 | 
				
			||||||
 | 
					def set_auth (
 | 
				
			||||||
 | 
					        id:Annotated[str,typer.Argument(help="identifier used in setting cookies")],
 | 
				
			||||||
 | 
					        manifest:Annotated[str,typer.Argument(help="path manifest or site folder")],
 | 
				
			||||||
 | 
					        registry:Annotated[str,typer.Argument(help="path to the registry created by plugin-ix")],
 | 
				
			||||||
 | 
					        authpath:Annotated[str,typer.Argument(help="Authentication file location, that contains the authentication model")]
 | 
				
			||||||
 | 
					         ):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    This function will set login configuration to a manifest
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        _args   = {"id":id,"registry":registry,"path":authpath,"authorization":{}}
 | 
				
			||||||
 | 
					        path    = cms.engine.config.get_manifest(manifest=manifest)
 | 
				
			||||||
 | 
					        _config = cms.engine.config.get(path)
 | 
				
			||||||
 | 
					        _config['system']['source'] = {'secure':_args}
 | 
				
			||||||
 | 
					        _secEngine = cms.secure.Manager(config=_config)
 | 
				
			||||||
 | 
					        cms.engine.config.write(config=_config,path=path)
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        print (f"""{FAILED} [bold][red]{id}, failed [/red][/bold], error found {str(e)}""")
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # we should try to test this configuration to see if it works
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					def permissions():
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					def inspect ():
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					@cli.command("drop")
 | 
				
			||||||
 | 
					def remove (manifest:Annotated[str,typer.Argument(help="path manifest or site folder")]):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    This function removes login configuration from a manifest
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    path = cms.engine.config.get_manifest(manifest=manifest)
 | 
				
			||||||
 | 
					    _config = cms.engine.config.get(path)
 | 
				
			||||||
 | 
					    _msg = f'{FAILED}'
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        if 'secure' in _config['system']['source'] :
 | 
				
			||||||
 | 
					            del _config['system']['source']['secure']
 | 
				
			||||||
 | 
					            cms.engine.config.write(config=_config,path=path)
 | 
				
			||||||
 | 
					            _msg = f'{PASSED} [green]Successfully[/green] removed secure attribute'
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        _msg = f'{_msg}, error found {str(e)}'
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    print (_msg)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					@cli.command(name="template")
 | 
				
			||||||
 | 
					def gen_auth (
 | 
				
			||||||
 | 
					        _model:Annotated[str,typer.Argument(help="generate an authentication parameter file")],
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    This function generates a template login file content for a model (pam, oauth2, nextcloud)
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    _conf = {"method":_model}
 | 
				
			||||||
 | 
					    _map = {"pam":{"age":3600},"nextcloud":{"url":"https://your-nextcloud-site"}}
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # parameters client_id, client-secret, 
 | 
				
			||||||
 | 
					    _map["oauth2"] = {"client_id":"client_id","client_secret":"client_secret","scope":"profile","response_type":"code","authorization_url":"authorization_url","redirect_uri":"redirect_uri"}
 | 
				
			||||||
 | 
					    if _model in _map :
 | 
				
			||||||
 | 
					        _conf = dict(_conf, **_map.get(_model))
 | 
				
			||||||
 | 
					        print (_conf)
 | 
				
			||||||
 | 
					        print ()
 | 
				
			||||||
 | 
					        print(f'{PASSED} [bold] Edit[/bold] and [bold]save[/bold] the content into an [bold]"authentication file"[/bold]')
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        print (f"""{FAILED} [bold]{_model}[/bold] is not a supported authentication model""")
 | 
				
			||||||
@ -0,0 +1,207 @@
 | 
				
			|||||||
 | 
					import typer
 | 
				
			||||||
 | 
					from typing_extensions import Annotated
 | 
				
			||||||
 | 
					from typing import Optional
 | 
				
			||||||
 | 
					from typing import Tuple
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					import plugin_ix as px
 | 
				
			||||||
 | 
					from enum import Enum
 | 
				
			||||||
 | 
					import pandas as pd
 | 
				
			||||||
 | 
					from rich.table import Table
 | 
				
			||||||
 | 
					from rich import print
 | 
				
			||||||
 | 
					import cms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FAILED = '[ [red] \u2717 [/red] ]'
 | 
				
			||||||
 | 
					PASSED = '[ [green] \u2713 [/green] ]'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					Handling cli interface for plugins, performing add list and remove
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cli = typer.Typer()
 | 
				
			||||||
 | 
					def to_Table(df: pd.DataFrame):
 | 
				
			||||||
 | 
					    """Displays a Pandas DataFrame as a rich table."""
 | 
				
			||||||
 | 
					    table = Table(show_header=True, header_style="bold magenta")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for col in df.columns:
 | 
				
			||||||
 | 
					        table.add_column(col)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for _, row in df.iterrows():
 | 
				
			||||||
 | 
					        table.add_row(*row.astype(str).tolist())
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # console.print(table)
 | 
				
			||||||
 | 
					    return table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# def cms.get_manifest (manifest):
 | 
				
			||||||
 | 
					#     if not manifest.endswith('json') and os.path.isdir(manifest):
 | 
				
			||||||
 | 
					#         manifest = manifest if not manifest.endswith(os.sep) else os.sep.join(manifest.split(os.sep)[:-1])
 | 
				
			||||||
 | 
					#         path =  os.sep.join([manifest,'qcms-manifest.json'])
 | 
				
			||||||
 | 
					#     else:
 | 
				
			||||||
 | 
					#         path =  manifest
 | 
				
			||||||
 | 
					#     return path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# def get_config(path,key=None):
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					#     f = open(path)
 | 
				
			||||||
 | 
					#     _config = json.loads(f.read())
 | 
				
			||||||
 | 
					#     f.close()
 | 
				
			||||||
 | 
					#     return _config[key] if key and key in _config else _config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def format(file,_content):
 | 
				
			||||||
 | 
					    return [{'file':file.replace('.py',''),'uri':f'api/{file.replace(".py","")}/{_name}','endpoint':_name} for _name in _content]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get (manifest:Annotated[str,typer.Argument(help="project folder or manifest file")],):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    List the plugins in the from a project folder (from the manifest)    
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    path    = cms.engine.config.get_manifest(manifest=manifest) #
 | 
				
			||||||
 | 
					    _config = cms.engine.config.get(path) #get_config(path)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    _root  = _config['layout']['root']
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # remove the manifest file to pull the plugins folder
 | 
				
			||||||
 | 
					    folder  = os.sep.join([path.replace('qcms-manifest.json','')[:-1],f'{_root}/_plugins'])
 | 
				
			||||||
 | 
					    loader = px.Loader ()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    _api = []
 | 
				
			||||||
 | 
					    for _name in os.listdir(folder):
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        _file =   os.sep.join([folder,_name])
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            loader.load(file=_file)
 | 
				
			||||||
 | 
					            _api+= format(_name,loader.names())
 | 
				
			||||||
 | 
					            # _ondisk[_name] = loader.names()
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            # If the file has an error, it will be skipped
 | 
				
			||||||
 | 
					            print (e)
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # at this point we know what we have on disk, we should be able to make a report/dashboard of sorts
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    # On disk
 | 
				
			||||||
 | 
					    # files = os.listdir(folder)
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    _online = []
 | 
				
			||||||
 | 
					    _plugins = _config['plugins']
 | 
				
			||||||
 | 
					    for _name in _plugins :
 | 
				
			||||||
 | 
					        _online += format(_name, _plugins[_name])
 | 
				
			||||||
 | 
					    return _api,_online
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StatusFilter(str,Enum):
 | 
				
			||||||
 | 
					    online="online"
 | 
				
			||||||
 | 
					    offline="offline"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@cli.command(name="status")
 | 
				
			||||||
 | 
					def status(manifest:Annotated[str,typer.Argument(help="project folder or manifest file")],
 | 
				
			||||||
 | 
					           filter : StatusFilter = None
 | 
				
			||||||
 | 
					           ):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    This function will provide the status of all available plugins
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    _avail,_depl = get(manifest)
 | 
				
			||||||
 | 
					    _avail = pd.DataFrame(_avail)# available on disk (not deployed)
 | 
				
			||||||
 | 
					    _depl = pd.DataFrame(_depl) # deployed
 | 
				
			||||||
 | 
					    files = _avail.file.unique().tolist()+ _depl.file.unique().tolist()
 | 
				
			||||||
 | 
					    _df = pd.DataFrame()
 | 
				
			||||||
 | 
					    for _name in files :
 | 
				
			||||||
 | 
					        _xe = _avail[_avail.file == _name].endpoint.tolist()  
 | 
				
			||||||
 | 
					        _ye = _depl[_depl.file == _name].endpoint.tolist()
 | 
				
			||||||
 | 
					        _online = list(set(_xe) & set(_ye))
 | 
				
			||||||
 | 
					        _offline = list(set(_xe) - set(_ye))
 | 
				
			||||||
 | 
					        _data = pd.DataFrame()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        _data['api']    = _offline + _online
 | 
				
			||||||
 | 
					        _data['file']       = _name
 | 
				
			||||||
 | 
					        _data['status'] = (['[red]offline[/red]']* len(_offline)) + (['[green]online[/green]']* len(_online))
 | 
				
			||||||
 | 
					        # _data['deployed'] = _online
 | 
				
			||||||
 | 
					        _data = _data[['file','api','status']]
 | 
				
			||||||
 | 
					        _df = pd.concat([_df, _data])
 | 
				
			||||||
 | 
					        # _df.append({'file':_name,'deployed':_online,'offline':_offline})
 | 
				
			||||||
 | 
					    _df['uri'] = _df.apply(lambda row: f'api/{row.file}/{row.api}',axis=1)
 | 
				
			||||||
 | 
					    _df = _df[['file','uri','api','status']]
 | 
				
			||||||
 | 
					    if filter :
 | 
				
			||||||
 | 
					        print (f"status in ('{filter.value}')")
 | 
				
			||||||
 | 
					        _df = _df[_df.status.str.contains(filter.value, case=False, regex=True)]
 | 
				
			||||||
 | 
					        # _df = _df.query(f" '{filter.value}' in status")
 | 
				
			||||||
 | 
					    print (to_Table(_df))
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					           
 | 
				
			||||||
 | 
					@cli.command(name="register")
 | 
				
			||||||
 | 
					def add (manifest:Annotated[str,typer.Argument(help="project folder or manifest file")],
 | 
				
			||||||
 | 
					         pointer:Annotated[str,typer.Argument(help="file/function or file.function with no file extension. e.g: demo/info")]
 | 
				
			||||||
 | 
					         ):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    This function will add a plugin function to the site's configuration file making it available as an API
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # Let's make sure we are adding to the configuration something that actually exists
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    _file,_name = pointer.split('/')
 | 
				
			||||||
 | 
					    path    = cms.engine.config.get_manifest(manifest=manifest) #
 | 
				
			||||||
 | 
					    _config = cms.engine.config.get(path) #get_config(path)    
 | 
				
			||||||
 | 
					    _root  = _config['layout']['root']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _folder  = os.sep.join([path.replace('qcms-manifest.json','')[:-1],f'{_root}/_plugins'])
 | 
				
			||||||
 | 
					    if f'{_file}.py' in os.listdir(_folder) :
 | 
				
			||||||
 | 
					        loader = px.Loader ()
 | 
				
			||||||
 | 
					        loader.load(file=f'{_folder}{os.sep}{_file}.py')
 | 
				
			||||||
 | 
					        if loader.has(_name) :
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            # adding to plugins
 | 
				
			||||||
 | 
					            _plugins = _config['plugins']
 | 
				
			||||||
 | 
					            if _file not in _plugins :
 | 
				
			||||||
 | 
					                _plugins[_file] = []
 | 
				
			||||||
 | 
					            if _name not in _plugins[_file] :
 | 
				
			||||||
 | 
					                _plugins[_file].append (_name)
 | 
				
			||||||
 | 
					                _config['plugins'] = _plugins
 | 
				
			||||||
 | 
					                cms.engine.config.write(config=_config,path=path)
 | 
				
			||||||
 | 
					                _msg = f"{PASSED} [bold]{pointer}[/bold] successfully added to {manifest}\nAPI endpoint [bold]api/{_file}/{_name}[/bold]"
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                _msg = f"{FAILED} [bold]{pointer}[/bold] [red]already exists[/red] in  configuration"
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            # failure at this point, asking for a function in a file that doesn't exist
 | 
				
			||||||
 | 
					            _msg = f"[bold]{pointer}[/bold] [red]{_name} missing[/red] in {_folder}{os.sep}{_file}.py"
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        # throw/raise an exception 
 | 
				
			||||||
 | 
					        _msg = f"{FAILED} [bold]{pointer}[/bold] [red]NOT found[/red] in {_folder}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print (_msg)
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					@cli.command(name="unregister")
 | 
				
			||||||
 | 
					def remove(manifest:Annotated[str,typer.Argument(help="project folder or manifest file")],
 | 
				
			||||||
 | 
					         pointer:Annotated[str,typer.Argument(help="file/function or file.function with no file extension. e.g: demo/info")]
 | 
				
			||||||
 | 
					         ):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    This function will remove an api from the configuration of a project and won't be available via http/https
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    _file,_name = pointer.split('/')
 | 
				
			||||||
 | 
					    path    = cms.engine.config.get_manifest(manifest=manifest) #
 | 
				
			||||||
 | 
					    _config = cms.engine.config.get(path) #get_config(path)    
 | 
				
			||||||
 | 
					    _root  = _config['layout']['root']
 | 
				
			||||||
 | 
					    _plugins = _config.get('plugins',{})
 | 
				
			||||||
 | 
					    if _file in _plugins :
 | 
				
			||||||
 | 
					        _plugins[_file] = [_fname for _fname in _plugins[_file] if _fname != _name]
 | 
				
			||||||
 | 
					        _config['plugins'] = _plugins
 | 
				
			||||||
 | 
					        _msg = f"{PASSED} [bold]{pointer}[/bold] was [green]successfully[/green] removed from {path}"
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        _msg = f"{FAILED} [bold]{pointer}[/bold] was [red]NOT found[/red] in {path}"
 | 
				
			||||||
 | 
					    print (_msg)
 | 
				
			||||||
 | 
					    cms.engine.config.write(_config,path)
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					# def post(config,path):
 | 
				
			||||||
 | 
					#     f = open(path,'w')
 | 
				
			||||||
 | 
					#     f.write(json.dumps(config,indent=4))
 | 
				
			||||||
 | 
					#     f.close()
 | 
				
			||||||
@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					This file will handle security aspects associated with QCMS
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import typer
 | 
				
			||||||
 | 
					from typing_extensions import Annotated
 | 
				
			||||||
 | 
					from typing import Optional
 | 
				
			||||||
 | 
					from typing import Tuple
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					import plugin_ix as px
 | 
				
			||||||
 | 
					from enum import Enum
 | 
				
			||||||
 | 
					import pandas as pd
 | 
				
			||||||
 | 
					from rich.table import Table
 | 
				
			||||||
 | 
					from rich import print
 | 
				
			||||||
 | 
					import uuid
 | 
				
			||||||
 | 
					import cms
 | 
				
			||||||
 | 
					import requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FAILED = '[ [red] \u2717 [/red] ]'
 | 
				
			||||||
 | 
					PASSED = '[ [green] \u2713 [/green] ]'
 | 
				
			||||||
 | 
					cli = typer.Typer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@cli.command(name="set-key")
 | 
				
			||||||
 | 
					def set_key (manifest:Annotated[str,typer.Argument(help="path to manifest or manifest folder")],
 | 
				
			||||||
 | 
					            keyfile:Annotated[str,typer.Argument(help="path of the key file to generate")]
 | 
				
			||||||
 | 
					            ):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    force-reload of an application
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    keyfile = cms.engine.config.get_manifest(keyfile)
 | 
				
			||||||
 | 
					    if not os.path.exists(keyfile):
 | 
				
			||||||
 | 
					        f = open(keyfile,'w')
 | 
				
			||||||
 | 
					        f.write(str(uuid.uuid4()))
 | 
				
			||||||
 | 
					        f.close()
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        manifest = cms.engine.config.get_manifest(manifest)
 | 
				
			||||||
 | 
					        _config = cms.engine.config.get(manifest)
 | 
				
			||||||
 | 
					        if 'source' not in _config['system']:
 | 
				
			||||||
 | 
					            _config['system']['source'] = {'id':'disk'}
 | 
				
			||||||
 | 
					        _config['system']['source']['key'] = os.path.abspath(keyfile)
 | 
				
			||||||
 | 
					        cms.engine.config.write(_config,manifest)
 | 
				
			||||||
 | 
					        _msg = f"""{PASSED} [bold]{_config['layout']['header']['title']}[/bold] : A key was generated and written to {keyfile}
 | 
				
			||||||
 | 
					            use this key in header to enable reload of the site ...
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        _msg = f"""{FAILED} [bold]{_config['system']['layout']['header']['title']}[/bold] : could [bold]NOT[/bold] generate a key, because it would seem you already have one
 | 
				
			||||||
 | 
					            Please manually delete {keyfile}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					    print (_msg)
 | 
				
			||||||
 | 
					@cli.command (name='reload')
 | 
				
			||||||
 | 
					def reload (
 | 
				
			||||||
 | 
					    path:Annotated[str,typer.Argument(help="")],
 | 
				
			||||||
 | 
					    port:int=typer.Option(default=None,help="port of the host to call")
 | 
				
			||||||
 | 
					    ) :
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Reload a site/portal given the manifest ...
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    path = cms.engine.config.get_manifest(path)
 | 
				
			||||||
 | 
					    _config = cms.engine.config.get( path)
 | 
				
			||||||
 | 
					    if 'source' in _config['system'] and 'key' in _config['system']['source'] :
 | 
				
			||||||
 | 
					        _spath = _config['system']['source']['key']
 | 
				
			||||||
 | 
					        # f = open(_config['system']['source']['key'])
 | 
				
			||||||
 | 
					        if not os.path.exists(_spath) :
 | 
				
			||||||
 | 
					            mpath = path.split(os.sep)[:-1] + _spath.split(os.sep)
 | 
				
			||||||
 | 
					            _spath = os.sep.join(mpath)
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        f  = open(_spath)
 | 
				
			||||||
 | 
					        key = f.read()
 | 
				
			||||||
 | 
					        f.close()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        _port = port if port else _config['system']['app']['port']
 | 
				
			||||||
 | 
					        url = f"http://localhost:{_port}/reload"
 | 
				
			||||||
 | 
					        resp = requests.post(url, headers={"key":key})
 | 
				
			||||||
 | 
					        if resp.status_code == 200 :
 | 
				
			||||||
 | 
					            _msg = f"""{PASSED} [bold]{_config['layout']['header']['title']}[/bold] : successfully reloaded {url}"""
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            _msg = f"""{FAILED} failed to reload, status code {resp.status_code}\n{url}
 | 
				
			||||||
 | 
					            """
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        _msg = f"""{FAILED} no secure key found in manifest to request reload"""
 | 
				
			||||||
 | 
					    print (_msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue