# Openflow Gdrive Setup

> Interactive setup for OpenFlow Google Drive demo. Prompts for missing config, creates infrastructure, writes to manifest.

- Skill: `snowflake-labs/openflow-gdrive-setup` (Agent Skill)
- Install (CLI): `npx skillmds@latest add snowflake-labs/openflow-gdrive-setup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/snowflake-labs/openflow-gdrive-setup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: snowflake-labs (https://skillmd.com/u/snowflake-labs)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/snowflake-labs/openflow-gdrive-setup

---


# 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`
- `ACCOUNTADMIN` or equivalent role for creating EAI/network rules

## Workflow

### Step 1: Resolve Config (manifest → env → prompt)

```bash
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

```bash
snow connection test -c $CONNECTION
```

**If fails:** Stop — user must fix their Snowflake connection.

### Step 3: Verify Role and Warehouse

```bash
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:

```bash
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:

```bash
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` (or `EGRESS_RULE` if no prefix)
- EAI name: `{PREFIX}_OPENFLOW_EAI` (or `OPENFLOW_EAI` if 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
```

