Skip to content

Commit

Permalink
Set VPCNetworkConfiguration status when no ExternalIPBlocks exist in …
Browse files Browse the repository at this point in the history
…VPCConnectivityProfile (vmware-tanzu#730)

* Set VPCNetworkConfiguration status when no ExternalIPBlocks exist in VPCConnectivityProfile

Signed-off-by: Wenqi Qiu <[email protected]>
  • Loading branch information
wenqiq authored Sep 3, 2024
1 parent 2a4a9a0 commit a08ea89
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 16 deletions.
7 changes: 4 additions & 3 deletions pkg/apis/vpc/v1alpha1/condition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
type ConditionType string

const (
Ready ConditionType = "Ready"
GatewayConnectionReady ConditionType = "GatewayConnectionReady"
AutoSnatEnabled ConditionType = "AutoSnatEnabled"
Ready ConditionType = "Ready"
GatewayConnectionReady ConditionType = "GatewayConnectionReady"
AutoSnatEnabled ConditionType = "AutoSnatEnabled"
ExternalIPBlocksConfigured ConditionType = "ExternalIPBlocksConfigured"
)

// Condition defines condition of custom resource.
Expand Down
16 changes: 9 additions & 7 deletions pkg/controllers/networkinfo/networkinfo_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,6 @@ func (r *NetworkInfoReconciler) Reconcile(ctx context.Context, req ctrl.Request)
updateFail(r, ctx, obj, &err, r.Client, nil)
return common.ResultRequeueAfter10sec, err
}
vpcNetworkConfiguration := &v1alpha1.VPCNetworkConfiguration{}
err := r.Client.Get(ctx, types.NamespacedName{Name: ncName}, vpcNetworkConfiguration)
if err != nil {
log.Error(err, "failed to get VPCNetworkConfiguration", "Name", ncName)
updateFail(r, ctx, obj, &err, r.Client, nil)
return common.ResultRequeueAfter10sec, err
}
setVPCNetworkConfigurationStatusWithGatewayConnection(ctx, r.Client, vpcNetworkConfiguration, gatewayConnectionReady, reason)
} else {
log.Info("skipping reconciling the network info because the system gateway connection is not ready", "NetworkInfo", req.NamespacedName)
Expand Down Expand Up @@ -141,6 +134,15 @@ func (r *NetworkInfoReconciler) Reconcile(ctx context.Context, req ctrl.Request)
updateFail(r, ctx, obj, &err, r.Client, nil)
return common.ResultRequeueAfter10sec, err
}

