Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ convention:
- Python >= 3.11; use modern syntax (PEP 604 unions, f-strings, `match` where appropriate).
- Linter: `ruff` (line length 99, target py311). Run `ruff check python/`.
- All new Python code should have type hints.
- Never hardcode credentials use env vars, Ansible Vault, or Terraform `sensitive`.
- Never hardcode credentials - use env vars, Ansible Vault, or Terraform `sensitive`.
- Ansible playbooks use `netapp.ontap` FQCNs with `use_rest: always`.
- Terraform modules use the `NetApp/netapp-ontap` provider `~> 2.5`.
- Every generated source file (`.py`, `.yml`, `.tf`, `.sh`, `.html`) MUST start
Expand All @@ -59,17 +59,17 @@ Exempt files: Markdown, `requirements.*`, `ansible/inventory/*`,

## ONTAP API rules

- Use ONLY ONTAP REST APIs no ZAPI, no CLI passthrough, no SSH.
- Use ONLY ONTAP REST APIs - no ZAPI, no CLI passthrough, no SSH.
- Target ONTAP 9.8+ REST endpoints.
- See `docs/ontap-api-patterns.md` for endpoints, auth, async job handling.

## Python conventions

- Import and use `python/ontap_client.py` never build a new HTTP client.
- Import and use `python/ontap_client.py` - never build a new HTTP client.
- Authenticate via `OntapClient.from_env()` (reads `ONTAP_HOST`, `ONTAP_PASS`).
- Operational params via `argparse` with env-var fallbacks.
- Async jobs: `client.poll_job(resp["job"]["uuid"])`.
- Logging via `logging` module never `print()`.
- Logging via `logging` module - never `print()`.

## Ansible conventions

Expand Down
32 changes: 16 additions & 16 deletions .github/prompts/generate-ansible.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ collection, which calls exclusively REST APIs.

Use these repository files as the authoritative source for conventions:

- [ansible/nfs_provision.yml](../../ansible/nfs_provision.yml) NFS reference implementation
- [ansible/cifs_provision.yml](../../ansible/cifs_provision.yml) CIFS reference implementation
- [ansible/group_vars/ontap.yml.example](../../ansible/group_vars/ontap.yml.example) variable defaults
- [ansible/inventory/hosts.yml](../../ansible/inventory/hosts.yml) inventory structure
- [ansible/requirements.yml](../../ansible/requirements.yml) collection version pin
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) API endpoints, auth, async jobs
- [docs/example-template/ansible/example.yml](../../docs/example-template/ansible/example.yml) skeleton
- [CONTRIBUTING.md](../../CONTRIBUTING.md) naming, CI, quality bar
- [ansible/nfs_provision.yml](../../ansible/nfs_provision.yml) - NFS reference implementation
- [ansible/cifs_provision.yml](../../ansible/cifs_provision.yml) - CIFS reference implementation
- [ansible/group_vars/ontap.yml.example](../../ansible/group_vars/ontap.yml.example) - variable defaults
- [ansible/inventory/hosts.yml](../../ansible/inventory/hosts.yml) - inventory structure
- [ansible/requirements.yml](../../ansible/requirements.yml) - collection version pin
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) - API endpoints, auth, async jobs
- [docs/example-template/ansible/example.yml](../../docs/example-template/ansible/example.yml) - skeleton
- [CONTRIBUTING.md](../../CONTRIBUTING.md) - naming, CI, quality bar

## Step 1 Clarify Inputs
## Step 1 - Clarify Inputs

Before writing YAML, identify what information is missing and ask me.
Common inputs: SVM name, volume name/size, aggregate, protocol details,
cluster hostname, special options (snapshot policy, QoS, junction path).

## Step 2 API Sequence
## Step 2 - API Sequence

Even though Ansible modules abstract the API, list the underlying REST calls
and map each to its `netapp.ontap` module:
Expand All @@ -40,22 +40,22 @@ and map each to its `netapp.ontap` module:
|---|---------------|--------|----------------|-----|

