Skip to content

Commit 877f746

Browse files
SoulKyuclaude
andcommitted
docs(15): add phase 15 plan files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d6b3cd2 commit 877f746

3 files changed

Lines changed: 649 additions & 0 deletions

File tree

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
phase: 15-replication-resources
3+
plan: 01
4+
type: execute
5+
wave: 1
6+
depends_on: []
7+
files_modified:
8+
- internal/client/models_storage.go
9+
- internal/client/remote_credentials.go
10+
- internal/client/bucket_replica_links.go
11+
autonomous: true
12+
requirements: [RCR-01, RCR-02, BRL-01, BRL-02, BRL-03]
13+
14+
must_haves:
15+
truths:
16+
- "Client can GET/POST/PATCH/DELETE remote credentials by name"
17+
- "Client can GET/POST/PATCH/DELETE bucket replica links by local+remote bucket names"
18+
- "Model structs serialize to correct JSON for FlashBlade API"
19+
artifacts:
20+
- path: "internal/client/models_storage.go"
21+
provides: "ObjectStoreRemoteCredentials, ObjectStoreRemoteCredentialsPost, ObjectStoreRemoteCredentialsPatch, BucketReplicaLink, BucketReplicaLinkPost, BucketReplicaLinkPatch model structs"
22+
contains: "ObjectStoreRemoteCredentials"
23+
- path: "internal/client/remote_credentials.go"
24+
provides: "CRUD client methods for /object-store-remote-credentials"
25+
exports: ["GetRemoteCredentials", "PostRemoteCredentials", "PatchRemoteCredentials", "DeleteRemoteCredentials"]
26+
- path: "internal/client/bucket_replica_links.go"
27+
provides: "CRUD client methods for /bucket-replica-links"
28+
exports: ["GetBucketReplicaLink", "PostBucketReplicaLink", "PatchBucketReplicaLink", "DeleteBucketReplicaLink"]
29+
key_links:
30+
- from: "internal/client/remote_credentials.go"
31+
to: "internal/client/models_storage.go"
32+
via: "uses ObjectStoreRemoteCredentials types"
33+
pattern: "ObjectStoreRemoteCredentials"
34+
- from: "internal/client/bucket_replica_links.go"
35+
to: "internal/client/models_storage.go"
36+
via: "uses BucketReplicaLink types"
37+
pattern: "BucketReplicaLink"
38+
---
39+
40+
<objective>
41+
Add model structs and client CRUD methods for both remote credentials and bucket replica link resources.
42+
43+
Purpose: Foundation layer for Phase 15 -- downstream resource implementations (plans 02 and 03) depend on these models and client methods.
44+
Output: Model structs in models_storage.go, client methods in two new files.
45+
</objective>
46+
47+
<execution_context>
48+
@/home/gule/.claude/get-shit-done/workflows/execute-plan.md
49+
@/home/gule/.claude/get-shit-done/templates/summary.md
50+
</execution_context>
51+
52+
<context>
53+
@.planning/PROJECT.md
54+
@.planning/ROADMAP.md
55+
@.planning/STATE.md
56+
57+
@internal/client/models_storage.go
58+
@internal/client/models_common.go
59+
@internal/client/object_store_accounts.go
60+
@internal/client/buckets.go
61+
@internal/client/array_connections.go
62+
63+
<interfaces>
64+
<!-- Existing types the executor needs -->
65+
66+
From internal/client/models_common.go:
67+
```go
68+
type NamedReference struct {
69+
Name string `json:"name,omitempty"`
70+
ID string `json:"id,omitempty"`
71+
}
72+
73+
type ListResponse[T any] struct {
74+
Items []T `json:"items"`
75+
ContinuationToken string `json:"continuation_token,omitempty"`
76+
TotalItemCount int `json:"total_item_count,omitempty"`
77+
}
78+
```
79+
80+
From internal/client/client.go (methods available):
81+
```go
82+
func (c *FlashBladeClient) get(ctx context.Context, path string, out interface{}) error
83+
func (c *FlashBladeClient) post(ctx context.Context, path string, body interface{}, out interface{}) error
84+
func (c *FlashBladeClient) patch(ctx context.Context, path string, body interface{}, out interface{}) error
85+
func (c *FlashBladeClient) delete(ctx context.Context, path string) error
86+
```
87+
</interfaces>
88+
</context>
89+
90+
<tasks>
91+
92+
<task type="auto">
93+
<name>Task 1: Add model structs for remote credentials and bucket replica link</name>
94+
<files>internal/client/models_storage.go</files>
95+
<action>
96+
Append the following model structs to the end of models_storage.go:
97+
98+
**ObjectStoreRemoteCredentials** (GET response model):
99+
- `ID` string `json:"id"`
100+
- `Name` string `json:"name"`
101+
- `AccessKeyID` string `json:"access_key_id"`
102+
- `SecretAccessKey` string `json:"secret_access_key,omitempty"` (only returned on POST, empty on GET)
103+
- `Remote` NamedReference `json:"remote"`
104+
- `Realms` []NamedReference `json:"realms,omitempty"` (computed, read-only)
105+
106+
**ObjectStoreRemoteCredentialsPost** (POST body):
107+
- `AccessKeyID` string `json:"access_key_id"`
108+
- `SecretAccessKey` string `json:"secret_access_key"`
109+
- Name is passed via `?names=` query param, NOT in body.
110+
- Remote is passed via `?remote_names=` query param (reference to array connection remote), NOT in body.
111+
112+
**ObjectStoreRemoteCredentialsPatch** (PATCH body — pointer fields for partial update):
113+
- `AccessKeyID` *string `json:"access_key_id,omitempty"`
114+
- `SecretAccessKey` *string `json:"secret_access_key,omitempty"`
115+
116+
**BucketReplicaLink** (GET response model):
117+
- `ID` string `json:"id"`
118+
- `LocalBucket` NamedReference `json:"local_bucket"`
119+
- `RemoteBucket` NamedReference `json:"remote_bucket"`
120+
- `Remote` NamedReference `json:"remote"`
121+
- `RemoteCredentials` *NamedReference `json:"remote_credentials,omitempty"` (pointer — nil for FB-to-FB links)
122+
- `Paused` bool `json:"paused"`
123+
- `CascadingEnabled` bool `json:"cascading_enabled"`
124+
- `Direction` string `json:"direction,omitempty"` (read-only: "inbound" or "outbound")
125+
- `Status` string `json:"status,omitempty"` (read-only)
126+
- `StatusDetails` string `json:"status_details,omitempty"` (read-only)
127+
- `Lag` int64 `json:"lag,omitempty"` (read-only, milliseconds)
128+
- `RecoveryPoint` int64 `json:"recovery_point,omitempty"` (read-only, epoch ms)
129+
- `ObjectBacklog` *ObjectBacklog `json:"object_backlog,omitempty"` (read-only)
130+
131+
**ObjectBacklog** (nested struct for replica link):
132+
- `Count` int64 `json:"count,omitempty"`
133+
- `TotalSize` int64 `json:"total_size,omitempty"`
134+
135+
**BucketReplicaLinkPost** (POST body):
136+
- `Paused` bool `json:"paused,omitempty"`
137+
- `CascadingEnabled` bool `json:"cascading_enabled,omitempty"`
138+
- Local bucket, remote bucket, and remote credentials are all query params, NOT body fields.
139+
140+
**BucketReplicaLinkPatch** (PATCH body — pointer fields):
141+
- `Paused` *bool `json:"paused,omitempty"`
142+
</action>
143+
<verify>
144+
<automated>cd /home/gule/Workspace/team-infrastructure/terraform-provider-flashblade && go build ./internal/client/...</automated>
145+
</verify>
146+
<done>All 6 new structs compile. ObjectStoreRemoteCredentials, ObjectStoreRemoteCredentialsPost, ObjectStoreRemoteCredentialsPatch, BucketReplicaLink, BucketReplicaLinkPost, BucketReplicaLinkPatch, ObjectBacklog exist in models_storage.go.</done>
147+
</task>
148+
149+
<task type="auto">
150+
<name>Task 2: Client CRUD methods for remote credentials and bucket replica links</name>
151+
<files>internal/client/remote_credentials.go, internal/client/bucket_replica_links.go</files>
152+
<action>
153+
**Create internal/client/remote_credentials.go** following the pattern from object_store_accounts.go:
154+
155+
- `GetRemoteCredentials(ctx, name string) (*ObjectStoreRemoteCredentials, error)` — GET `/object-store-remote-credentials?names={name}`, return first item or 404.
156+
- `ListRemoteCredentials(ctx) ([]ObjectStoreRemoteCredentials, error)` — GET with pagination (continuation_token loop).
157+
- `PostRemoteCredentials(ctx, name string, remoteName string, body ObjectStoreRemoteCredentialsPost) (*ObjectStoreRemoteCredentials, error)` — POST `/object-store-remote-credentials?names={name}&remote_names={remoteName}`, body contains access_key_id + secret_access_key.
158+
- `PatchRemoteCredentials(ctx, name string, body ObjectStoreRemoteCredentialsPatch) (*ObjectStoreRemoteCredentials, error)` — PATCH `/object-store-remote-credentials?names={name}`.
159+
- `DeleteRemoteCredentials(ctx, name string) error` — DELETE `/object-store-remote-credentials?names={name}`.
160+
161+
**Create internal/client/bucket_replica_links.go** — this resource uses MULTIPLE query params for identification (not just names=):
162+
163+
- `GetBucketReplicaLink(ctx, localBucketName string, remoteBucketName string) (*BucketReplicaLink, error)` — GET `/bucket-replica-links?local_bucket_names={local}&remote_bucket_names={remote}`, return first item or 404.
164+
- `ListBucketReplicaLinks(ctx) ([]BucketReplicaLink, error)` — GET with pagination.
165+
- `PostBucketReplicaLink(ctx, localBucketName string, remoteBucketName string, remoteCredentialsName string, body BucketReplicaLinkPost) (*BucketReplicaLink, error)` — POST `/bucket-replica-links?local_bucket_names={local}&remote_bucket_names={remote}&remote_credentials_names={cred}`. If remoteCredentialsName is empty, omit that param (FB-to-FB case uses remote_names= derived from array connection, but for now only remote_credentials_names is supported).
166+
- `PatchBucketReplicaLink(ctx, id string, body BucketReplicaLinkPatch) (*BucketReplicaLink, error)` — PATCH `/bucket-replica-links?ids={id}`. Use ID for PATCH stability (same pattern as PatchBucket).
167+
- `DeleteBucketReplicaLink(ctx, localBucketName string, remoteBucketName string) error` — DELETE `/bucket-replica-links?local_bucket_names={local}&remote_bucket_names={remote}`.
168+
169+
All methods use `url.QueryEscape` for parameter values. All POST/PATCH return the first item from the ListResponse wrapper.
170+
</action>
171+
<verify>
172+
<automated>cd /home/gule/Workspace/team-infrastructure/terraform-provider-flashblade && go build ./internal/client/...</automated>
173+
</verify>
174+
<done>Both client files compile. GetRemoteCredentials, PostRemoteCredentials, PatchRemoteCredentials, DeleteRemoteCredentials, GetBucketReplicaLink, PostBucketReplicaLink, PatchBucketReplicaLink, DeleteBucketReplicaLink are all callable from the client package.</done>
175+
</task>
176+
177+
</tasks>
178+
179+
<verification>
180+
```bash
181+
cd /home/gule/Workspace/team-infrastructure/terraform-provider-flashblade && go build ./... && go vet ./internal/client/...
182+
```
183+
</verification>
184+
185+
<success_criteria>
186+
- models_storage.go contains 7 new structs (ObjectStoreRemoteCredentials, Post, Patch, BucketReplicaLink, Post, Patch, ObjectBacklog)
187+
- remote_credentials.go has Get/List/Post/Patch/Delete methods
188+
- bucket_replica_links.go has Get/List/Post/Patch/Delete methods
189+
- `go build ./...` passes with no errors
190+
</success_criteria>
191+
192+
<output>
193+
After completion, create `.planning/phases/15-replication-resources/15-01-SUMMARY.md`
194+
</output>

0 commit comments

Comments
 (0)