railiance-platform/tests/test_argocd_adoption_proof.py
codex 725d126c77 Prove pinned OpenBao ArgoCD adoption with deterministic native checks
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 21:30:47 +02:00

143 lines
10 KiB
Python

import copy
from datetime import datetime, timezone, timedelta
import importlib.util
from pathlib import Path
import unittest
from unittest import mock
SPEC=importlib.util.spec_from_file_location('adoption',Path(__file__).parents[1]/'scripts/argocd_adoption_proof.py')
p=importlib.util.module_from_spec(SPEC);SPEC.loader.exec_module(p)
NOW=datetime(2026,10,11,20,tzinfo=timezone.utc)
def fixture():
return {'captured_at':NOW.isoformat(),'estate_ip':'92.205.62.239',
'tracking_settings':{'method':'annotation','controller_version':'v3.5.3','installation_id_absent':True,'instance_label_key':'app.kubernetes.io/instance'},
'application':{'name':'openbao-secretstore','uid':'app-uid','project':p.CONTRACT['project'],'destination':p.CONTRACT['destination'],
'source':{'repoURL':p.CONTRACT['repo_url'],'path':p.CONTRACT['source_path'],'targetRevision':p.PIN},
'revision':p.PIN,'automated_present':False,'pending_operation':False,'sync':'Synced','health':'Healthy',
'condition_types':['OrphanedResourceWarning'],'sync_prune':False,'sync_strategy_apply':True,
'operation_revision':p.PIN,'operation':{'phase':'Succeeded','startedAt':'2026-09-21T17:09:16Z','finishedAt':'2026-09-21T17:09:18Z'},
'resources':[dict(p.CONTRACT['resources'][0],status='Synced')]},
'ready_checks':[{'kind':c['kind'],'namespace':c['namespace'],'name':c['name'],'uid':'resource-uid',
'ready':[{'status':'True','lastTransitionTime':'2026-08-19T19:49:59Z'}],
'tracking_matches':True if 'tracking_id' in c else None} for c in p.CONTRACT['ready_checks']],
'pinned_render_diff':{'revision':p.PIN,'path':p.CONTRACT['source_path'],'exit_code':0,'render_resource_count':1,'render_sha256':'a'*64,
'client_side_exit_code':0,'normalized_render_sha256':'b'*64,'same_api_version':True,
'normalization':'argocd-v3-annotation-tracking-destination-namespace',
'tracking_settings':{'method':'annotation','controller_version':'v3.5.3','installation_id_absent':True,'instance_label_key':'app.kubernetes.io/instance'},
'normalized_client_changed_paths':[],'normalized_server_changed_paths':[],
'raw_client_exit_code':1,'raw_server_exit_code':1,
'raw_client_changed_paths':['/metadata/annotations/argocd.argoproj.io~1tracking-id','/metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration'],
'raw_server_changed_paths':['/metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration']}}
class ProofTest(unittest.TestCase):
def test_complete_fixture_passes(self):
self.assertEqual(p.verify(fixture(),p.CONTRACT,now=NOW)['status'],'verified')
def test_wrong_estate_stale_future_or_missing_observation_refused(self):
for values in [{'estate_ip':'other'},{'captured_at':(NOW-timedelta(minutes=6)).isoformat()},
{'captured_at':(NOW+timedelta(seconds=1)).isoformat()},{'captured_at':'2026-10-11'}]:
with self.subTest(values=values), self.assertRaises(ValueError):
p.verify(fixture()|values,p.CONTRACT,now=NOW)
def test_exact_pin_project_source_policy_and_health_refusals(self):
for key,value in [('revision','b'*40),('destination',{'server':'other'}),('project','other'),('automated_present',True),
('pending_operation',True),('sync','OutOfSync'),('health','Degraded'),
('condition_types',['ComparisonError']),('sync_prune',True),
('sync_strategy_apply',False),('operation_revision','b'*40),
('source',{'repoURL':'different'})]:
data=fixture();data['application'][key]=value
with self.subTest(key=key),self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
def test_extra_duplicate_missing_or_wrong_tracked_resources_refused(self):
for resources in [[],[p.CONTRACT['resources'][0]]*2,
[dict(p.CONTRACT['resources'][0],name='another',status='Synced')],
[dict(p.CONTRACT['resources'][0],status='OutOfSync')]]:
data=fixture();data['application']['resources']=resources
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
def test_proving_period_and_nonmonotonic_operation_refusals(self):
for operation in [{'phase':'Succeeded','startedAt':NOW.isoformat(),'finishedAt':NOW.isoformat()},
{'phase':'Failed','startedAt':'2026-09-21T17:09:16Z','finishedAt':'2026-09-21T17:09:18Z'},
{'phase':'Succeeded','startedAt':'2026-09-22T17:09:16Z','finishedAt':'2026-09-21T17:09:18Z'}]:
data=fixture();data['application']['operation']=operation
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
def test_readiness_tracking_and_incomplete_health_refusals(self):
for key,value in [('tracking_matches',False),('ready',[]),
('ready',[{'status':'False','lastTransitionTime':'2026-08-19T19:49:59Z'}]),
('ready',[{'status':'True','lastTransitionTime':'2026-10-11T19:49:59Z'}])]:
data=fixture();data['ready_checks'][0][key]=value
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
data=fixture();data['ready_checks']=[]
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
def test_nonzero_wrong_pin_missing_or_invalid_diff_refusals(self):
for key,value in [('exit_code',1),('exit_code',2),('revision','b'*40),
('render_resource_count',2),('render_sha256','wrong'),('client_side_exit_code',1),
('exit_code',False),('same_api_version',False),('normalization','unknown'),
('normalized_client_changed_paths',['/spec/provider']),
('normalized_server_changed_paths',['/metadata/labels/unknown']),
('raw_client_changed_paths',['unknown']),('raw_server_changed_paths',['/spec/provider'])]:
data=fixture();data['pinned_render_diff'][key]=value
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
data=fixture();del data['pinned_render_diff']
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
def test_subprocess_failure_and_timeout_do_not_leak_output(self):
import subprocess
from types import SimpleNamespace
secret='CANARY-DO-NOT-EMIT'
with mock.patch.object(p.subprocess,'run',return_value=SimpleNamespace(returncode=1,stdout=secret,stderr=secret)):
with self.assertRaises(RuntimeError) as exc:p.checked_run(['kubectl','get','nodes'])
self.assertNotIn(secret,str(exc.exception))
with mock.patch.object(p.subprocess,'run',side_effect=subprocess.TimeoutExpired('cmd',1,output=secret,stderr=secret)):
with self.assertRaises(RuntimeError) as exc:p.checked_run(['kubectl','get','nodes'])
self.assertNotIn(secret,str(exc.exception))
def test_argo_tracking_injection_preserves_source_spec_and_annotations(self):
source={'apiVersion':'external-secrets.io/v1beta1','kind':'ClusterSecretStore',
'metadata':{'name':'openbao','annotations':{'source-owned':'preserve'}},
'spec':{'provider':{'vault':{'path':'platform'}}}}
original=copy.deepcopy(source)
settings=fixture()['tracking_settings']
desired=p.argo_desired(source,p.CONTRACT,settings)
self.assertEqual(source,original)
self.assertEqual(desired['spec'],source['spec'])
self.assertEqual(desired['metadata']['annotations']['source-owned'],'preserve')
self.assertEqual(desired['metadata']['annotations']['argocd.argoproj.io/tracking-id'],
'openbao-secretstore:external-secrets.io/ClusterSecretStore:external-secrets/openbao')
self.assertNotIn('labels',desired['metadata'])
def test_unknown_tracking_semantics_conflicting_id_or_secret_render_refused(self):
source={'apiVersion':'external-secrets.io/v1beta1','kind':'ClusterSecretStore','metadata':{'name':'openbao'}}
settings=fixture()['tracking_settings']
for delta in [{'method':'label'},{'controller_version':'unknown'},{'installation_id_absent':False}]:
with self.assertRaises(ValueError):p.argo_desired(source,p.CONTRACT,settings|delta)
for delta in [{'kind':'Secret'},{'apiVersion':'external-secrets.io/v1'},
{'metadata':{'name':'openbao','namespace':'external-secrets'}},
{'metadata':{'name':'openbao','annotations':{'argocd.argoproj.io/tracking-id':'foreign-owner'}}}]:
with self.assertRaises(ValueError):p.argo_desired(source|delta,p.CONTRACT,settings)
def test_changed_paths_preserve_unknown_fields_and_never_expose_values(self):
before={'metadata':{'annotations':{'x/y~z':'CANARY-PRIVATE'}},'spec':{'path':'old'}}
after={'metadata':{'annotations':{'x/y~z':'OTHER-PRIVATE'}},'spec':{'path':'new'}}
paths=p.changed_paths(before,after)
self.assertEqual(paths,['/metadata/annotations/x~1y~0z','/spec/path'])
self.assertNotIn('CANARY',str(paths))
self.assertNotIn('PRIVATE',str(paths))
def test_runtime_tracking_and_diagnostic_integrity_refusals(self):
for delta in [{'method':'label'},{'controller_version':'v2.14.0'},{'installation_id_absent':False}]:
data=fixture();data['tracking_settings'].update(delta)
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
for delta in [{'raw_client_changed_paths':None},{'raw_client_exit_code':0},
{'raw_server_changed_paths':['unknown']},{'raw_server_exit_code':2}]:
data=fixture();data['pinned_render_diff'].update(delta)
with self.assertRaises(ValueError):p.verify(data,p.CONTRACT,now=NOW)
def test_secret_read_contract_is_rejected(self):
contract=copy.deepcopy(p.CONTRACT);contract['ready_checks'][0]['kind']='Secret'
with self.assertRaises(ValueError):p.validate_contract(contract)