Setting the file. One moment.
Blob Observation · Foundry Iq · microsoft/azure-skills · Skills Docs
ContentsBack to the top of the page File Cu Canary
helpers/ _blob_observation.py
Python · 83 lines · 4 KB
10
11
12 FIELDS = frozenset (( "name" , "type" , "container" , "identity" , "description" ,
13 "dataChangeDetectionPolicy" , "dataDeletionDetectionPolicy" , "encryptionKey" ,
14 "fields" , "scoringProfiles" , "defaultScoringProfile" , "corsOptions" ,
15 "suggesters" , "analyzers" , "normalizers" , "tokenizers" , "tokenFilters" ,
16 "charFilters" , "similarity" , "semantic" , "vectorSearch" ,
17 "skills" , "cognitiveServices" , "knowledgeStore" , "indexProjections" ,
18 "dataSourceName" , "targetIndexName" , "skillsetName" , "parameters" ,
19 "fieldMappings" , "outputFieldMappings" , "cache" , "disabled" ))
20 PROJECTION_FIELDS = { "core_digest" , "field_digests" }
21
22
23 def observe (child, kind):
24 excluded = { "@odata.etag" }
25 if kind == "datasource" :
26 excluded.add( "credentials" )
27 if kind == "indexer" :
28 excluded.add( "schedule" )
29 core = {key: value for key, value in child.items() if key not in excluded}
30 fields = {key: digest(value) for key, value in core.items() if key in FIELDS }
31 fields[ "additionalProperties" ] = digest({key: value for key, value in core.items() if key not in FIELDS })
32 result = { "core_digest" : digest(core), "field_digests" : fields}
33 if kind == "datasource" :
34 result[ "credential_digest" ] = digest({ "present" : "credentials" in child, "value" : child.get( "credentials" )})
35 return result
36
37
38 def note (diagnostics, kind, severity, code, field, request_id):
39 indexer.note(diagnostics, severity, code, f " { kind } . { field } " ,
40 f " { kind } . { field } : { code } ; values withheld." , request_id)
41
42
43 def compare (current, expected, kind, diagnostics, request_id):
44 if current[ "digest" ] == expected[ "digest" ] and current != expected:
45 raise HelperFailure( f " { kind } -evidence-inconsistent" , "Equal full hashes have inconsistent projection evidence." ,
46 blocked_at = "verification" , request_id = request_id)
47 if current[ "core_digest" ] != expected[ "core_digest" ]:
48 fields = current[ "field_digests" ].keys() | expected[ "field_digests" ].keys()
49 for field in sorted (fields):
50 if current[ "field_digests" ].get(field) != expected[ "field_digests" ].get(field):
51 note(diagnostics, kind, "error" , "definition-drift" , field, request_id)
52 raise HelperFailure( "indexer-definition-drift" if kind == "indexer" else "definition-drift" ,
53 "Meaningful generated configuration changed; inspect child diagnostics." ,
54 blocked_at = "verification" , request_id = request_id)
55 if current[ "etag" ] != expected[ "etag" ]:
56 note(diagnostics, kind, "info" , "generated-version-changed" , "@odata.etag" , request_id)
57 if kind == "datasource" and current[ "credential_digest" ] != expected[ "credential_digest" ]:
58 note(diagnostics, kind, "warning" , "datasource-credential-projection-changed" , "credentials" , request_id)
59
60
61 def indexer_only (diagnostics):
62 return [item for item in diagnostics
63 if not item[ "field" ].startswith(( "datasource." , "indexer." , "skillset." , "index." ))]
64
65
66 def valid (value, kind, sha256):
67 fields = { "etag" , "digest" } | PROJECTION_FIELDS
68 if kind == "indexer" :
69 fields |= indexer. PROJECTION_FIELDS
70 if kind == "datasource" :
71 fields |= { "credential_digest" , "binding_proof" }
72 if not isinstance (value, dict ) or set (value) != fields:
73 return False
74 hashes = fields - { "etag" , "field_digests" , "binding_proof" }
75 return ( isinstance (value[ "etag" ], str ) and bool (value[ "etag" ].strip())
76 and all ( isinstance (value[key], str ) and sha256.fullmatch(value[key]) for key in hashes)
77 and isinstance (value[ "field_digests" ], dict )
78 and set (value[ "field_digests" ]) <= FIELDS | { "additionalProperties" }
79 and "additionalProperties" in value[ "field_digests" ]
80 and all ( isinstance (item, str ) and sha256.fullmatch(item)
81 for item in value[ "field_digests" ].values())
82 and (kind != "datasource" or isinstance (value[ "binding_proof" ], str )
83 and value[ "binding_proof" ] in { "resource-id" , "unverified" }))