Rules:
- REST only `use_rest: always` on every ONTAP module.
- REST only - `use_rest: always` on every ONTAP module.
- Target ONTAP 9.8+.
- Fully-qualified collection names: `netapp.ontap.na_ontap_*`.
- Collection version: `netapp.ontap >= 22.12.0`.

Wait for my confirmation before generating the playbook.

## Step 3 Generate Playbook
## Step 3 - Generate Playbook

File: `ansible/<use_case>.yml` (snake_case filename)

### Mandatory conventions

```yaml
---
# <use_case>.yml Brief description.
# <use_case>.yml - Brief description.
#
# Usage:
# ansible-playbook -i inventory/hosts.yml <use_case>.yml
Expand Down Expand Up @@ -106,11 +106,11 @@ svm_name, volume_name, volume_size, volume_size_unit, aggregate_name,
client_match (NFS), share_name (CIFS), etc.
```

## Step 4 Validate
## Step 4 - Validate

After the playbook, provide:
1. Exact `ansible-playbook` command to run it.
2. Idempotency behavior what happens on re-run for each task.
2. Idempotency behavior - what happens on re-run for each task.
3. Teardown playbook or reversal instructions.

## Copyright header (required)
Expand All @@ -128,4 +128,4 @@ See the NOTICE file in the repo root for trademark and attribution details.

Place after any shebang (`#!/usr/bin/env python3`), YAML directive (`---`),
or `<!DOCTYPE html>` line. Do **not** duplicate the full trademark text in
source files it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
source files - it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
24 changes: 12 additions & 12 deletions .github/prompts/generate-python.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,34 @@ The script automates a NetApp ONTAP storage task using exclusively REST APIs.

Use these repository files as the authoritative source for conventions:

- [python/ontap_client.py](../../python/ontap_client.py) shared REST client (MUST import and use this)
- [python/nfs_provision.py](../../python/nfs_provision.py) reference implementation pattern
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) API endpoints, auth, async jobs
- [docs/example-template/python/example.py](../../docs/example-template/python/example.py) skeleton to start from
- [CONTRIBUTING.md](../../CONTRIBUTING.md) naming, CI, quality bar
- [python/ontap_client.py](../../python/ontap_client.py) - shared REST client (MUST import and use this)
- [python/nfs_provision.py](../../python/nfs_provision.py) - reference implementation pattern
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) - API endpoints, auth, async jobs
- [docs/example-template/python/example.py](../../docs/example-template/python/example.py) - skeleton to start from
- [CONTRIBUTING.md](../../CONTRIBUTING.md) - naming, CI, quality bar

## Step 1 Clarify Inputs
## Step 1 - Clarify Inputs

Before writing code, identify what information is missing and ask me.
Common inputs: SVM name, volume name/size, aggregate, protocol details,
cluster hostname, special options (snapshot policy, QoS, junction path).

## Step 2 API Sequence
## Step 2 - API Sequence

List the ONTAP REST API calls in execution order:

| # | Method | Endpoint | Key Body/Query Params | Sync/Async | Why |
|---|--------|----------|-----------------------|------------|-----|

Rules:
- ONTAP REST only no ZAPI, no CLI passthrough, no SSH.
- ONTAP REST only - no ZAPI, no CLI passthrough, no SSH.
- Target ONTAP 9.8+ endpoints.
- Full endpoint paths (e.g. `/api/storage/volumes`).
- For async calls, include the poll step: `GET /api/cluster/jobs/{uuid}`.

Wait for my confirmation before generating code.

## Step 3 Generate Python Script
## Step 3 - Generate Python Script

File: `python/<use_case>.py` (snake_case filename)

