Skip to content

Commit

Permalink
Remove AVI SE ingress allow rule in the Networkinfo controller (#669)
Browse files Browse the repository at this point in the history
Signed-off-by: Wenqi Qiu <[email protected]>
  • Loading branch information
wenqiq authored Aug 15, 2024
1 parent d5107ef commit 52b9aad
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 407 deletions.
21 changes: 0 additions & 21 deletions pkg/controllers/networkinfo/networkinfo_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,6 @@ func (r *NetworkInfoReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return common.ResultRequeueAfter10sec, err
}

isShared, err := r.Service.IsSharedVPCNamespaceByNS(obj.GetNamespace())
if err != nil {
log.Error(err, "failed to check if namespace is shared", "Namespace", obj.GetNamespace())
return common.ResultRequeue, err
}
if r.Service.NSXConfig.NsxConfig.UseAVILoadBalancer && !isShared {
err = r.Service.CreateOrUpdateAVIRule(createdVpc, obj.Namespace)
if err != nil {
state := &v1alpha1.VPCState{
Name: *createdVpc.DisplayName,
VPCPath: *createdVpc.Path,
DefaultSNATIP: "",
LoadBalancerIPAddresses: "",
PrivateIPs: nc.PrivateIPs,
}
log.Error(err, "update avi rule failed, would retry exponentially", "NetworkInfo", req.NamespacedName, "state", state)
// updateFail(r, &ctx, obj, &err, r.Client, state)
// return common.ResultRequeueAfter10sec, err
}
}

snatIP, path, cidr := "", "", ""
parts := strings.Split(nc.VPCConnectivityProfile, "/")
if len(parts) < 1 {
Expand Down
242 changes: 0 additions & 242 deletions pkg/nsx/services/vpc/vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import (
"context"
"errors"
"fmt"
"math"
"net"
"strings"
"sync"

"github.com/vmware/vsphere-automation-sdk-go/runtime/data"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/cache"

"github.com/vmware-tanzu/nsx-operator/pkg/apis/vpc/v1alpha1"
Expand Down Expand Up @@ -710,245 +707,6 @@ func (s *VPCService) Cleanup(ctx context.Context) error {
return nil
}

func (service *VPCService) needUpdateRule(rule *model.Rule, externalCIDRs []string) bool {
des := rule.DestinationGroups
currentDesSet := sets.Set[string]{}
for _, group := range des {
currentDesSet.Insert(group)
}
if len(externalCIDRs) != len(currentDesSet) {
return true
}
for _, cidr := range externalCIDRs {
if !currentDesSet.Has(cidr) {
return true
}
}
return false
}

func (service *VPCService) getIpblockCidr(blocks []string) (result []string, err error) {
for _, cidr := range blocks {
ipblock := service.PubIpblockStore.GetByKey(cidr)
if ipblock == nil {
// in case VPC using the new ipblock, search the ipblock from nsxt
// return error, and retry next time when the ipblock is synced into store
err = errors.New("ipblock not found")
log.Error(err, "failed to get public ipblock", "path", cidr)
query := fmt.Sprintf("%s:%s AND visibility:EXTERNAL", common.ResourceType, common.ResourceTypeIPBlock)
count, searcherr := service.SearchResource(common.ResourceTypeIPBlock, query, service.PubIpblockStore, nil)
if searcherr != nil {
log.Error(searcherr, "failed to query public ipblock", "query", query)
} else {
log.V(1).Info("query public ipblock", "count", count)
}
return
} else {
result = append(result, *ipblock.Cidr)
}
}
return
}

func (service *VPCService) CreateOrUpdateAVIRule(vpc *model.Vpc, namespace string) error {
if !enableAviAllowRule {
return nil
}
if !nsxutil.IsLicensed(nsxutil.FeatureDFW) {
log.Info("avi rule cannot be created or updated due to no DFW license")
return nil
}
vpcInfo, err := common.ParseVPCResourcePath(*vpc.Path)
if err != nil {
log.Error(err, "failed to parse VPC Resource Path: ", *vpc.Path)
return err
}
orgId := vpcInfo.OrgID
projectId := vpcInfo.ProjectID
ruleId := AviSEIngressAllowRuleId
groupId := VPCAviSEGroupId
spId := VpcDefaultSecurityPolicyId

if !service.checkAVISecurityPolicyExist(orgId, projectId, *vpc.Id, spId) {
return errors.New("avi security policy not found")
}
allowrule, err := service.getAVIAllowRule(orgId, projectId, *vpc.Id, spId, ruleId)
if err != nil {
log.Info("avi rule is not found, creating")
}
externalCIDRs, err := service.getIpblockCidr(vpc.ExternalIpv4Blocks)
if err != nil {
return err
}
log.Info("avi rule get external cidr", "cidr", externalCIDRs)
if allowrule != nil {
if !service.needUpdateRule(allowrule, externalCIDRs) {
log.Info("avi rule is not changed, skip updating avi rule")
return nil
} else {
log.Info("avi rule changed", "previous", allowrule.DestinationGroups, "current", externalCIDRs)
}
}

group, err := service.getorCreateAVIGroup(orgId, projectId, *vpc.Id, groupId)
if err != nil {
log.Error(err, "failed to get avi group", "group", groupId)
return err
}

newrule, err := service.buildAVIAllowRule(vpc, externalCIDRs, *group.Path, ruleId, projectId)
log.Info("creating avi rule", "rule", newrule)
if err != nil {
log.Error(err, "failed to build avi rule", "rule", newrule)
return err
}

err = service.NSXClient.VPCRuleClient.Patch(orgId, projectId, *vpc.Id, spId, *newrule.Id, *newrule)
err = nsxutil.NSXApiError(err)
if err != nil {
log.Error(err, "failed to create avi rule", "rule", newrule)
return err
}
nsxrule, err := service.NSXClient.VPCRuleClient.Get(orgId, projectId, *vpc.Id, spId, *newrule.Id)
err = nsxutil.NSXApiError(err)
if err != nil {
log.Error(err, "failed to get avi rule", "rule", nsxrule)
return err
}
service.RuleStore.Add(&nsxrule)
log.Info("created avi rule successfully")
return nil
}

func (service *VPCService) getorCreateAVIGroup(orgId string, projectId string, vpcId string, groupId string) (*model.Group, error) {
groupPtr, err := service.getAVIGroup(orgId, projectId, vpcId, groupId)
if err != nil {
log.Info("create avi group", "group", groupId)
groupPtr, err = service.createAVIGroup(orgId, projectId, vpcId, groupId)
if err != nil {
log.Error(err, "failed to create avi group", "group", groupId)
return groupPtr, err
}
service.GroupStore.Add(groupPtr)
}
return groupPtr, err
}

func (service *VPCService) buildAVIGroupTag(vpcId string) []model.Tag {
return []model.Tag{
{
Scope: common.String(common.TagScopeCluster),
Tag: common.String(service.NSXConfig.Cluster),
},
{
Scope: common.String(common.TagScopeVersion),
Tag: common.String(strings.Join(common.TagValueVersion, ".")),
},
{
Scope: common.String(common.TagScopeGroupType),
Tag: common.String(common.TagValueGroupAvi),
},
}
}

func (service *VPCService) createAVIGroup(orgId string, projectId string, vpcId string, groupId string) (*model.Group, error) {
group := model.Group{}
group.Tags = service.buildAVIGroupTag(vpcId)
expression := service.buildExpression("Condition", "VpcSubnet", "AVI_SUBNET_LB|", "Tag", "EQUALS", "EQUALS")
group.Expression = []*data.StructValue{expression}
group.DisplayName = common.String(groupId)

err := service.NSXClient.VpcGroupClient.Patch(orgId, projectId, vpcId, groupId, group)
err = nsxutil.NSXApiError(err)
if err != nil {
return &group, err
}
nsxgroup, err := service.NSXClient.VpcGroupClient.Get(orgId, projectId, vpcId, groupId)
err = nsxutil.NSXApiError(err)
return &nsxgroup, err
}

func (service *VPCService) buildExpression(resource_type, member_type, value, key, operator, scope_op string) *data.StructValue {
return data.NewStructValue(
"",
map[string]data.DataValue{
"resource_type": data.NewStringValue(resource_type),
"member_type": data.NewStringValue(member_type),
"value": data.NewStringValue(value),
"key": data.NewStringValue(key),
"operator": data.NewStringValue(operator),
"scope_operator": data.NewStringValue(scope_op),
},
)
}

func (service *VPCService) buildAVIAllowRule(obj *model.Vpc, externalCIDRs []string, groupId, ruleId, projectId string) (*model.Rule, error) {
rule := &model.Rule{}
rule.Action = common.String(model.Rule_ACTION_ALLOW)
rule.Direction = common.String(model.Rule_DIRECTION_IN_OUT)
rule.Scope = append(rule.Scope, groupId)
rule.SequenceNumber = common.Int64(math.MaxInt32 - 1)
rule.DestinationGroups = externalCIDRs
rule.SourceGroups = append(rule.SourceGroups, "Any")
name := fmt.Sprintf("PROJECT-%s-VPC-%s-%s", projectId, *obj.Id, ruleId)
rule.DisplayName = common.String(name)
rule.Id = common.String(ruleId)
rule.Services = []string{"ANY"}
rule.IsDefault = common.Bool(true)
tags := []model.Tag{
{
Scope: common.String(common.TagScopeCluster),
Tag: common.String(service.NSXConfig.Cluster),
},
{
Scope: common.String(common.TagScopeVersion),
Tag: common.String(strings.Join(common.TagValueVersion, ".")),
},
}
rule.Tags = tags
return rule, nil
}

func (service *VPCService) getAVIAllowRule(orgId string, projectId string, vpcId string, spId string, ruleId string) (*model.Rule, error) {
key := fmt.Sprintf(RuleKey, orgId, projectId, vpcId, spId, ruleId)
rule := service.RuleStore.GetByKey(key)
if rule == nil {
log.Info("avi rule not found", "key", key)
return nil, errors.New("avi rule not found")
}
return rule, nil
}

func (service *VPCService) getAVIGroup(orgId string, projectId string, vpcId string, groupId string) (*model.Group, error) {
key := fmt.Sprintf(GroupKey, orgId, projectId, vpcId, groupId)
group := service.GroupStore.GetByKey(key)
var err error
if group == nil {
log.Info("avi se group not found", "key", key)
err = errors.New("avi se group not found")
}
return group, err
}

// checkAVISecurityPolicyExist returns true if security policy for that VPC already exists
// this security policy created by NSXT once VPC created
// if not found, wait until it created
func (service *VPCService) checkAVISecurityPolicyExist(orgId string, projectId string, vpcId string, spId string) bool {
key := fmt.Sprintf(SecurityPolicyKey, orgId, projectId, vpcId, spId)
sp := service.SecurityPolicyStore.GetByKey(key)
if sp != nil {
return true
}
nsxtsp, err := service.NSXClient.VPCSecurityClient.Get(orgId, projectId, vpcId, spId)
err = nsxutil.NSXApiError(err)
if err != nil {
log.Error(err, "failed to get avi security policy", "key", key)
return false
}
service.SecurityPolicyStore.Add(&nsxtsp)
return true
}

func (service *VPCService) ListVPCInfo(ns string) []common.VPCResourceInfo {
var VPCInfoList []common.VPCResourceInfo
vpcs := service.GetVPCsByNamespace(ns) // Transparently call the VPCService.GetVPCsByNamespace method
Expand Down
Loading

0 comments on commit 52b9aad

Please sign in to comment.