Skip to content

Commit f62802b

Browse files
Merge pull request #4336 from maqiuyujoyce/resource-networkmanagement-connectivitytest-controller
Support direct controller for NetworkManagementConnectivityTest
2 parents cd7beac + f4c71fb commit f62802b

File tree

21 files changed

+1421
-185
lines changed

21 files changed

+1421
-185
lines changed

apis/networkmanagement/v1alpha1/connectivitytest_identity.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type ConnectivityTestIdentity struct {
3232
}
3333

3434
func (i *ConnectivityTestIdentity) String() string {
35-
return i.parent.String() + "/connectivitytests/" + i.id
35+
return i.parent.String() + "/connectivityTests/" + i.id
3636
}
3737

3838
func (i *ConnectivityTestIdentity) ID() string {
@@ -106,8 +106,8 @@ func NewConnectivityTestIdentity(ctx context.Context, reader client.Reader, obj
106106

107107
func ParseConnectivityTestExternal(external string) (parent *ConnectivityTestParent, resourceID string, err error) {
108108
tokens := strings.Split(external, "/")
109-
if len(tokens) != 6 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "connectivitytests" {
110-
return nil, "", fmt.Errorf("format of NetworkManagementConnectivityTest external=%q was not known (use projects/{{projectID}}/locations/{{location}}/connectivitytests/{{connectivitytestID}})", external)
109+
if len(tokens) != 6 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "connectivityTests" {
110+
return nil, "", fmt.Errorf("format of NetworkManagementConnectivityTest external=%q was not known (use projects/{{projectID}}/locations/{{location}}/connectivityTests/{{connectivityTestID}})", external)
111111
}
112112
parent = &ConnectivityTestParent{
113113
ProjectID: tokens[1],

apis/networkmanagement/v1alpha1/connectivitytest_reference.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var _ refsv1beta1.ExternalNormalizer = &ConnectivityTestRef{}
3232
// holds the GCP identifier for the KRM object.
3333
type ConnectivityTestRef struct {
3434
// A reference to an externally managed NetworkManagementConnectivityTest resource.
35-
// Should be in the format "projects/{{projectID}}/locations/{{location}}/connectivitytests/{{connectivitytestID}}".
35+
// Should be in the format "projects/{{projectID}}/locations/{{location}}/connectivityTests/{{connectivityTestID}}".
3636
External string `json:"external,omitempty"`
3737

3838
// The name of a NetworkManagementConnectivityTest resource.

apis/networkmanagement/v1alpha1/connectivitytest_types.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ type NetworkManagementConnectivityTestStatus struct {
245245
// NetworkManagementConnectivityTestObservedState is the state of the NetworkManagementConnectivityTest resource as most recently observed in GCP.
246246
// +kcc:proto=google.cloud.networkmanagement.v1.ConnectivityTest
247247
type NetworkManagementConnectivityTestObservedState struct {
248-
// Required. Source specification of the Connectivity Test.
248+
// Source specification of the Connectivity Test.
249249
//
250250
// You can use a combination of source IP address, virtual machine
251251
// (VM) instance, or Compute Engine network to uniquely identify
@@ -270,6 +270,27 @@ type NetworkManagementConnectivityTestObservedState struct {
270270
// +kcc:proto:field=google.cloud.networkmanagement.v1.ConnectivityTest.source
271271
Source *EndpointObservedState `json:"source,omitempty"`
272272

273+
// Destination specification of the Connectivity Test.
274+
//
275+
// You can use a combination of destination IP address, Compute Engine
276+
// VM instance, or VPC network to uniquely identify the destination
277+
// location.
278+
//
279+
// Even if the destination IP address is not unique, the source IP
280+
// location is unique. Usually, the analysis can infer the destination
281+
// endpoint from route information.
282+
//
283+
// If the destination you specify is a VM instance and the instance has
284+
// multiple network interfaces, then you must also specify either
285+
// a destination IP address or VPC network to identify the destination
286+
// interface.
287+
//
288+
// A reachability analysis proceeds even if the destination location is
289+
// ambiguous. However, the result can include endpoints that you don't
290+
// intend to test.
291+
// +kcc:proto:field=google.cloud.networkmanagement.v1.ConnectivityTest.destination
292+
Destination *EndpointObservedState `json:"destination,omitempty"`
293+
273294
// Output only. The display name of a Connectivity Test.
274295
// +kcc:proto:field=google.cloud.networkmanagement.v1.ConnectivityTest.display_name
275296
DisplayName *string `json:"displayName,omitempty"`

apis/networkmanagement/v1alpha1/zz_generated.deepcopy.go

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_networkmanagementconnectivitytests.networkmanagement.cnrm.cloud.google.com.yaml

+36-1
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,41 @@ spec:
726726
createTime:
727727
description: Output only. The time the test was created.
728728
type: string
729+
destination:
730+
description: |-
731+
Destination specification of the Connectivity Test.
732+
733+
You can use a combination of destination IP address, Compute Engine
734+
VM instance, or VPC network to uniquely identify the destination
735+
location.
736+
737+
Even if the destination IP address is not unique, the source IP
738+
location is unique. Usually, the analysis can infer the destination
739+
endpoint from route information.
740+
741+
If the destination you specify is a VM instance and the instance has
742+
multiple network interfaces, then you must also specify either
743+
a destination IP address or VPC network to identify the destination
744+
interface.
745+
746+
A reachability analysis proceeds even if the destination location is
747+
ambiguous. However, the result can include endpoints that you don't
748+
intend to test.
749+
properties:
750+
forwardingRuleTarget:
751+
description: Output only. Specifies the type of the target
752+
of the forwarding rule.
753+
type: string
754+
loadBalancerID:
755+
description: Output only. ID of the load balancer the forwarding
756+
rule points to. Empty for forwarding rules not related to
757+
load balancers.
758+
type: string
759+
loadBalancerType:
760+
description: Output only. Type of the load balancer the forwarding
761+
rule points to.
762+
type: string
763+
type: object
729764
displayName:
730765
description: Output only. The display name of a Connectivity Test.
731766
type: string
@@ -2939,7 +2974,7 @@ spec:
29392974
type: object
29402975
source:
29412976
description: |-
2942-
Required. Source specification of the Connectivity Test.
2977+
Source specification of the Connectivity Test.
29432978
29442979
You can use a combination of source IP address, virtual machine
29452980
(VM) instance, or Compute Engine network to uniquely identify

config/tests/samples/create/harness.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -900,10 +900,12 @@ func MaybeSkip(t *testing.T, name string, resources []*unstructured.Unstructured
900900
case schema.GroupKind{Group: "monitoring.cnrm.cloud.google.com", Kind: "MonitoringServiceLevelObjective"}:
901901
case schema.GroupKind{Group: "monitoring.cnrm.cloud.google.com", Kind: "MonitoringUptimeCheckConfig"}:
902902

903+
case schema.GroupKind{Group: "netapp.cnrm.cloud.google.com", Kind: "NetAppBackupPolicy"}:
904+
903905
case schema.GroupKind{Group: "networkconnectivity.cnrm.cloud.google.com", Kind: "NetworkConnectivityServiceConnectionPolicy"}:
904906
case schema.GroupKind{Group: "networkconnectivity.cnrm.cloud.google.com", Kind: "NetworkConnectivityInternalRange"}:
905907

906-
case schema.GroupKind{Group: "netapp.cnrm.cloud.google.com", Kind: "NetAppBackupPolicy"}:
908+
case schema.GroupKind{Group: "networkmanagement.cnrm.cloud.google.com", Kind: "NetworkManagementConnectivityTest"}:
907909

908910
case schema.GroupKind{Group: "networkservices.cnrm.cloud.google.com", Kind: "NetworkServicesMesh"}:
909911
case schema.GroupKind{Group: "networkservices.cnrm.cloud.google.com", Kind: "NetworkServicesServiceBinding"}:

mockgcp/mocknetworkmanagement/connectivitytest.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ func (s *reachabilityService) GetConnectivityTest(ctx context.Context, req *pb.G
5050

5151
obj := &pb.ConnectivityTest{}
5252
if err := s.storage.Get(ctx, fqn, obj); err != nil {
53+
if status.Code(err) == codes.NotFound {
54+
return nil, status.Errorf(codes.NotFound, "Resource '%s' was not found", fqn)
55+
}
56+
5357
return nil, err
5458
}
5559
// TODO: Remove these lines, or add default values, this is just a workaround for the test
@@ -127,9 +131,7 @@ func (s *reachabilityService) CreateConnectivityTest(ctx context.Context, req *p
127131
DestIpRange: "10.0.0.0/20",
128132
DisplayName: "default-route-f17b1d9b115a2c1e",
129133
NetworkUri: "projects/${projectId}/global/networks/default",
130-
NextHop: "network gateway",
131134
NextHopType: pb.RouteInfo_NEXT_HOP_NETWORK,
132-
RouteScope: pb.RouteInfo_NETWORK,
133135
RouteType: pb.RouteInfo_SUBNET,
134136
Uri: "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e",
135137
},
@@ -200,6 +202,7 @@ func (s *reachabilityService) UpdateConnectivityTest(ctx context.Context, req *p
200202
}
201203
}
202204
obj.UpdateTime = timestamppb.New(time.Now())
205+
obj.Protocol = "TCP"
203206

204207
if err := s.storage.Update(ctx, fqn, obj); err != nil {
205208
return nil, err

mockgcp/mocknetworkmanagement/service.go

+5
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,10 @@ func (s *MockService) NewHTTPMux(ctx context.Context, conn *grpc.ClientConn) (ht
6666
return nil, err
6767
}
6868

69+
mux.RewriteError = func(ctx context.Context, error *httpmux.ErrorResponse) {
70+
if error.Code == 404 {
71+
error.Errors = nil
72+
}
73+
}
6974
return mux, nil
7075
}

mockgcp/mocknetworkmanagement/testdata/connectivitytest/crud/_http.log

+7-21
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ X-Xss-Protection: 0
8686
"protocol": "TCP",
8787
"sourceIp": "10.0.0.1",
8888
"sourceNetworkUri": "projects/${projectId}/global/networks/default",
89-
"sourcePort": 55896
89+
"sourcePort": "12345"
9090
},
9191
"forwardTraceId": 1,
9292
"steps": [
@@ -122,9 +122,7 @@ X-Xss-Protection: 0
122122
"destIpRange": "10.0.0.0/20",
123123
"displayName": "default-route-f17b1d9b115a2c1e",
124124
"networkUri": "projects/${projectId}/global/networks/default",
125-
"nextHop": "network gateway",
126125
"nextHopType": "NEXT_HOP_NETWORK",
127-
"routeScope": "NETWORK",
128126
"routeType": "SUBNET",
129127
"uri": "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e"
130128
},
@@ -188,7 +186,7 @@ X-Xss-Protection: 0
188186
"protocol": "TCP",
189187
"sourceIp": "10.0.0.1",
190188
"sourceNetworkUri": "projects/${projectId}/global/networks/default",
191-
"sourcePort": 55896
189+
"sourcePort": "12345"
192190
},
193191
"forwardTraceId": 1,
194192
"steps": [
@@ -224,9 +222,7 @@ X-Xss-Protection: 0
224222
"destIpRange": "10.0.0.0/20",
225223
"displayName": "default-route-f17b1d9b115a2c1e",
226224
"networkUri": "projects/${projectId}/global/networks/default",
227-
"nextHop": "network gateway",
228225
"nextHopType": "NEXT_HOP_NETWORK",
229-
"routeScope": "NETWORK",
230226
"routeType": "SUBNET",
231227
"uri": "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e"
232228
},
@@ -289,7 +285,7 @@ X-Xss-Protection: 0
289285
"protocol": "TCP",
290286
"sourceIp": "10.0.0.1",
291287
"sourceNetworkUri": "projects/${projectId}/global/networks/default",
292-
"sourcePort": 55896
288+
"sourcePort": "12345"
293289
},
294290
"forwardTraceId": 1,
295291
"steps": [
@@ -325,9 +321,7 @@ X-Xss-Protection: 0
325321
"destIpRange": "10.0.0.0/20",
326322
"displayName": "default-route-f17b1d9b115a2c1e",
327323
"networkUri": "projects/${projectId}/global/networks/default",
328-
"nextHop": "network gateway",
329324
"nextHopType": "NEXT_HOP_NETWORK",
330-
"routeScope": "NETWORK",
331325
"routeType": "SUBNET",
332326
"uri": "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e"
333327
},
@@ -390,7 +384,7 @@ X-Xss-Protection: 0
390384
"protocol": "TCP",
391385
"sourceIp": "10.0.0.1",
392386
"sourceNetworkUri": "projects/${projectId}/global/networks/default",
393-
"sourcePort": 55896
387+
"sourcePort": "12345"
394388
},
395389
"forwardTraceId": 1,
396390
"steps": [
@@ -426,9 +420,7 @@ X-Xss-Protection: 0
426420
"destIpRange": "10.0.0.0/20",
427421
"displayName": "default-route-f17b1d9b115a2c1e",
428422
"networkUri": "projects/${projectId}/global/networks/default",
429-
"nextHop": "network gateway",
430423
"nextHopType": "NEXT_HOP_NETWORK",
431-
"routeScope": "NETWORK",
432424
"routeType": "SUBNET",
433425
"uri": "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e"
434426
},
@@ -483,7 +475,7 @@ Content-Type: application/json
483475
"protocol": "TCP",
484476
"sourceIp": "10.0.0.1",
485477
"sourceNetworkUri": "projects/${projectId}/global/networks/default",
486-
"sourcePort": 55896
478+
"sourcePort": "12345"
487479
},
488480
"forwardTraceId": 1,
489481
"steps": [
@@ -519,9 +511,7 @@ Content-Type: application/json
519511
"destIpRange": "10.0.0.0/20",
520512
"displayName": "default-route-f17b1d9b115a2c1e",
521513
"networkUri": "projects/${projectId}/global/networks/default",
522-
"nextHop": "network gateway",
523514
"nextHopType": "NEXT_HOP_NETWORK",
524-
"routeScope": "NETWORK",
525515
"routeType": "SUBNET",
526516
"uri": "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e"
527517
},
@@ -618,7 +608,7 @@ X-Xss-Protection: 0
618608
"protocol": "TCP",
619609
"sourceIp": "10.0.0.1",
620610
"sourceNetworkUri": "projects/${projectId}/global/networks/default",
621-
"sourcePort": 55896
611+
"sourcePort": "12345"
622612
},
623613
"forwardTraceId": 1,
624614
"steps": [
@@ -654,9 +644,7 @@ X-Xss-Protection: 0
654644
"destIpRange": "10.0.0.0/20",
655645
"displayName": "default-route-f17b1d9b115a2c1e",
656646
"networkUri": "projects/${projectId}/global/networks/default",
657-
"nextHop": "network gateway",
658647
"nextHopType": "NEXT_HOP_NETWORK",
659-
"routeScope": "NETWORK",
660648
"routeType": "SUBNET",
661649
"uri": "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e"
662650
},
@@ -720,7 +708,7 @@ X-Xss-Protection: 0
720708
"protocol": "TCP",
721709
"sourceIp": "10.0.0.1",
722710
"sourceNetworkUri": "projects/${projectId}/global/networks/default",
723-
"sourcePort": 55896
711+
"sourcePort": "12345"
724712
},
725713
"forwardTraceId": 1,
726714
"steps": [
@@ -756,9 +744,7 @@ X-Xss-Protection: 0
756744
"destIpRange": "10.0.0.0/20",
757745
"displayName": "default-route-f17b1d9b115a2c1e",
758746
"networkUri": "projects/${projectId}/global/networks/default",
759-
"nextHop": "network gateway",
760747
"nextHopType": "NEXT_HOP_NETWORK",
761-
"routeScope": "NETWORK",
762748
"routeType": "SUBNET",
763749
"uri": "projects/${projectId}/global/routes/default-route-f17b1d9b115a2c1e"
764750
},

pkg/controller/direct/maputils.go

+12
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,18 @@ func Enum_FromProto[U ProtoEnum](mapCtx *MapContext, v U) *string {
145145
return &s
146146
}
147147

148+
func ZeroBasedEnum_FromProto[U ProtoEnum](mapCtx *MapContext, v U) *string {
149+
descriptor := v.Descriptor()
150+
151+
val := descriptor.Values().ByNumber(protoreflect.EnumNumber(v))
152+
if val == nil {
153+
mapCtx.Errorf("unknown enum value %d", v)
154+
return nil
155+
}
156+
s := string(val.Name())
157+
return &s
158+
}
159+
148160
func EnumSlice_FromProto[U ProtoEnum](mapCtx *MapContext, in []U) []string {
149161
if in == nil {
150162
return nil
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// +tool:controller-client
16+
// proto.service: google.cloud.networkmanagement.v1.ReachabilityService
17+
18+
package networkmanagement
19+
20+
import (
21+
"context"
22+
"fmt"
23+
24+
api "cloud.google.com/go/networkmanagement/apiv1"
25+
"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/config"
26+
)
27+
28+
func newReachabilityClient(ctx context.Context, config *config.ControllerConfig) (*api.ReachabilityClient, error) {
29+
opts, err := config.RESTClientOptions()
30+
if err != nil {
31+
return nil, err
32+
}
33+
client, err := api.NewReachabilityRESTClient(ctx, opts...)
34+
if err != nil {
35+
return nil, fmt.Errorf("building networkmanagement reachability client: %w", err)
36+
}
37+
return client, err
38+
}

0 commit comments

Comments
 (0)