Expand Down Expand Up @@ -72,7 +72,7 @@ File: `python/<use_case>.py` (snake_case filename)
```
- Async job polling: `client.poll_job(resp["job"]["uuid"])`
- Logging: `logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)-8s %(message)s")`
- `logger = logging.getLogger(__name__)` never use `print()`.
- `logger = logging.getLogger(__name__)` - never use `print()`.
- Entry point:
```python
if __name__ == "__main__":
Expand All @@ -86,7 +86,7 @@ File: `python/<use_case>.py` (snake_case filename)
```
- Type hints on all functions. No hardcoded credentials.

## Step 4 Validate
## Step 4 - Validate

After the code, provide:
1. Exact shell commands to run the script.
Expand All @@ -108,4 +108,4 @@ See the NOTICE file in the repo root for trademark and attribution details.

Place after any shebang (`#!/usr/bin/env python3`), YAML directive (`---`),
or `<!DOCTYPE html>` line. Do **not** duplicate the full trademark text in
source files it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
source files - it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
26 changes: 13 additions & 13 deletions .github/prompts/generate-terraform.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ provider, which calls exclusively REST APIs.

Use these repository files as the authoritative source for conventions:

- [terraform/nfs-provision/main.tf](../../terraform/nfs-provision/main.tf) reference implementation
- [terraform/nfs-provision/variables.tf](../../terraform/nfs-provision/variables.tf) variable patterns
- [terraform/nfs-provision/outputs.tf](../../terraform/nfs-provision/outputs.tf) output patterns
- [terraform/nfs-provision/terraform.tfvars.example](../../terraform/nfs-provision/terraform.tfvars.example) tfvars template
- [docs/example-template/terraform/](../../docs/example-template/terraform/) skeleton files
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) API endpoints and conventions
- [CONTRIBUTING.md](../../CONTRIBUTING.md) naming, CI, quality bar
- [terraform/nfs-provision/main.tf](../../terraform/nfs-provision/main.tf) - reference implementation
- [terraform/nfs-provision/variables.tf](../../terraform/nfs-provision/variables.tf) - variable patterns
- [terraform/nfs-provision/outputs.tf](../../terraform/nfs-provision/outputs.tf) - output patterns
- [terraform/nfs-provision/terraform.tfvars.example](../../terraform/nfs-provision/terraform.tfvars.example) - tfvars template
- [docs/example-template/terraform/](../../docs/example-template/terraform/) - skeleton files
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) - API endpoints and conventions
- [CONTRIBUTING.md](../../CONTRIBUTING.md) - naming, CI, quality bar

## Step 1 Clarify Inputs
## Step 1 - Clarify Inputs

Before writing HCL, identify what information is missing and ask me.
Common inputs: SVM name, volume name/size, aggregate, protocol details,
cluster hostname, special options (snapshot policy, QoS, junction path).

## Step 2 API Sequence & Resource Mapping
## Step 2 - API Sequence & Resource Mapping

List the REST API calls the provider makes and map each to a Terraform
resource or data source:
Expand All @@ -47,7 +47,7 @@ Rules:

Wait for my confirmation before generating HCL.

## Step 3 Generate Module
## Step 3 - Generate Module

Directory: `terraform/<use-case>/` (kebab-case directory name)

Expand All @@ -56,7 +56,7 @@ Create four files:
### main.tf

```hcl
# <use-case> Brief description.
# <use-case> - Brief description.

terraform {
required_version = ">= 1.4"
Expand Down Expand Up @@ -101,7 +101,7 @@ provider "netapp-ontap" {

- Placeholder values with comments. Never include real credentials.

## Step 4 Validate
## Step 4 - Validate

After the module, provide:
1. Exact commands: `terraform init`, `terraform plan`, `terraform apply`.
Expand All @@ -123,4 +123,4 @@ See the NOTICE file in the repo root for trademark and attribution details.

Place after any shebang (`#!/usr/bin/env python3`), YAML directive (`---`),
or `<!DOCTYPE html>` line. Do **not** duplicate the full trademark text in
source files it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
source files - it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
36 changes: 18 additions & 18 deletions .github/prompts/generate-workflow.prompt.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Generate a complete ONTAP workflow Python + Ansible + Terraform for a storage task"
description: "Generate a complete ONTAP workflow - Python + Ansible + Terraform - for a storage task"
---

