OpenFlow Google Drive — Setup
Interactive setup that prompts for all missing config and provisions infrastructure.
When to Load
Parent SKILL.md routes here on: "setup", "provision", "configure", "first time", "initialize"
Prerequisites
- Snowflake connection configured in
manifest.toml [snowflake].connection ACCOUNTADMINor equivalent role for creating EAI/network rules
Workflow
Step 1: Resolve Config (manifest → env → prompt)
eval $(python3 -c "
import tomllib, os
m = tomllib.load(open('.sfutils/manifest.toml', 'rb'))
o = m.get('openflow', {})
rt = o.get('runtime', {})
src = o.get('source', {}).get('gdrive', {})
s = m.get('snowflake', {})
print(f'CONNECTION={s.get(\"connection\", os.environ.get(\"SNOWFLAKE_DEFAULT_CONNECTION_NAME\", \"\"))}')
print(f'DATABASE={o.get(\"database\", os.environ.get(\"OPENFLOW_DATABASE\", \"\"))}')
print(f'SCHEMA={o.get(\"schema\", os.environ.get(\"OPENFLOW_SCHEMA\", \"\"))}')
print(f'ROLE={o.get(\"role\", os.environ.get(\"OPENFLOW_ROLE\", \"\"))}')
print(f'WAREHOUSE={o.get(\"warehouse\", os.environ.get(\"OPENFLOW_WAREHOUSE\", \"\"))}')
print(f'RUNTIME={rt.get(\"name\", os.environ.get(\"OPENFLOW_RUNTIME\", \"\"))}')
print(f'EAI={o.get(\"eai\", os.environ.get(\"OPENFLOW_EAI\", \"\"))}')
print(f'DRIVE_ID={src.get(\"drive_id\", os.environ.get(\"GDRIVE_DRIVE_ID\", \"\"))}')
print(f'FOLDER_NAME={src.get(\"folder_name\", os.environ.get(\"GDRIVE_FOLDER_NAME\", \"\"))}')
print(f'GCP_CRED={src.get(\"credential_path\", os.environ.get(\"GCP_CREDENTIAL_PATH\", \"~/.snowflake/cortex/secrets/gcp-service-account.json\"))}')
")
For each empty value, use ask_user_question showing the env var value (if set) as the default option.
⚠️ MANDATORY STOP: Present all resolved values and wait for user confirmation before proceeding.
Step 2: Verify Connection
snow connection test -c $CONNECTION
If fails: Stop — user must fix their Snowflake connection.
Step 3: Verify Role and Warehouse
snow sql -q "SHOW ROLES LIKE '$ROLE'" -c $CONNECTION --format json
snow sql -q "SHOW WAREHOUSES LIKE '$WAREHOUSE'" -c $CONNECTION --format json
If role/warehouse missing: Inform user and stop.
Step 4: Verify Runtime and Profile
The bootstrap skill already ran $openflow setup. Read runtime metadata from its cache:
cat ~/.snowflake/cortex/memory/openflow_infrastructure_${CONNECTION}.json | jq '{
runtime: .deployments[0].runtimes[0].runtime_name,
role: .deployments[0].runtimes[0].execute_as_role,
profile: .deployments[0].runtimes[0].nipyapi_profile
}'
If cache is empty or missing, invoke $openflow with "setup" intent to re-discover.
Step 5: Verify or Create EAI
Check if EAI exists in the manifest ([openflow].eai). If set, verify it's enabled:
snow sql -q "DESCRIBE INTEGRATION $EAI" -c $CONNECTION --format json
If EAI exists and enabled: Proceed to Step 6.
If EAI missing: STOP. Invoke $sfutils:network-rule with:
- Type: EGRESS
- Hosts:
googleapis.com,www.googleapis.com,oauth2.googleapis.com,accounts.google.com - Rule name:
{PREFIX}_EGRESS_RULE(orEGRESS_RULEif no prefix) - EAI name:
{PREFIX}_OPENFLOW_EAI(orOPENFLOW_EAIif no prefix) - Database/Schema:
OPENFLOW_DEMOS.NETWORKS - Grant USAGE to:
OPENFLOW_DEMOS_ROLE - Manifest path:
.sfutils/manifest.toml
Do NOT write SQL for EAI/NW creation. Wait for the skill to confirm.
Then ask user to attach EAI to runtime via Snowsight.
Step 6: Write Config to Manifest
The $sfutils:network-rule and $sfutils:programmatic-access-token skills write their own sections. Write remaining config values to .sfutils/manifest.toml:
[openflow].database[openflow].schema[openflow].role[openflow].warehouse[openflow].connector_flow = "unstructured-google-drive-cdc-no-dwd"[openflow.source.gdrive].drive_id[openflow.source.gdrive].folder_name
Step 7: Verify PAT
Check if [pat.openflow-runner] exists and is COMPLETE in manifest.
| Result | Action |
|---|---|
| COMPLETE | Setup done -- PAT exists |
| MISSING | STOP. Invoke $sfutils:programmatic-access-token (see bootstrap Step 8 for params) |
Do NOT write PAT SQL manually.
Stopping Points
- ✋ After Step 1: user must confirm config values
- ✋ If runtime not found: user must create via $openflow or Snowsight
- ✋ If EAI missing: user must create
Output
Setup complete!
Connection: $CONNECTION
Database: $DATABASE.$SCHEMA
Runtime: $RUNTIME (ACTIVE)
Profile: $PROFILE
EAI: $EAI
PAT: $SA_USER (COMPLETE)
Manifest: .sfutils/manifest.toml updated