Skip to content

Commit a54e910

Browse files
authored
Add connectivity rule support for azure (#91)
* Add connectivity rule support for azure * bump go * fix test from update * remove now irrelevant test
1 parent 05bbed4 commit a54e910

8 files changed

Lines changed: 1428 additions & 143 deletions

File tree

‎go.mod‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/temporalio/cloud-cli
22

3-
go 1.26.3
3+
go 1.26.4
44

55
require (
66
github.com/aws/aws-sdk-go-v2 v1.41.11
@@ -14,7 +14,7 @@ require (
1414
github.com/stretchr/testify v1.11.1
1515
github.com/temporalio/cli/cliext v0.0.0-20260602200703-8bb57b77ad55
1616
go.temporal.io/api v1.62.13
17-
go.temporal.io/cloud-sdk v0.13.0
17+
go.temporal.io/cloud-sdk v0.15.0
1818
go.temporal.io/sdk v1.44.1
1919
go.temporal.io/sdk/contrib/envconfig v1.0.0
2020
golang.org/x/oauth2 v0.36.0

‎go.sum‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09
154154
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
155155
go.temporal.io/api v1.62.13 h1:xMa8Nt5oAMX+LvlCJA44wjTCc1H09i2rG9poB1/xvH4=
156156
go.temporal.io/api v1.62.13/go.mod h1:0k75tRljEuELWGeXjEZZO7zYqBln4+1FrG6+IMOMy7Q=
157-
go.temporal.io/cloud-sdk v0.13.0 h1:Yhh6TEQG7xZgn8/A7C9WcxM+LS08qXlITRicuo2zGOA=
158-
go.temporal.io/cloud-sdk v0.13.0/go.mod h1:W2O9t9tvo3Q/LhGgYdj8JijWbN5C84os+cz/BadIHYI=
157+
go.temporal.io/cloud-sdk v0.15.0 h1:TwlGhTVnF7d9uIP5wjV/vr7TBYsPEpJw/MNuiylX3DQ=
158+
go.temporal.io/cloud-sdk v0.15.0/go.mod h1:W2O9t9tvo3Q/LhGgYdj8JijWbN5C84os+cz/BadIHYI=
159159
go.temporal.io/sdk v1.44.1 h1:Mt2OZLZpqkzDIdg9YyQzO0Rb/HqCDnnqHlIAGAJ5gqM=
160160
go.temporal.io/sdk v1.44.1/go.mod h1:vkApR12F9/Y8OR+hkxe7WyXQFuCX6clhzqnAk6rzDAM=
161161
go.temporal.io/sdk/contrib/envconfig v1.0.0 h1:1Q/swVgB4EW/p3k7rI9/4hpU4/DC57FSRbU90+UisXw=

‎internal/cloudservice/mock/mock.go‎

Lines changed: 1344 additions & 99 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎temporalcloudcli/commands.connectivity.go‎

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ type (
3737
}
3838

3939
CreatePrivateConnectivityRuleParams struct {
40-
ConnectionID string
41-
Region string
42-
GCPProjectID string
43-
AsyncOperationID string
40+
ConnectionID string
41+
Region string
42+
GCPProjectID string
43+
AzurePeResourceID string
44+
AsyncOperationID string
4445

4546
Cloud cloudservice.CloudServiceClient
4647
Prompter Prompter
@@ -123,19 +124,17 @@ func CreatePublicConnectivityRule(ctx context.Context, params CreatePublicConnec
123124

124125
// CreatePrivateConnectivityRule creates a new private VPC connectivity rule.
125126
func CreatePrivateConnectivityRule(ctx context.Context, params CreatePrivateConnectivityRuleParams) error {
126-
if params.ConnectionID == "" {
127-
return errors.New("--connection-id is required for private connectivity")
128-
}
129127
if params.Region == "" {
130128
return errors.New("--region is required for private connectivity")
131129
}
132130

133131
spec := &connectivityrulev1.ConnectivityRuleSpec{
134132
ConnectionType: &connectivityrulev1.ConnectivityRuleSpec_PrivateRule{
135133
PrivateRule: &connectivityrulev1.PrivateConnectivityRule{
136-
ConnectionId: params.ConnectionID,
137-
GcpProjectId: params.GCPProjectID,
138-
Region: params.Region,
134+
ConnectionId: params.ConnectionID,
135+
GcpProjectId: params.GCPProjectID,
136+
Region: params.Region,
137+
AzurePeResourceId: params.AzurePeResourceID,
139138
},
140139
},
141140
}
@@ -230,13 +229,14 @@ func (c *CloudConnectivityPrivateCreateCommand) run(cctx *CommandContext, _ []st
230229
return err
231230
}
232231
return CreatePrivateConnectivityRule(cctx.Context, CreatePrivateConnectivityRuleParams{
233-
ConnectionID: c.ConnectionId,
234-
Region: c.Region,
235-
GCPProjectID: c.GcpProjectId,
236-
AsyncOperationID: c.AsyncOperationId,
237-
Cloud: cloudClient.CloudService(),
238-
Prompter: newPrompter(cctx),
239-
OperationHandler: NewOperationHandler(cctx, c.AsyncOperationOptions, c.ClientOptions),
232+
ConnectionID: c.ConnectionId,
233+
Region: c.Region,
234+
GCPProjectID: c.GcpProjectId,
235+
AzurePeResourceID: c.AzurePeResourceId,
236+
AsyncOperationID: c.AsyncOperationId,
237+
Cloud: cloudClient.CloudService(),
238+
Prompter: newPrompter(cctx),
239+
OperationHandler: NewOperationHandler(cctx, c.AsyncOperationOptions, c.ClientOptions),
240240
})
241241
}
242242

‎temporalcloudcli/commands.connectivity_test.go‎

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,32 +315,58 @@ func TestCreatePrivateConnectivityRule_Success(t *testing.T) {
315315
require.NoError(t, err)
316316
}
317317

318-
// TestCreatePrivateConnectivityRule_MissingConnectionID verifies an error when no connection-id.
319-
func TestCreatePrivateConnectivityRule_MissingConnectionID(t *testing.T) {
318+
// TestCreatePrivateConnectivityRule_MissingRegion verifies an error when no region.
319+
func TestCreatePrivateConnectivityRule_MissingRegion(t *testing.T) {
320320
mockCloud := cloudmock.NewMockCloudServiceClient(t)
321321
mockHandler := cmdmock.NewMockAsyncOperationHandler(t)
322322

323323
err := temporalcloudcli.CreatePrivateConnectivityRule(context.Background(), temporalcloudcli.CreatePrivateConnectivityRuleParams{
324-
Region: "aws-us-west-2",
324+
ConnectionID: "vpce-12345",
325325
Cloud: mockCloud,
326326
OperationHandler: mockHandler,
327327
})
328328
require.Error(t, err)
329-
assert.Contains(t, err.Error(), "--connection-id is required")
329+
assert.Contains(t, err.Error(), "--region is required")
330330
}
331331

332-
// TestCreatePrivateConnectivityRule_MissingRegion verifies an error when no region.
333-
func TestCreatePrivateConnectivityRule_MissingRegion(t *testing.T) {
332+
// TestCreatePrivateConnectivityRule_Azure_Success verifies that an Azure rule is created with the PE resource ID.
333+
func TestCreatePrivateConnectivityRule_Azure_Success(t *testing.T) {
334334
mockCloud := cloudmock.NewMockCloudServiceClient(t)
335335
mockHandler := cmdmock.NewMockAsyncOperationHandler(t)
336+
mockPrompter := cmdmock.NewMockPrompter(t)
337+
338+
azurePeResourceID := "/subscriptions/sub-123/resourceGroups/rg-1/providers/Microsoft.Network/privateEndpoints/pe-1"
339+
op := &operation.AsyncOperation{Id: "op-azure"}
340+
expectedSpec := &connectivityrulev1.ConnectivityRuleSpec{
341+
ConnectionType: &connectivityrulev1.ConnectivityRuleSpec_PrivateRule{
342+
PrivateRule: &connectivityrulev1.PrivateConnectivityRule{
343+
Region: "azure-eastus",
344+
AzurePeResourceId: azurePeResourceID,
345+
},
346+
},
347+
}
348+
mockPrompter.EXPECT().
349+
PromptApply(&connectivityrulev1.ConnectivityRuleSpec{}, expectedSpec, false).
350+
Return(nil)
351+
mockCloud.EXPECT().
352+
CreateConnectivityRule(context.Background(), &cloudservice.CreateConnectivityRuleRequest{
353+
Spec: expectedSpec,
354+
}).
355+
Return(&cloudservice.CreateConnectivityRuleResponse{
356+
ConnectivityRuleId: "rule-azure",
357+
AsyncOperation: op,
358+
}, nil)
359+
360+
mockHandler.EXPECT().HandleOperation(op, "rule-azure").Return(nil)
336361

337362
err := temporalcloudcli.CreatePrivateConnectivityRule(context.Background(), temporalcloudcli.CreatePrivateConnectivityRuleParams{
338-
ConnectionID: "vpce-12345",
339-
Cloud: mockCloud,
340-
OperationHandler: mockHandler,
363+
AzurePeResourceID: azurePeResourceID,
364+
Region: "azure-eastus",
365+
Cloud: mockCloud,
366+
Prompter: mockPrompter,
367+
OperationHandler: mockHandler,
341368
})
342-
require.Error(t, err)
343-
assert.Contains(t, err.Error(), "--region is required")
369+
require.NoError(t, err)
344370
}
345371

346372
// TestDeleteConnectivityRule_Success verifies that the rule is fetched, diff shown, then deleted.

‎temporalcloudcli/commands.gen.go‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,9 +1427,10 @@ type CloudConnectivityPrivateCreateCommand struct {
14271427
Command cobra.Command
14281428
ClientOptions
14291429
AsyncOperationOptions
1430-
ConnectionId string
1431-
Region string
1432-
GcpProjectId string
1430+
ConnectionId string
1431+
Region string
1432+
GcpProjectId string
1433+
AzurePeResourceId string
14331434
}
14341435

14351436
func NewCloudConnectivityPrivateCreateCommand(cctx *CommandContext, parent *CloudConnectivityPrivateCommand) *CloudConnectivityPrivateCreateCommand {
@@ -1439,16 +1440,16 @@ func NewCloudConnectivityPrivateCreateCommand(cctx *CommandContext, parent *Clou
14391440
s.Command.Use = "create [flags]"
14401441
s.Command.Short = "Create a private connectivity rule"
14411442
if hasHighlighting {
1442-
s.Command.Long = "Create a new private VPC connectivity rule. Requires --connection-id and --region.\n\nExample:\n\n\x1b[1mtemporal cloud connectivity private create --connection-id vpce-12345 --region aws-us-west-2\x1b[0m"
1443+
s.Command.Long = "Create a new private connectivity rule for AWS, GCP, or Azure.\n\nFor AWS, provide --connection-id (VPC endpoint ID) and --region.\nFor GCP, provide --connection-id (PSC connection ID), --gcp-project-id, and --region.\nFor Azure, provide --azure-pe-resource-id (ARM resource ID) and --region.\n\nExamples:\n\n\x1b[1mtemporal cloud connectivity private create --connection-id vpce-12345 --region aws-us-west-2\n\ntemporal cloud connectivity private create \\\n --azure-pe-resource-id /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/privateEndpoints/{name} \\\n --region azure-eastus\x1b[0m"
14431444
} else {
1444-
s.Command.Long = "Create a new private VPC connectivity rule. Requires --connection-id and --region.\n\nExample:\n\n```\ntemporal cloud connectivity private create --connection-id vpce-12345 --region aws-us-west-2\n```"
1445+
s.Command.Long = "Create a new private connectivity rule for AWS, GCP, or Azure.\n\nFor AWS, provide --connection-id (VPC endpoint ID) and --region.\nFor GCP, provide --connection-id (PSC connection ID), --gcp-project-id, and --region.\nFor Azure, provide --azure-pe-resource-id (ARM resource ID) and --region.\n\nExamples:\n\n```\ntemporal cloud connectivity private create --connection-id vpce-12345 --region aws-us-west-2\n\ntemporal cloud connectivity private create \\\n --azure-pe-resource-id /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/privateEndpoints/{name} \\\n --region azure-eastus\n```"
14451446
}
14461447
s.Command.Args = cobra.NoArgs
1447-
s.Command.Flags().StringVar(&s.ConnectionId, "connection-id", "", "The connection ID for private connectivity. Required.")
1448-
_ = cobra.MarkFlagRequired(s.Command.Flags(), "connection-id")
1448+
s.Command.Flags().StringVar(&s.ConnectionId, "connection-id", "", "The connection ID for private connectivity (AWS VPC endpoint ID or GCP PSC connection ID).")
14491449
s.Command.Flags().StringVar(&s.Region, "region", "", "The region for private connectivity. Required.")
14501450
_ = cobra.MarkFlagRequired(s.Command.Flags(), "region")
14511451
s.Command.Flags().StringVar(&s.GcpProjectId, "gcp-project-id", "", "The GCP project ID (only for GCP private connectivity).")
1452+
s.Command.Flags().StringVar(&s.AzurePeResourceId, "azure-pe-resource-id", "", "The ARM resource ID of the Azure Private Endpoint (only for Azure private connectivity). Example: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/privateEndpoints/{name}.")
14521453
s.ClientOptions.BuildFlags(s.Command.Flags())
14531454
s.AsyncOperationOptions.BuildFlags(s.Command.Flags())
14541455
s.Command.Run = func(c *cobra.Command, args []string) {

‎temporalcloudcli/commands.yml‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,12 +2645,20 @@ commands:
26452645
- name: cloud connectivity private create
26462646
summary: Create a private connectivity rule
26472647
description: |
2648-
Create a new private VPC connectivity rule. Requires --connection-id and --region.
2648+
Create a new private connectivity rule for AWS, GCP, or Azure.
26492649
2650-
Example:
2650+
For AWS, provide --connection-id (VPC endpoint ID) and --region.
2651+
For GCP, provide --connection-id (PSC connection ID), --gcp-project-id, and --region.
2652+
For Azure, provide --azure-pe-resource-id (ARM resource ID) and --region.
2653+
2654+
Examples:
26512655
26522656
```
26532657
temporal cloud connectivity private create --connection-id vpce-12345 --region aws-us-west-2
2658+
2659+
temporal cloud connectivity private create \
2660+
--azure-pe-resource-id /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/privateEndpoints/{name} \
2661+
--region azure-eastus
26542662
```
26552663
has-init: false
26562664
option-sets:
@@ -2659,9 +2667,8 @@ commands:
26592667
options:
26602668
- name: connection-id
26612669
type: string
2662-
required: true
26632670
description: |
2664-
The connection ID for private connectivity.
2671+
The connection ID for private connectivity (AWS VPC endpoint ID or GCP PSC connection ID).
26652672
- name: region
26662673
type: string
26672674
required: true
@@ -2671,6 +2678,11 @@ commands:
26712678
type: string
26722679
description: |
26732680
The GCP project ID (only for GCP private connectivity).
2681+
- name: azure-pe-resource-id
2682+
type: string
2683+
description: |
2684+
The ARM resource ID of the Azure Private Endpoint (only for Azure private connectivity).
2685+
Example: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/privateEndpoints/{name}.
26742686
26752687
# User commands
26762688
- name: cloud user

‎temporalcloudcli/internal/protoutils/testdata/strip_deprecated/removes_deprecated_field_in_map_value_message.golden.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
"ns1": {
55
"permission": "PERMISSION_READ"
66
}
7-
}
7+
},
8+
"projectAccesses": {}
89
}

0 commit comments

Comments
 (0)