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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ All notable changes to zcp will be documented in this file.
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), using
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.0.8] - 2026-04-09

### Fixed

- **VPC create**: Correct payload structure — `cidr` is the network address (e.g. `10.1.0.1`), `size` is the mask (e.g. `16`), requires `type=Vpc`, `billing_cycle`, `plan` (from router plans), `storage_category`
- **ACL create**: Fixed to create ACL lists (name, description, vpc) instead of incorrectly sending protocol/port rule fields
- **Volume Size type**: Fixed `string` to `interface{}` — API returns number, not string
- **JSON tags**: Fixed camelCase to snake_case for `cloud_provider` across vpc, vpn, autoscale request structs
- **VPN user create**: Updated to accept `UserCreateRequest` struct with cloud_provider, region, project

### Added

- **VPC tier/subnet creation**: Confirmed working via `POST /networks` with `type=Vpc`, `gateway`, `netmask`, `acl_id`
- **`--cloud-provider`, `--region`, `--project` flags**: Added to network, vpc, virtualrouter, dns, vpn, autoscale create commands
- **`docs/roadmap.md`**: Feature roadmap documenting what works, what's coming, and what's blocked on platform

### Changed

- **VPC create flags**: Replaced old `--zone`, `--offering`, `--network-domain`, `--lb-provider` with `--cidr`, `--size`, `--plan`, `--billing-cycle`, `--storage-category`, `--cloud-provider`, `--region`, `--project`
- **ACL commands**: `zcp acl create` and `zcp vpc acl-create` now take `--name` and `--description` (matching the actual API)

Comment thread
ditahkk marked this conversation as resolved.
**Full Changelog**: https://github.com/zsoftly/zcp-cli/compare/0.0.7...0.0.8

---

## [0.0.7] - 2026-04-08

### Added
Expand Down
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,13 @@ zcp vm-snapshot revert <slug>
# Networks
zcp network list
zcp network categories
zcp network create --name my-net --category <slug>
zcp network create --name my-net --category <slug> --cloud-provider nimbo --region noida --project default-124
zcp network update <slug> --name "New Name"

# VPC tier networks
zcp network create --name public-tier --cloud-provider nimbo --region noida --project default-124 \
--vpc <vpc-slug> --type Vpc --gateway 10.1.1.1 --netmask 255.255.255.0 --acl-id <acl-id>

