"""Synthetic fixture data only; no controller inventory or real report observations.""" from pathlib import Path import json,os,time,uuid from ruamel.yaml import YAML from aim_webgui.core.protocol import COUNTS def declared(name='host_capabilities_v1',scope='per_host'): source=Path(os.environ['AIM_TEST_CORE_ROOT'])/'playbooks/schemas'/f'{name}.yml' schema=YAML(typ='safe').load(source.read_text()) return {'protocol':'aim_output_v1','schema':name,'scope':scope,'required':True,'sensitivity':'safe', 'max_bytes_per_host':1048576,'data_schema':schema} def sample(schema): t=schema['type'] if isinstance(t,list):t='null' if 'null' in t else t[0] if 'enum' in schema:return schema['enum'][0] if t=='object':return {k:sample(v) for k,v in schema['properties'].items()} if t=='array':return [] if t=='boolean':return False if t=='integer':return int(schema.get('minimum',0)) if t=='number':return float(schema.get('minimum',0)) if t=='null':return None return 'synthetic' def plan(declaration=None,hosts=None): hosts=hosts or ['test01.example'] req={'customer':'example','playbook':'debug_detect_host_roles','hosts':hosts,'overrides':{},'check':False, 'key_mode':'none','become_password':False,'timeout_seconds':30,'progress_mode':'detail'} return {'customer':'example','playbook':req['playbook'],'targets':hosts,'overrides':{},'result_contract':declaration, 'core_request':req,'core_version':'3.3.0rc8','core_api':'1.0','core_revision':'a'*64,'inventory_revision':'a'*64, 'credential_requirements':[],'authentication':{'mode':'inventory','key_mode':'none'}} def result(declaration=None,hosts=None,*,availability='available',status='succeeded',report_data=None): hosts=hosts or ['test01.example'];counts=dict.fromkeys(COUNTS,0);counts['ok']=3 report=None if declaration is not None: data=sample(declaration['data_schema']) if report_data is None else report_data entry={'schema':declaration['schema'],'status':availability,'data':data if availability=='available' else None,'error':None} report={'protocol':'aim_operation_result_v1','schema':declaration['schema'],'scope':declaration['scope'], 'required':True,'complete':availability=='available','check_mode':False, 'hosts':{h:dict(entry) for h in hosts} if declaration['scope']=='per_host' else {}, 'global':dict(entry) if declaration['scope']=='global' else None} return {'api_version':'1.0','run_id':'fixture-run','status':status,'stage':'completed' if status=='succeeded' else 'result_validation', 'exit_code':0,'remote_work_may_have_started':True,'counts':counts, 'error':None if status=='succeeded' else {'code':'operation_result_missing','message':'Required report missing','stage':'result_validation'}, 'target_summary':{'schema':'target_outcome_summary_v1','requested':len(hosts),'accounted':len(hosts), 'successful':len(hosts),'failed':0,'unreachable':0,'not_started':0,'indeterminate':0,'complete':True}, 'targets':[{'host':h,'outcome':'successful','counts':dict(counts)} for h in hosts],'operation_result':report} def job(auth,owner,p=None,*,status='running'): ident=uuid.uuid4().hex;p=p or plan() with auth.store.transaction() as db: db.execute('''INSERT INTO jobs(id,owner_id,plan,mode,status,scheduled_at,created_at) VALUES(?,?,?,?,?,?,?)''', (ident,owner,json.dumps(p),'apply',status,int(time.time()),int(time.time()))) return ident def ev(seq,kind='task_started',**extra): data={'event_version':'1.0','run_id':'fixture-run','sequence':seq,'timestamp':'2026-09-20T10:00:00Z','kind':kind} if kind=='task_started':data.update(play_id='p1',task_id='t'+str(seq),label='Synthetic task '+str(seq),label_redacted=False,handler=False) if kind=='host_result':data.update(play_id='p1',task_id='t1',host='test01.example',host_redacted=False,status='ok',changed=False,ignored=False,details_redacted=False,error=None) if kind=='stage':data['stage']='execution' data.update(extra);return data