if ncName == commonservice.SystemVPCNetworkConfigurationName {
if len(vpcConnectivityProfile.ExternalIpBlocks) == 0 {
setVPCNetworkConfigurationStatusWithNoExternalIPBlock(ctx, r.Client, vpcNetworkConfiguration, false)
log.Error(err, "there is no ExternalIPBlock in VPC ConnectivityProfile", "VPC", req.NamespacedName)
} else {
setVPCNetworkConfigurationStatusWithNoExternalIPBlock(ctx, r.Client, vpcNetworkConfiguration, true)
}
}
isEnableAutoSNAT := func() bool {
if vpcConnectivityProfile.ServiceGateway == nil || vpcConnectivityProfile.ServiceGateway.Enable == nil {
return false
Expand Down
85 changes: 82 additions & 3 deletions pkg/controllers/networkinfo/networkinfo_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func TestNetworkInfoReconciler_Reconcile(t *testing.T) {
return false, nil
})
patches.ApplyMethodSeq(reflect.TypeOf(r.Service.Service.NSXClient.VPCConnectivityProfilesClient), "Get", []gomonkey.OutputCell{{
Values: gomonkey.Params{model.VpcConnectivityProfile{}, nil},
Values: gomonkey.Params{model.VpcConnectivityProfile{ExternalIpBlocks: []string{"fake-ip-block"}}, nil},
Times: 1,
}})
patches.ApplyMethod(reflect.TypeOf(r.Service), "GetNSXLBSPath", func(_ *vpc.VPCService, _ string) string {
Expand Down Expand Up @@ -203,7 +203,7 @@ func TestNetworkInfoReconciler_Reconcile(t *testing.T) {
return false, nil
})
patches.ApplyMethodSeq(reflect.TypeOf(r.Service.Service.NSXClient.VPCConnectivityProfilesClient), "Get", []gomonkey.OutputCell{{
Values: gomonkey.Params{model.VpcConnectivityProfile{}, nil},
Values: gomonkey.Params{model.VpcConnectivityProfile{ExternalIpBlocks: []string{"fake-ip-block"}}, nil},
Times: 1,
}})
patches.ApplyMethod(reflect.TypeOf(r.Service), "GetNSXLBSPath", func(_ *vpc.VPCService, _ string) string {
Expand Down Expand Up @@ -308,6 +308,7 @@ func TestNetworkInfoReconciler_Reconcile(t *testing.T) {
})
patches.ApplyMethodSeq(reflect.TypeOf(r.Service.Service.NSXClient.VPCConnectivityProfilesClient), "Get", []gomonkey.OutputCell{{
Values: gomonkey.Params{model.VpcConnectivityProfile{
ExternalIpBlocks: []string{"fake-ip-block"},
ServiceGateway: &model.VpcServiceGatewayConfig{
Enable: servicecommon.Bool(true),
NatConfig: &model.VpcNatConfig{
Expand Down Expand Up @@ -386,7 +387,8 @@ func TestNetworkInfoReconciler_Reconcile(t *testing.T) {
})
patches.ApplyMethodSeq(reflect.TypeOf(r.Service.Service.NSXClient.VPCConnectivityProfilesClient), "Get", []gomonkey.OutputCell{{
Values: gomonkey.Params{model.VpcConnectivityProfile{
ServiceGateway: nil,
ExternalIpBlocks: []string{"fake-ip-block"},
ServiceGateway: nil,
}, nil},
Times: 1,
}})
Expand Down Expand Up @@ -459,6 +461,7 @@ func TestNetworkInfoReconciler_Reconcile(t *testing.T) {
})
patches.ApplyMethodSeq(reflect.TypeOf(r.Service.Service.NSXClient.VPCConnectivityProfilesClient), "Get", []gomonkey.OutputCell{{
Values: gomonkey.Params{model.VpcConnectivityProfile{
ExternalIpBlocks: []string{"fake-ip-block"},
ServiceGateway: &model.VpcServiceGatewayConfig{
Enable: servicecommon.Bool(true),
NatConfig: &model.VpcNatConfig{
Expand Down Expand Up @@ -491,6 +494,82 @@ func TestNetworkInfoReconciler_Reconcile(t *testing.T) {
want: common.ResultNormal,
wantErr: false,
},
{
name: "VPCNetworkConfigurationStatusWithNoExternalIPBlockInSystemVPC",
prepareFunc: func(t *testing.T, r *NetworkInfoReconciler, ctx context.Context) (patches *gomonkey.Patches) {
assert.NoError(t, r.Client.Create(ctx, &v1alpha1.NetworkInfo{
ObjectMeta: metav1.ObjectMeta{
Namespace: requestArgs.req.Namespace,
Name: requestArgs.req.Name,
},
}))
assert.NoError(t, r.Client.Create(ctx, &v1alpha1.VPCNetworkConfiguration{
ObjectMeta: metav1.ObjectMeta{
Name: "system",
},
}))
patches = gomonkey.ApplyMethod(reflect.TypeOf(r.Service), "GetNetworkconfigNameFromNS", func(_ *vpc.VPCService, _ string) (string, error) {
return servicecommon.SystemVPCNetworkConfigurationName, nil

})
patches.ApplyMethod(reflect.TypeOf(r.Service), "GetVPCNetworkConfig", func(_ *vpc.VPCService, _ string) (servicecommon.VPCNetworkConfigInfo, bool) {
return servicecommon.VPCNetworkConfigInfo{
VPCConnectivityProfile: "/orgs/default/projects/nsx_operator_e2e_test/vpc-connectivity-profiles/default",
Org: "default",
NSXProject: "project-quality",
}, true

})
patches.ApplyFunc(getGatewayConnectionStatus, func(_ context.Context, _ *v1alpha1.VPCNetworkConfiguration) (bool, string, error) {
return false, "", nil
})
patches.ApplyMethod(reflect.TypeOf(r.Service), "ValidateGatewayConnectionStatus", func(_ *vpc.VPCService, _ *servicecommon.VPCNetworkConfigInfo) (bool, string, error) {
return true, "", nil
})
patches.ApplyMethod(reflect.TypeOf(r.Service), "CreateOrUpdateVPC", func(_ *vpc.VPCService, _ *v1alpha1.NetworkInfo, _ *servicecommon.VPCNetworkConfigInfo) (*model.Vpc, error) {
return &model.Vpc{
DisplayName: servicecommon.String("vpc-name"),
Path: servicecommon.String("/orgs/default/projects/project-quality/vpcs/fake-vpc"),
Id: servicecommon.String("vpc-id"),
}, nil
})
patches.ApplyMethod(reflect.TypeOf(r.Service), "IsSharedVPCNamespaceByNS", func(_ *vpc.VPCService, _ string) (bool, error) {
return false, nil
})
patches.ApplyMethodSeq(reflect.TypeOf(r.Service.Service.NSXClient.VPCConnectivityProfilesClient), "Get", []gomonkey.OutputCell{{
Values: gomonkey.Params{model.VpcConnectivityProfile{
ServiceGateway: nil,
}, nil},
Times: 1,
}})
patches.ApplyFunc(setVPCNetworkConfigurationStatusWithNoExternalIPBlock,
func(_ context.Context, _ client.Client, _ *v1alpha1.VPCNetworkConfiguration, _ bool) {
t.Log("setVPCNetworkConfigurationStatusWithNoExternalIPBlock")
})

patches.ApplyMethod(reflect.TypeOf(r.Service), "GetNSXLBSPath", func(_ *vpc.VPCService, _ string) string {
return "lbs-path"

})
patches.ApplyMethod(reflect.TypeOf(r.Service), "GetDefaultSNATIP", func(_ *vpc.VPCService, _ model.Vpc) (string, error) {
return "snat-ip", nil

})
patches.ApplyFunc(updateSuccess,
func(_ *NetworkInfoReconciler, _ context.Context, o *v1alpha1.NetworkInfo, _ client.Client, _ *v1alpha1.VPCState, _ string, _ string) {
})
patches.ApplyFunc(setVPCNetworkConfigurationStatusWithSnatEnabled,
func(_ context.Context, _ client.Client, _ *v1alpha1.VPCNetworkConfiguration, autoSnatEnabled bool) {
if autoSnatEnabled {
assert.FailNow(t, "should set VPCNetworkConfiguration status with AutoSnatEnabled=false")
}
})
return patches
},
args: requestArgs,
want: common.ResultNormal,
wantErr: false,
},
}

for _, tt := range tests {
Expand Down
21 changes: 21 additions & 0 deletions pkg/controllers/networkinfo/networkinfo_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,27 @@ func setVPCNetworkConfigurationStatusWithSnatEnabled(ctx context.Context, client
}
}

func setVPCNetworkConfigurationStatusWithNoExternalIPBlock(ctx context.Context, client client.Client, nc *v1alpha1.VPCNetworkConfiguration, hasExternalIPs bool) {
newCondition := v1alpha1.Condition{
Type: v1alpha1.ExternalIPBlocksConfigured,
LastTransitionTime: metav1.Time{},
}
if !hasExternalIPs {
newCondition.Status = v1.ConditionFalse
newCondition.Reason = svccommon.ReasonNoExternalIPBlocksInVPCConnectivityProfile
newCondition.Message = "No External IP Blocks exist in VPC Connectivity Profile"
} else {
newCondition.Status = v1.ConditionTrue
}
if mergeStatusCondition(ctx, &nc.Status.Conditions, &newCondition) {
if err := client.Status().Update(ctx, nc); err != nil {
log.Error(err, "update VPCNetworkConfiguration status failed", "VPCNetworkConfiguration", nc.Name)
return
}
}
log.Info("Updated VPCNetworkConfiguration status", "VPCNetworkConfiguration", nc.Name, "status", newCondition)
}

// TODO: abstract the logic of merging condition for common, which can be used by the other controller, e.g. security policy
func mergeStatusCondition(ctx context.Context, conditions *[]v1alpha1.Condition, newCondition *v1alpha1.Condition) bool {
existingCondition := getExistingConditionOfType(newCondition.Type, *conditions)
Expand Down
7 changes: 4 additions & 3 deletions pkg/nsx/services/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ var (
ResourceTypeNode = "HostTransportNode"

// Reasons for verification of gateway connection in day0
ReasonEdgeMissingInProject = "EdgeMissingInProject"
ReasonDistributedGatewayConnectionNotSupported = "DistributedGatewayConnectionNotSupported"
ReasonGatewayConnectionNotSet = "GatewayConnectionNotSet"
ReasonEdgeMissingInProject = "EdgeMissingInProject"
ReasonDistributedGatewayConnectionNotSupported = "DistributedGatewayConnectionNotSupported"
ReasonGatewayConnectionNotSet = "GatewayConnectionNotSet"
ReasonNoExternalIPBlocksInVPCConnectivityProfile = "ExternalIPBlockMissingInProfile"
)

type Service struct {
Expand Down

0 comments on commit a08ea89

Please sign in to comment.