# Public IP addresses
zcp ip list
zcp ip allocate --network <slug>
Expand Down Expand Up @@ -321,13 +325,20 @@ zcp portforward create \
```bash
# VPCs
zcp vpc list
zcp vpc create --zone <slug> --name my-vpc --offering <slug> --cidr 10.0.0.0/8
zcp vpc delete <slug>
zcp vpc create \
--name my-vpc \
--cloud-provider nimbo \
--region noida \
--project default-124 \
--plan vpc-1 \
--network-address 10.1.0.1 \
--size 16 \
--billing-cycle hourly \
--storage-category nvme

# Network ACLs
zcp acl list
zcp acl create --vpc <slug> --name my-acl
zcp acl delete <slug>
# Network ACL lists
zcp acl list <vpc-slug>
zcp acl create <vpc-slug> --name my-acl --description "Allow web traffic"

# Public load balancers
zcp loadbalancer list
Expand Down Expand Up @@ -362,7 +373,7 @@ zcp dns list
zcp dns show <slug>

# Create a domain
zcp dns create --name example.com --project my-project
zcp dns create --name example.com --project my-project --cloud-provider nimbo --region noida --dns-provider powerdns

# Create a record
zcp dns record-create --domain <domain-slug> --name www --type A --content 192.0.2.1
Expand All @@ -388,7 +399,7 @@ zcp backup delete <slug>
```bash
zcp autoscale list
zcp autoscale get <slug>
zcp autoscale create --name my-policy --min 1 --max 5
zcp autoscale create --name my-policy --min 1 --max 5 --cloud-provider nimbo --region noida --project default-124
zcp autoscale delete <slug>
```

Expand Down
96 changes: 46 additions & 50 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,79 +1,75 @@
# zcp 0.0.7 Release Notes
# zcp 0.0.8 Release Notes

## What's New

### 8 new commands
### VPC create fixed

| Command | Description |
| --------------------------- | ---------------------------------------------------------------------------------------------- |
| `zcp region list` | List available regions (replaces `zone list`) |
| `zcp profile-info` | User profile, company details, time settings, API access, activity logs (2FA status via `get`) |
| `zcp vm-backup list/create` | VM backup operations |
| `zcp cloud-provider list` | List available cloud providers |
| `zcp server list` | List available servers |
| `zcp currency list` | List available currencies |
| `zcp billing-cycle list` | List available billing cycles |
| `zcp storage-category list` | List available storage categories |
VPC creation now works with the correct payload structure:

### Dead code removed
```bash
zcp vpc create \
--name my-vpc \
--cloud-provider nimbo \
--region noida \
--project default-124 \
--plan vpc-1 \
--network-address 10.1.0.1 \
--size 16 \
--billing-cycle hourly \
--storage-category nvme
```
Comment thread
ditahkk marked this conversation as resolved.

Key: `--network-address` is just the IP (not CIDR notation), `--size` is the mask separately.

11 commands and 13 API packages that still pointed at old `/restapi/` endpoints have been removed. These commands were broken since v0.0.6 and would return 403 errors:
### ACL list creation fixed

`zone`, `offering`, `resource`, `host`, `cost`, `usage`, `internal-lb`, `snapshot-policy`, `security-group`, `tag`, `admin`
`zcp vpc acl-create` and `zcp acl create` now correctly create ACL lists:

Use the STKCNSL replacements instead:
```bash
zcp vpc acl-create my-vpc --name allow-web --description "Allow HTTP"
zcp acl create my-vpc --name private-acl --description "Deny all inbound"
```
Comment thread
ditahkk marked this conversation as resolved.

| Old command | Replacement |
| ------------------------- | --------------------------- |
| `zcp zone list` | `zcp region list` |
| `zcp offering compute` | `zcp plan vm` |
| `zcp offering storage` | `zcp plan storage` |
| `zcp cost summary` | `zcp billing costs` |
| `zcp usage list` | `zcp billing monthly-usage` |
| `zcp tag create` | `zcp instance tag-create` |
| `zcp admin list-accounts` | Not available via API |
### Create commands gain required flags

### Auth validate fixed
`--cloud-provider`, `--region`, `--project` added to: network, vpc, virtualrouter, dns, vpn, autoscale create commands.

`zcp auth validate` now correctly hits the STKCNSL region API instead of the dead zone API.
### Volume Size type fix

---
Volume list no longer fails when the API returns size as a number.

## 42 total commands
### Roadmap published

The CLI now has 42 commands, all backed by the STKCNSL API with zero legacy code remaining.
See `docs/roadmap.md` for what's working, what's coming, and what's blocked on the platform.

---

## Installation
## Known limitations (blocked on platform)

### Quick Install (Recommended)
These require API changes from the STKCNSL team:

**Windows:**
- **No DELETE endpoints** for VPCs, networks, virtual routers, IP addresses, or ACL lists
- **No ACL rule CRUD** — can create ACL lists but not rules inside them
- **Network create (isolated)** — `networkofferingid` not resolvable for nimbo/noida
- **DNS create** — needs admin-side `cloud_provider_setup` provisioning
- **billing cancel-service for VPCs** — returns "service not found"

```powershell
irm https://github.com/zsoftly/zcp-cli/releases/latest/download/install.ps1 | iex
```
See `docs/roadmap.md` for full details.

---

## Installation

**macOS/Linux/WSL:**

```bash
curl -fsSL https://github.com/zsoftly/zcp-cli/releases/latest/download/install.sh | bash
```

### Manual Install

Download the binary for your platform from the assets below, make it executable, and move it to your `PATH`.

## Platforms
**Windows:**

| OS | Architecture | Binary |
| ------- | ------------ | ----------------------- |
| Linux | amd64 | `zcp-linux-amd64` |
| Linux | arm64 | `zcp-linux-arm64` |
| macOS | amd64 | `zcp-darwin-amd64` |
| macOS | arm64 | `zcp-darwin-arm64` |
| Windows | amd64 | `zcp-windows-amd64.exe` |
| Windows | arm64 | `zcp-windows-arm64.exe` |
```powershell
irm https://github.com/zsoftly/zcp-cli/releases/latest/download/install.ps1 | iex
```

**Full Changelog**: https://github.com/zsoftly/zcp-cli/compare/0.0.6...0.0.7
**Full Changelog**: https://github.com/zsoftly/zcp-cli/compare/0.0.7...0.0.8
2 changes: 1 addition & 1 deletion docs/command-taxonomy.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ zcp
│ ├── delete Delete a VPC
│ ├── restart Restart a VPC
│ ├── acl-list List ACL rules for a VPC
│ ├── acl-create-rule Create an ACL rule in a VPC
│ ├── acl-create Create a network ACL list in a VPC
│ ├── acl-replace Replace the ACL on a VPC network
│ └── vpn-gateway VPN gateway operations within a VPC
│ ├── list List VPN gateways
Expand Down
81 changes: 81 additions & 0 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# ZCP CLI Roadmap

Features planned, in progress, or blocked on platform support.

---

## Completed (v0.0.7)

- 42 commands covering VM, storage, networking, billing, monitoring, DNS, projects, support, and more
- Full VM lifecycle: create, start, stop, reboot, reset, tags, change-plan, change-OS, cancel
- VPC lifecycle: create, list, update, restart, ACL list create, VPN gateway create
- VPC tier/subnet creation via `POST /networks` with `type=Vpc`
- Bearer token authentication
- Global `--auto-approve` / `-y` flag for CI/CD automation
- All old STKBILL code removed, zero `/restapi/` references

---

## Planned for next patch

### CLI improvements (no platform dependency)

- [ ] `network create` — add `--vpc`, `--type`, `--gateway`, `--netmask`, `--acl-id` flags for VPC tier creation
- [ ] `network create` — add `--acl` flag that resolves ACL name to ID automatically
- [ ] `portforward create` — add `--public-end-port` and `--private-end-port` flags (API requires them)
- [ ] `instance change-hostname` — fix request body field name (`vm_label` instead of `label`)
- [ ] `region` command — add `use` subcommand to set default region in profile
- [ ] Default `--cloud-provider`, `--region`, `--project` from profile config to reduce flag repetition

### Blocked on STKCNSL platform

These features require API endpoints or fixes from the STKCNSL team.

#### Missing DELETE endpoints

The API has no DELETE for these resource types. Resources can only be removed via `billing cancel-service` for VMs/volumes, but not for networking resources.

- [ ] `DELETE /vpcs/{slug}` — VPC deletion
- [ ] `DELETE /networks/{slug}` — network deletion (isolated and VPC tiers)
- [ ] `DELETE /virtual-routers/{slug}` — virtual router deletion
- [ ] `DELETE /ipaddresses/{slug}` — IP address release
- [ ] `DELETE /vpcs/{slug}/network-acl-list/{id}` — ACL list deletion
- [ ] `billing cancel-service` for VPC/Virtual Router service type — currently returns "service not found"

#### Missing ACL rule CRUD

The UI has "Add Rule" with Number, CIDR, Action, Protocol, Traffic Type fields, but no public API endpoint exists for creating rules inside an ACL list.

- [ ] `POST /vpcs/{slug}/network-acl-list/{acl_id}/rules` — create ACL rule
- [ ] `DELETE /vpcs/{slug}/network-acl-list/{acl_id}/rules/{rule_id}` — delete ACL rule
- [ ] `GET /vpcs/{slug}/network-acl-list/{acl_id}/rules` — list ACL rules

#### Network create (isolated) — noida region

`POST /networks` returns `missing parameter networkofferingid` for the nimbo/noida region. The API doesn't expose the network offering field. Likely a region configuration issue.

- [ ] Network offering mapping for nimbo/noida

#### DNS provisioning

`POST /dns/domains` returns `cloud_provider_setup: DNS configuration required`. DNS needs admin-side provisioning.

- [ ] DNS enabled for our account/region

#### Network quota

Only 2 VPC tier networks allowed before quota exceeded.

- [ ] Quota increase for testing

---

## Future (v0.0.9+)

- [ ] Pagination support — `--page`, `--per-page` flags for list commands
- [ ] `--wait` flag on VPC create, volume create (poll until ready)
- [ ] JSON output improvements — consistent envelope stripping
- [ ] Shell completion for dynamic values (region slugs, plan slugs, etc.)
- [ ] `zcp config set` for default cloud-provider, region, project
- [ ] Object storage management (if API endpoint becomes available)
- [ ] Kubernetes cluster full lifecycle (create works, delete via billing cancel-service)
21 changes: 12 additions & 9 deletions internal/api/acl/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ type NetworkACL struct {
VPCSlug string `json:"vpcSlug"`
}

// ACLRuleCreateRequest holds parameters for creating a Network ACL rule.
// ACLCreateRequest holds parameters for creating a Network ACL list.
type ACLCreateRequest struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
VPC string `json:"vpc"`
}

// ACLRuleCreateRequest holds parameters for creating a rule inside an ACL.
type ACLRuleCreateRequest struct {
Protocol string `json:"protocol"`
CIDRList string `json:"cidrList,omitempty"`
Expand Down Expand Up @@ -77,17 +84,13 @@ func (s *Service) List(ctx context.Context, vpcSlug string) ([]NetworkACL, error
return acls, nil
}

// CreateRule creates a new ACL rule in a VPC.
func (s *Service) CreateRule(ctx context.Context, vpcSlug string, req ACLRuleCreateRequest) (*ACLRule, error) {
// Create creates a new ACL list in a VPC.
func (s *Service) Create(ctx context.Context, vpcSlug string, req ACLCreateRequest) error {
var env apiResponse
if err := s.client.Post(ctx, "/vpcs/"+vpcSlug+"/network-acl-list", req, &env); err != nil {
return nil, fmt.Errorf("creating ACL rule in VPC %s: %w", vpcSlug, err)
return fmt.Errorf("creating ACL in VPC %s: %w", vpcSlug, err)
}
var rule ACLRule
if err := json.Unmarshal(env.Data, &rule); err != nil {
return nil, fmt.Errorf("decoding created ACL rule: %w", err)
}
return &rule, nil
return nil
}

// ReplaceNetworkACL replaces the ACL on a network by slug.
Expand Down
16 changes: 8 additions & 8 deletions internal/api/acl/acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,26 @@ func TestACLList(t *testing.T) {
}
}

func TestACLCreateRule(t *testing.T) {
func TestACLCreate(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
t.Errorf("method = %q, want POST", r.Method)
}
if r.URL.Path != "/vpcs/my-vpc/network-acl-list" {
t.Errorf("path = %q", r.URL.Path)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"status": "Success",
"data": map[string]interface{}{"slug": "rule-1", "protocol": "tcp", "action": "allow"},
"status": "Success",
"message": "Adding network ACL list.",
})
}))
defer srv.Close()

svc := acl.NewService(newClient(srv.URL))
rule, err := svc.CreateRule(context.Background(), "my-vpc", acl.ACLRuleCreateRequest{Protocol: "tcp", Action: "allow"})
err := svc.Create(context.Background(), "my-vpc", acl.ACLCreateRequest{Name: "web-acl", VPC: "my-vpc"})
Comment thread
ditahkk marked this conversation as resolved.
if err != nil {
t.Fatalf("CreateRule() error = %v", err)
}
if rule.Slug != "rule-1" {
t.Errorf("slug = %q, want %q", rule.Slug, "rule-1")
t.Fatalf("Create() error = %v", err)
}
}

Expand Down
3 changes: 3 additions & 0 deletions internal/api/autoscale/autoscale.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ type CreateRequest struct {
CooldownPeriod int `json:"cooldownPeriod,omitempty"`
ZoneSlug string `json:"zoneSlug"`
NetworkSlug string `json:"networkSlug,omitempty"`
CloudProvider string `json:"cloud_provider"`
Region string `json:"region"`
Project string `json:"project"`
}

// ChangePlanRequest holds parameters for changing an autoscale group's plan.
Expand Down
Loading
Loading