Skip to content

Commit e1c0b5f

Browse files
Added support for Proxy Enabled Application Profile in WCP env
1 parent 62f08b9 commit e1c0b5f

12 files changed

+428
-0
lines changed

Diff for: ako-clean/cleanup.go

+15
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ func (cfg *AKOCleanupConfig) Cleanup(ctx context.Context) error {
109109
cleanupL4PolicySets,
110110
cleanupPoolGroups,
111111
cleanupPools,
112+
cleanupAppProfiles,
112113
func() error {
113114
if VPCMode {
114115
return nil
@@ -140,6 +141,7 @@ func (cfg *AKOCleanupConfig) Cleanup(ctx context.Context) error {
140141
}
141142
return nil
142143
}
144+
143145
func getCloudInVPCMode() (string, error) {
144146
uri := "/api/cloud/"
145147
aviRestClientPool := avicache.SharedAVIClients(lib.GetTenant())
@@ -406,6 +408,19 @@ func cleanupPools() error {
406408
return deleteAviResource("/api/pool", pools)
407409
}
408410

411+
func cleanupAppProfiles() error {
412+
aviObjCache := avicache.SharedAviObjCache()
413+
appProfiles := make(map[string][]string)
414+
for _, key := range aviObjCache.AppProfileCache.AviGetAllKeys() {
415+
if _, ok := appProfiles[key.Namespace]; !ok {
416+
appProfiles[key.Namespace] = []string{}
417+
}
418+
appProfCache, _ := aviObjCache.AppProfileCache.AviCacheGet(key)
419+
appProfiles[key.Namespace] = append(appProfiles[key.Namespace], appProfCache.(*avicache.AviAppProfileCache).Uuid)
420+
}
421+
return deleteAviResource("/api/applicationprofile", appProfiles)
422+
}
423+
409424
/*
410425
Below section is only applicable for T1 based Supervisor deployments
411426
*/

Diff for: internal/cache/cache_utils.go

+10
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,16 @@ type AviVrfCache struct {
349349
CloudConfigCksum uint32
350350
}
351351

352+
type AviAppProfileCache struct {
353+
Name string
354+
Tenant string
355+
Uuid string
356+
Type string
357+
CloudConfigCksum uint32
358+
EnableProxyProtocol bool
359+
LastModified string
360+
}
361+
352362
func (v *AviVsCache) GetVSCopy() (*AviVsCache, bool) {
353363
v.VSCacheLock.RLock()
354364
defer v.VSCacheLock.RUnlock()

Diff for: internal/cache/controller_obj_cache.go

+53
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type AviObjCache struct {
5454
VsCacheMeta *AviCache
5555
VsCacheLocal *AviCache
5656
ClusterStatusCache *AviCache
57+
AppProfileCache *AviCache
5758
}
5859

5960
func NewAviObjCache() *AviObjCache {
@@ -71,6 +72,7 @@ func NewAviObjCache() *AviObjCache {
7172
c.VrfCache = NewAviCache()
7273
c.PKIProfileCache = NewAviCache()
7374
c.ClusterStatusCache = NewAviCache()
75+
c.AppProfileCache = NewAviCache()
7476
return &c
7577
}
7678

@@ -129,6 +131,12 @@ func (c *AviObjCache) AviObjCachePopulate(client []*clients.AviClient, version s
129131
if err != nil {
130132
return vsCacheCopy, allVsKeys, err
131133
}
134+
if utils.IsWCP() && tenant == lib.GetAdminTenant() {
135+
err := c.AviObjAppProfileCachePopulate(client[0])
136+
if err != nil {
137+
return vsCacheCopy, allVsKeys, err
138+
}
139+
}
132140
// Populate the VS cache
133141
utils.AviLog.Infof("Refreshing all object cache")
134142
c.AviRefreshObjectCache(client, cloud, tenant)
@@ -1917,6 +1925,51 @@ func (c *AviObjCache) AviObjVrfCachePopulate(client *clients.AviClient, cloud st
19171925
return nil
19181926
}
19191927

1928+
func (c *AviObjCache) AviObjAppProfileCachePopulate(client *clients.AviClient) error {
1929+
appName := lib.GetProxyEnabledApplicationProfileName()
1930+
uri := "/api/applicationprofile?name=" + appName + "&include_name=true" + "&created_by=" + lib.GetAKOUser()
1931+
result, err := lib.AviGetCollectionRaw(client, uri)
1932+
if err != nil {
1933+
utils.AviLog.Warnf("Get uri %v returned err for app profile %v", uri, err)
1934+
return err
1935+
}
1936+
elems := make([]json.RawMessage, result.Count)
1937+
err = json.Unmarshal(result.Results, &elems)
1938+
if err != nil {
1939+
utils.AviLog.Warnf("Failed to unmarshal app profile data, err: %v", err)
1940+
return err
1941+
}
1942+
for i := 0; i < result.Count; i++ {
1943+
appProf := models.ApplicationProfile{}
1944+
err = json.Unmarshal(elems[i], &appProf)
1945+
if err != nil {
1946+
utils.AviLog.Warnf("Failed to unmarshal app profile data, err: %v", err)
1947+
continue
1948+
}
1949+
if appProf.Name == nil || appProf.UUID == nil || appProf.TCPAppProfile == nil {
1950+
utils.AviLog.Warnf("Incomplete app profile data unmarshalled, %s", utils.Stringify(appProf))
1951+
continue
1952+
}
1953+
tenant := getTenantFromTenantRef(*appProf.TenantRef)
1954+
appType := *appProf.Type
1955+
ppe := *appProf.TCPAppProfile.ProxyProtocolEnabled
1956+
cksum := lib.AppProfileChecksum(appName, tenant, appType, ppe)
1957+
appProfileCacheObj := AviAppProfileCache{
1958+
Name: appName,
1959+
Tenant: tenant,
1960+
Uuid: *appProf.UUID,
1961+
Type: appType,
1962+
LastModified: *appProf.LastModified,
1963+
CloudConfigCksum: cksum,
1964+
EnableProxyProtocol: ppe,
1965+
}
1966+
k := NamespaceName{Namespace: tenant, Name: appName}
1967+
c.AppProfileCache.AviCacheAdd(k, &appProfileCacheObj)
1968+
utils.AviLog.Infof("Adding app profile to cache during refresh %s", utils.Stringify(appProfileCacheObj))
1969+
}
1970+
return nil
1971+
}
1972+
19201973
func (c *AviObjCache) AviObjVSCachePopulate(client *clients.AviClient, cloud string, vsCacheCopy *[]NamespaceName, overrideUri ...NextPage) error {
19211974
var rest_response interface{}
19221975
akoUser := lib.AKOUser

Diff for: internal/k8s/ako_init.go

+5
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,11 @@ func (c *AviController) FullSyncK8s(sync bool) error {
12261226
}
12271227
}
12281228

1229+
appProfileLabel := lib.GetModelName(lib.GetAdminTenant(), lib.GetProxyEnabledApplicationProfileName())
1230+
appKey := lib.ApplicationProfile + "/" + appProfileLabel
1231+
lib.IncrementQueueCounter(utils.ObjectIngestionLayer)
1232+
nodes.DequeueIngestion(appKey, true)
1233+
12291234
//Ingress Section
12301235
if utils.GetInformers().IngressInformer != nil {
12311236
for namespace := range acceptedNamespaces {

Diff for: internal/lib/constants.go

+2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ const (
163163
PriorityLabel = "PriorityLabel"
164164
SSLKeyCert = "SSLKeyandCertificate"
165165
PKIProfile = "PKI Profile"
166+
ApplicationProfile = "ApplicationProfile"
166167
PassthroughPG = "Passthrough PG"
167168
Passthroughpool = "Passthrough pool"
168169
PassthroughVS = "Passthrough VirtualService"
@@ -261,6 +262,7 @@ const (
261262
CalicoIPv6AddressAnnotation = "projectcalico.org/IPv6Address"
262263
AntreaTransportAddressAnnotation = "node.antrea.io/transport-addresses"
263264
TenantAnnotation = "ako.vmware.com/tenant-name"
265+
GwProxyProtocolEnableAnnotation = "iaas.vmware.com/proxy-protocol-enabled"
264266

265267
// Specifies command used in namespace event handler
266268
NsFilterAdd = "ADD"

Diff for: internal/lib/lib.go

+9
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,11 @@ func GetVrf() string {
689689
return VRFContext
690690
}
691691

692+
// One proxy enabled app profile per cluster
693+
func GetProxyEnabledApplicationProfileName() string {
694+
return GetClusterName()
695+
}
696+
692697
func GetVPCMode() bool {
693698
if vpcMode, _ := strconv.ParseBool(os.Getenv(utils.VPC_MODE)); vpcMode {
694699
return true
@@ -1450,6 +1455,10 @@ func L4PolicyChecksum(ports []int64, protocols []string, pools []string, ingesti
14501455
return checksum
14511456
}
14521457

1458+
func AppProfileChecksum(name, tenant, appType string, ppe bool) uint32 {
1459+
return utils.Hash(name + tenant + appType + strconv.FormatBool(ppe))
1460+
}
1461+
14531462
func IsNodePortMode() bool {
14541463
nodePortType := os.Getenv(SERVICE_TYPE)
14551464
if nodePortType == NODE_PORT {

Diff for: internal/nodes/avi_app_profile_translator.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2019-2020 VMware, Inc.
3+
* All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
15+
package nodes
16+
17+
import (
18+
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/lib"
19+
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/pkg/utils"
20+
)
21+
22+
func (o *AviObjectGraph) BuildAppProfileGraph(ns, name, key string) {
23+
o.Lock.Lock()
24+
defer o.Lock.Unlock()
25+
aviAppProfNode := &AviAppProfileNode{
26+
Name: name,
27+
Tenant: ns,
28+
Type: lib.AllowedL4ApplicationProfile,
29+
EnableProxyProtocol: true,
30+
}
31+
o.AddModelNode(aviAppProfNode)
32+
aviAppProfNode.CalculateCheckSum()
33+
utils.AviLog.Infof("key: %s, Added app profile node %s", key, name)
34+
utils.AviLog.Debugf("key: %s, app profile node: [%v]", key, utils.Stringify(aviAppProfNode))
35+
}

Diff for: internal/nodes/avi_model_advl4_translator.go

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package nodes
1616

1717
import (
1818
"fmt"
19+
"strconv"
1920
"strings"
2021

2122
"github.com/vmware/load-balancer-and-ingress-services-for-kubernetes/internal/lib"
@@ -138,6 +139,12 @@ func (o *AviObjectGraph) ConstructAdvL4VsNode(gatewayName, namespace, key string
138139

139140
avi_vs_meta.PortProto = portProtocols
140141
avi_vs_meta.ApplicationProfile = utils.DEFAULT_L4_APP_PROFILE
142+
if proxyProtoEnb, ok := gw.GetAnnotations()[lib.GwProxyProtocolEnableAnnotation]; ok {
143+
proxyProtocolEnabled, err := strconv.ParseBool(proxyProtoEnb)
144+
if err == nil && proxyProtocolEnabled {
145+
avi_vs_meta.ApplicationProfile = lib.GetProxyEnabledApplicationProfileName()
146+
}
147+
}
141148

142149
avi_vs_meta.NetworkProfile = getNetworkProfile(isSCTP, isTCP, isUDP)
143150

Diff for: internal/nodes/avi_model_nodes.go

+45
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,51 @@ func (o *AviObjectGraph) GetAviVRF() []*AviVrfNode {
357357
}
358358
return aviVrf
359359
}
360+
361+
type AviAppProfileNode struct {
362+
Name string
363+
Tenant string
364+
Type string
365+
EnableProxyProtocol bool
366+
CloudConfigCksum uint32
367+
}
368+
369+
func (v *AviAppProfileNode) GetNodeType() string {
370+
return "AppProfileNode"
371+
}
372+
373+
func (v *AviAppProfileNode) CopyNode() AviModelNode {
374+
newNode := AviAppProfileNode{}
375+
bytes, err := json.Marshal(v)
376+
if err != nil {
377+
utils.AviLog.Warnf("Unable to marshal AviAppProfileNode: %s", err)
378+
}
379+
err = json.Unmarshal(bytes, &newNode)
380+
if err != nil {
381+
utils.AviLog.Warnf("Unable to unmarshal AviAppProfileNode: %s", err)
382+
}
383+
return &newNode
384+
}
385+
386+
func (v *AviAppProfileNode) GetCheckSum() uint32 {
387+
v.CalculateCheckSum()
388+
return v.CloudConfigCksum
389+
}
390+
391+
func (v *AviAppProfileNode) CalculateCheckSum() {
392+
v.CloudConfigCksum = lib.AppProfileChecksum(v.Name, v.Tenant, v.Type, v.EnableProxyProtocol)
393+
}
394+
395+
func (o *AviObjectGraph) GetAviAppProfileNode() *AviAppProfileNode {
396+
for _, model := range o.modelNodes {
397+
appProfNode, ok := model.(*AviAppProfileNode)
398+
if ok {
399+
return appProfNode
400+
}
401+
}
402+
return nil
403+
}
404+
360405
func (o *AviObjectGraph) GetIstioNodes() (*AviPkiProfileNode, *AviTLSKeyCertNode) {
361406
var pkiNode *AviPkiProfileNode
362407
var sslNode *AviTLSKeyCertNode

Diff for: internal/nodes/dequeue_ingestion.go

+9
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,15 @@ func DequeueIngestion(key string, fullsync bool) {
289289
}
290290
}
291291
}
292+
if objType == lib.ApplicationProfile && utils.IsWCP() {
293+
modelName := lib.GetModelName(namespace, name)
294+
aviModelGraph := NewAviObjectGraph()
295+
aviModelGraph.BuildAppProfileGraph(namespace, name, key)
296+
ok := saveAviModel(modelName, aviModelGraph, key)
297+
if ok && !fullsync {
298+
PublishKeyToRestLayer(modelName, key, sharedQueue)
299+
}
300+
}
292301
if objType == utils.Namespace && utils.IsWCP() && isNamespaceDeleted(name) {
293302
cache := avicache.SharedAviObjCache()
294303
vsKeys := cache.VsCacheMeta.AviCacheGetAllParentVSKeys()

0 commit comments

Comments
 (0)