# Generate Complete ONTAP Workflow (All Three Tools)
Expand All @@ -14,16 +14,16 @@ implementations so users can compare side-by-side.

## Reference Files

- [python/ontap_client.py](../../python/ontap_client.py) shared Python REST client
- [python/nfs_provision.py](../../python/nfs_provision.py) Python reference
- [ansible/nfs_provision.yml](../../ansible/nfs_provision.yml) Ansible reference
- [ansible/cifs_provision.yml](../../ansible/cifs_provision.yml) Ansible CIFS reference
- [terraform/nfs-provision/](../../terraform/nfs-provision/) Terraform reference
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) API endpoints, auth, async jobs
- [docs/example-template/](../../docs/example-template/) skeleton files for all tools
- [CONTRIBUTING.md](../../CONTRIBUTING.md) naming, CI, quality bar
- [python/ontap_client.py](../../python/ontap_client.py) - shared Python REST client
- [python/nfs_provision.py](../../python/nfs_provision.py) - Python reference
- [ansible/nfs_provision.yml](../../ansible/nfs_provision.yml) - Ansible reference
- [ansible/cifs_provision.yml](../../ansible/cifs_provision.yml) - Ansible CIFS reference
- [terraform/nfs-provision/](../../terraform/nfs-provision/) - Terraform reference
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) - API endpoints, auth, async jobs
- [docs/example-template/](../../docs/example-template/) - skeleton files for all tools
- [CONTRIBUTING.md](../../CONTRIBUTING.md) - naming, CI, quality bar

## Phase 1 Clarify Inputs
## Phase 1 - Clarify Inputs

Before generating any code, ask me for anything missing:
- SVM name, volume name/size, aggregate
Expand All @@ -32,7 +32,7 @@ Before generating any code, ask me for anything missing:
- Authentication approach
- Non-default options (snapshot policy, tiering, QoS, junction path)

## Phase 2 API Sequence
## Phase 2 - API Sequence

Present a numbered list of ONTAP REST API calls in execution order.
For each:
Expand All @@ -41,16 +41,16 @@ For each:
|---|--------|----------|----------------|------------|-----|

Rules:
- ONTAP REST only no ZAPI, no CLI passthrough, no SSH.
- ONTAP REST only - no ZAPI, no CLI passthrough, no SSH.
- Target ONTAP 9.8+ endpoints.
- Full paths (e.g. `/api/storage/volumes`).
- Include poll steps for async calls.

**Wait for my approval before Phase 3.**

## Phase 3 Generate All Three Implementations
## Phase 3 - Generate All Three Implementations

### 3A. Python `python/<use_case>.py`
### 3A. Python - `python/<use_case>.py`

- `#!/usr/bin/env python3`, `from __future__ import annotations`
- Module docstring: steps, prerequisites, usage with CLI flags.
Expand All @@ -62,7 +62,7 @@ Rules:
- `if __name__ == "__main__":` with try/except guard.
- Type hints throughout. No hardcoded credentials.

### 3B. Ansible `ansible/<use_case>.yml`
### 3B. Ansible - `ansible/<use_case>.yml`

- `---` header with filename, description, usage comment.
- `hosts: ontap`, `gather_facts: false`, `connection: local`.
Expand All @@ -72,7 +72,7 @@ Rules:
- `vars:` for operational defaults (overridable with `-e`).
- Final `ansible.builtin.debug` summary. No hardcoded credentials.

### 3C. Terraform `terraform/<use-case>/`
### 3C. Terraform - `terraform/<use-case>/`

- `main.tf`: `required_version >= 1.4`, provider `NetApp/netapp-ontap ~> 2.5`,
`connection_profiles` with `cx_profile_name = "cluster1"`.
Expand All @@ -81,7 +81,7 @@ Rules:
- `terraform.tfvars.example`: placeholder values, no real credentials.
- `depends_on` where ordering matters.

## Phase 4 Validate
## Phase 4 - Validate

For each implementation:
1. Exact commands to run it.
Expand All @@ -103,4 +103,4 @@ See the NOTICE file in the repo root for trademark and attribution details.

Place after any shebang (`#!/usr/bin/env python3`), YAML directive (`---`),
or `<!DOCTYPE html>` line. Do **not** duplicate the full trademark text in
source files it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
source files - it lives in [NOTICE](../../NOTICE) and the LICENSE appendix.
8 changes: 4 additions & 4 deletions .github/prompts/plan-api-sequence.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ description: "Design the ONTAP REST API call sequence for a storage operation be
# Plan ONTAP REST API Sequence

You are an ONTAP REST API specialist. Design the exact sequence of API calls
for a storage operation **no code yet**, just the API plan.
for a storage operation - **no code yet**, just the API plan.

## Task

{task description}

## Reference

- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) endpoints, auth, query params, async jobs
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) - endpoints, auth, query params, async jobs
- ONTAP REST API docs: https://docs.netapp.com/us-en/ontap-restapi/swagger-ui/index.html

## Output Format
Expand All @@ -22,11 +22,11 @@ For each API call, fill in this table:

| # | Method | Endpoint | Key Body / Query Params | Sync/Async | Idempotent? | Why |
|---|--------|----------|-------------------------|------------|-------------|-----|
| 1 | GET | /api/svm/svms?name=vs0&fields=uuid | | Sync | Yes | Resolve SVM UUID |
| 1 | GET | /api/svm/svms?name=vs0&fields=uuid | - | Sync | Yes | Resolve SVM UUID |

## Rules

1. **REST only** no ZAPI, no CLI passthrough, no SSH.
1. **REST only** - no ZAPI, no CLI passthrough, no SSH.
2. **ONTAP 9.8+** target minimum.
3. Full endpoint paths (e.g. `/api/storage/volumes`, not just "volumes").
4. For POST/PATCH returning a job, include the poll step:
Expand Down
18 changes: 9 additions & 9 deletions .github/prompts/review-contribution.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ I provide and prepare it for a pull request.

## Reference Files

- [CONTRIBUTING.md](../../CONTRIBUTING.md) full contribution guide
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) API conventions
- [python/ontap_client.py](../../python/ontap_client.py) shared client
- [python/nfs_provision.py](../../python/nfs_provision.py) Python reference
- [ansible/nfs_provision.yml](../../ansible/nfs_provision.yml) Ansible reference
- [terraform/nfs-provision/](../../terraform/nfs-provision/) Terraform reference
- [CONTRIBUTING.md](../../CONTRIBUTING.md) - full contribution guide
- [docs/ontap-api-patterns.md](../../docs/ontap-api-patterns.md) - API conventions
- [python/ontap_client.py](../../python/ontap_client.py) - shared client
- [python/nfs_provision.py](../../python/nfs_provision.py) - Python reference
- [ansible/nfs_provision.yml](../../ansible/nfs_provision.yml) - Ansible reference
- [terraform/nfs-provision/](../../terraform/nfs-provision/) - Terraform reference

## 1. Naming & File Structure

Expand Down Expand Up @@ -74,9 +74,9 @@ I provide and prepare it for a pull request.
## 4. Documentation Updates

Generate README update snippets for each tool's README:
- `python/README.md` new section with description + run instructions
- `ansible/README.md` new section with description + run instructions
- `terraform/README.md` new section with description + run instructions
- `python/README.md` - new section with description + run instructions
- `ansible/README.md` - new section with description + run instructions
- `terraform/README.md` - new section with description + run instructions

## 5. Commit Message

Expand Down
Loading
Loading