Skip to content

Commit

Permalink
#3536 show resource status for VS, TS and IL (#3564)
Browse files Browse the repository at this point in the history
* #3536 show resource status for VS, TS and IL

* #3536 fix uts
  • Loading branch information
vidyasagar-m authored Sep 23, 2024
1 parent dc732f8 commit d378057
Show file tree
Hide file tree
Showing 10 changed files with 393 additions and 89 deletions.
17 changes: 12 additions & 5 deletions config/apis/cis/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ type VirtualServer struct {

// VirtualServerStatus is the status of the VirtualServer resource.
type VirtualServerStatus struct {
VSAddress string `json:"vsAddress,omitempty"`
StatusOk string `json:"status,omitempty"`
VSAddress string `json:"vsAddress,omitempty"`
StatusOk string `json:"status,omitempty"`
LastUpdated metav1.Time `json:"lastUpdated,omitempty"`
Error string `json:"error,omitempty"`
}

// VirtualServerSpec is the spec of the VirtualServer resource.
Expand Down Expand Up @@ -257,7 +259,10 @@ type IngressLink struct {

// IngressLinkStatus is the status of the ingressLink resource.
type IngressLinkStatus struct {
VSAddress string `json:"vsAddress,omitempty"`
VSAddress string `json:"vsAddress,omitempty"`
LastUpdated metav1.Time `json:"lastUpdated,omitempty"`
Error string `json:"error,omitempty"`
StatusOk string `json:"status,omitempty"`
}

// IngressLinkSpec is Spec for IngressLink
Expand Down Expand Up @@ -297,8 +302,10 @@ type TransportServer struct {

// TransportServerStatus is the status of the VirtualServer resource.
type TransportServerStatus struct {
VSAddress string `json:"vsAddress,omitempty"`
StatusOk string `json:"status,omitempty"`
VSAddress string `json:"vsAddress,omitempty"`
StatusOk string `json:"status,omitempty"`
LastUpdated metav1.Time `json:"lastUpdated,omitempty"`
Error string `json:"error,omitempty"`
}

// TransportServerSpec is the spec of the VirtualServer resource.
Expand Down
1 change: 1 addition & 0 deletions docs/RELEASE-NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Added Functionality
* Multi Cluster
* Support to add HA services in extendedServiceReferences for Transport Servers. Yet to be supported with Virtual Server
* CRD
* `Issue 3536 <https:/F5Networks/k8s-bigip-ctlr/issues/3536>`_: Support CRD status for VS, TS and IngressLink

Bug Fixes
````````````
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,10 @@ spec:
status:
type: string
default: Pending
lastUpdated:
type: string
error:
type: string
additionalPrinterColumns:
- name: host
type: string
Expand Down Expand Up @@ -806,6 +810,10 @@ spec:
status:
type: string
default: Pending
lastUpdated:
type: string
error:
type: string
additionalPrinterColumns:
- name: virtualServerAddress
type: string
Expand Down Expand Up @@ -1027,6 +1035,13 @@ spec:
properties:
vsAddress:
type: string
status:
type: string
default: pending
lastUpdated:
type: string
error:
type: string
additionalPrinterColumns:
- name: IPAMVSAddress
type: string
Expand Down
6 changes: 4 additions & 2 deletions pkg/controller/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ func (agent *Agent) agentWorker() {

if len(agent.incomingTenantDeclMap) == 0 {
log.Infof("%v[AS3] No tenants found in request", getRequestPrefix(rsConfig.reqId))
// notify resourceStatusUpdate response handler for resourcestatus update
agent.notifyRscStatusHandler(rsConfig.reqId, false)
agent.declUpdate.Unlock()
continue
}
Expand Down Expand Up @@ -357,10 +359,10 @@ func (agent *Agent) notifyRscStatusHandler(id int, overwriteCfg bool) {

rscUpdateMeta := resourceStatusMeta{
id,
make(map[string]struct{}),
make(map[string]tenantResponse),
}
for tenant := range agent.retryTenantDeclMap {
rscUpdateMeta.failedTenants[tenant] = struct{}{}
rscUpdateMeta.failedTenants[tenant] = agent.retryTenantDeclMap[tenant].tenantResponse
}
// If triggerred from retry block, process the previous successful request completely
if !overwriteCfg {
Expand Down
41 changes: 24 additions & 17 deletions pkg/controller/postManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,13 @@ func (postMgr *PostManager) httpPOST(request *http.Request) (*http.Response, map
return httpResp, response
}

func (postMgr *PostManager) updateTenantResponseCode(code int, id string, tenant string, isDeleted bool) {
func (postMgr *PostManager) updateTenantResponseCode(code int, id string, tenant string, isDeleted bool, message string) {
// Update status for a specific tenant if mentioned, else update the response for all tenants
if tenant != "" {
postMgr.tenantResponseMap[tenant] = tenantResponse{code, id, isDeleted}
postMgr.tenantResponseMap[tenant] = tenantResponse{code, id, isDeleted, message}
} else {
for tenant := range postMgr.tenantResponseMap {
postMgr.tenantResponseMap[tenant] = tenantResponse{code, id, false}
postMgr.tenantResponseMap[tenant] = tenantResponse{code, id, false, message}
}
}
}
Expand All @@ -227,7 +227,7 @@ func (postMgr *PostManager) handleResponseStatusOK(responseMap map[string]interf
tenant, ok2 := v["tenant"].(string)
if ok1 && ok2 {
log.Debugf("[AS3]%v Response from BIG-IP: code: %v --- tenant:%v --- message: %v", postMgr.postManagerPrefix, v["code"], v["tenant"], v["message"])
postMgr.updateTenantResponseCode(int(code), "", tenant, updateTenantDeletion(tenant, declaration))
postMgr.updateTenantResponseCode(int(code), "", tenant, updateTenantDeletion(tenant, declaration), "")
} else {
unknownResponse = true
}
Expand Down Expand Up @@ -275,7 +275,7 @@ func (postMgr *PostManager) getTenantConfigStatus(id string) {
return
}
// reset task id, so that any unknownResponse failed will go to post call in the next retry
postMgr.updateTenantResponseCode(int(code), "", tenant, updateTenantDeletion(tenant, declaration))
postMgr.updateTenantResponseCode(int(code), "", tenant, updateTenantDeletion(tenant, declaration), "")
if _, ok := v["response"]; ok {
log.Debugf("[AS3]%v Response from BIG-IP: code: %v --- tenant:%v --- message: %v %v", postMgr.postManagerPrefix, v["code"], v["tenant"], v["message"], v["response"])
} else {
Expand All @@ -297,7 +297,7 @@ func (postMgr *PostManager) getTenantConfigStatus(id string) {
}
} else if httpResp.StatusCode != http.StatusServiceUnavailable {
// reset task id, so that any failed tenants will go to post call in the next retry
postMgr.updateTenantResponseCode(httpResp.StatusCode, "", "", false)
postMgr.updateTenantResponseCode(httpResp.StatusCode, "", "", false, "")
}
if !postMgr.LogAS3Response && unknownResponse {
postMgr.logAS3Response(responseMap)
Expand All @@ -315,10 +315,10 @@ func (postMgr *PostManager) handleMultiStatus(responseMap map[string]interface{}
tenant, ok2 := v["tenant"].(string)
if ok1 && ok2 {
if code != 200 {
postMgr.updateTenantResponseCode(int(code), "", tenant, false)
postMgr.updateTenantResponseCode(int(code), "", tenant, false, fmt.Sprintf("Big-IP Responded with error code: %v -- verify the logs for detailed error", v["code"]))
log.Errorf("%v[AS3]%v Error response from BIG-IP: code: %v --- tenant:%v --- message: %v", getRequestPrefix(id), postMgr.postManagerPrefix, v["code"], v["tenant"], v["message"])
} else {
postMgr.updateTenantResponseCode(int(code), "", tenant, updateTenantDeletion(tenant, declaration))
postMgr.updateTenantResponseCode(int(code), "", tenant, updateTenantDeletion(tenant, declaration), "")
log.Debugf("[AS3]%v Response from BIG-IP: code: %v --- tenant:%v --- message: %v", postMgr.postManagerPrefix, v["code"], v["tenant"], v["message"])
}
} else {
Expand All @@ -339,38 +339,44 @@ func (postMgr *PostManager) handleMultiStatus(responseMap map[string]interface{}
func (postMgr *PostManager) handleResponseAccepted(responseMap map[string]interface{}) {
// traverse all response results
if respId, ok := (responseMap["id"]).(string); ok {
postMgr.updateTenantResponseCode(http.StatusAccepted, respId, "", false)
postMgr.updateTenantResponseCode(http.StatusAccepted, respId, "", false, "")
log.Debugf("[AS3]%v Response from BIG-IP: code 201 id %v, waiting %v seconds to poll response", postMgr.postManagerPrefix, respId, timeoutMedium)
} else {
postMgr.logAS3Response(responseMap)
}
}

func (postMgr *PostManager) handleResponseStatusServiceUnavailable(responseMap map[string]interface{}, id int) {
var message string
if err, ok := (responseMap["error"]).(map[string]interface{}); ok {
log.Errorf("%v[AS3]%v Big-IP Responded with error code: %v", getRequestPrefix(id), postMgr.postManagerPrefix, err["code"])
message = fmt.Sprintf("Big-IP Responded with error code: %v -- verify the logs for detailed error", err["code"])
} else {
postMgr.logAS3Response(responseMap)
}
log.Debugf("[AS3]%v Response from BIG-IP: BIG-IP is busy, waiting %v seconds and re-posting the declaration", postMgr.postManagerPrefix, timeoutMedium)
postMgr.updateTenantResponseCode(http.StatusServiceUnavailable, "", "", false)
postMgr.updateTenantResponseCode(http.StatusServiceUnavailable, "", "", false, message)
}

func (postMgr *PostManager) handleResponseStatusNotFound(responseMap map[string]interface{}, id int) {
var unknownResponse bool
var message string
if err, ok := (responseMap["error"]).(map[string]interface{}); ok {
log.Errorf("%v[AS3]%v Big-IP Responded with error code: %v", getRequestPrefix(id), postMgr.postManagerPrefix, err["code"])
message = fmt.Sprintf("Big-IP Responded with error code: %v -- verify the logs for detailed error", err["code"])
} else {
unknownResponse = true
message = "Big-IP Responded with error -- verify the logs for detailed error"
}
if postMgr.LogAS3Response || unknownResponse {
postMgr.logAS3Response(responseMap)
}
postMgr.updateTenantResponseCode(http.StatusNotFound, "", "", false)
postMgr.updateTenantResponseCode(http.StatusNotFound, "", "", false, message)
}

func (postMgr *PostManager) handleResponseStatusUnAuthorized(responseMap map[string]interface{}, id int) {
var unknownResponse bool
var message string
if _, ok := responseMap["code"].(float64); ok {
if _, ok := responseMap["message"].(string); ok {
log.Errorf("%v[AS3]%v authentication failed,"+
Expand All @@ -379,14 +385,16 @@ func (postMgr *PostManager) handleResponseStatusUnAuthorized(responseMap map[str
log.Errorf("%v[AS3]%v authentication failed,"+
" Error response from BIGIP with status code: 401", getRequestPrefix(id), postMgr.postManagerPrefix)
}
message = "authentication failed, Error response from BIGIP with status code: 401 -- verify the logs for detailed error"
} else {
unknownResponse = true
message = "Big-IP Responded with error -- verify the logs for detailed error"
}

if postMgr.LogAS3Response || unknownResponse {
postMgr.logAS3Response(responseMap)
}
postMgr.updateTenantResponseCode(http.StatusUnauthorized, "", "", false)
postMgr.updateTenantResponseCode(http.StatusUnauthorized, "", "", false, message)
}

func (postMgr *PostManager) handleResponseOthers(responseMap map[string]interface{}, id int) {
Expand All @@ -398,26 +406,25 @@ func (postMgr *PostManager) handleResponseOthers(responseMap map[string]interfac
tenant, ok2 := v["tenant"].(string)
if ok1 && ok2 {
log.Errorf("%v[AS3]%v Response from BIG-IP: code: %v --- tenant:%v --- message: %v", getRequestPrefix(id), postMgr.postManagerPrefix, v["code"], v["tenant"], v["message"])
postMgr.updateTenantResponseCode(int(code), "", tenant, false)
postMgr.updateTenantResponseCode(int(code), "", tenant, false, fmt.Sprintf("Big-IP Responded with error code: %v -- verify the logs for detailed error", code))
} else {
unknownResponse = true
}
} else {
unknownResponse = true
}

}
} else if err, ok := (responseMap["error"]).(map[string]interface{}); ok {
log.Errorf("%v[AS3]%v Big-IP Responded with error code: %v", getRequestPrefix(id), postMgr.postManagerPrefix, err["code"])
if code, ok := err["code"].(float64); ok {
postMgr.updateTenantResponseCode(int(code), "", "", false)
postMgr.updateTenantResponseCode(int(code), "", "", false, fmt.Sprintf("Big-IP Responded with error code: %v -- verify the logs for detailed error", err["code"]))
} else {
unknownResponse = true
}
} else {
unknownResponse = true
if code, ok := responseMap["code"].(float64); ok {
postMgr.updateTenantResponseCode(int(code), "", "", false)
postMgr.updateTenantResponseCode(int(code), "", "", false, fmt.Sprintf("Big-IP Responded with error code: %v -- verify the logs for detailed error", code))
}
}
if postMgr.LogAS3Response || unknownResponse {
Expand Down Expand Up @@ -775,7 +782,7 @@ func (postMgr *PostManager) updateRetryMap(tenant string, resp tenantResponse, t
} else {
postMgr.retryTenantDeclMap[tenant] = &tenantParams{
tenDecl,
tenantResponse{resp.agentResponseCode, resp.taskId, false},
tenantResponse{resp.agentResponseCode, resp.taskId, false, resp.message},
}
}
}
Expand Down
43 changes: 39 additions & 4 deletions pkg/controller/responseHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controller

import (
"container/list"
"errors"
ficV1 "github.com/F5Networks/f5-ipam-controller/pkg/ipamapis/apis/fic/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"strings"
Expand Down Expand Up @@ -75,9 +76,12 @@ func (ctlr *Controller) responseHandler(respChan chan resourceStatusMeta) {
}
virtual := obj.(*cisapiv1.VirtualServer)
if virtual.Namespace+"/"+virtual.Name == rscKey {
if _, found := rscUpdateMeta.failedTenants[partition]; !found {
if tenantResponse, found := rscUpdateMeta.failedTenants[partition]; found {
// update the status for virtual server as tenant posting is failed
ctlr.updateResourceStatus(VirtualServer, virtual, "", "", errors.New(tenantResponse.message))
} else {
// update the status for virtual server as tenant posting is success
ctlr.updateVirtualServerStatus(virtual, virtual.Status.VSAddress, "Ok")
ctlr.updateResourceStatus(VirtualServer, virtual, virtual.Status.VSAddress, "Ok", nil)
// Update Corresponding Service Status of Type LB
for _, pool := range virtual.Spec.Pools {
var svcNamespace string
Expand Down Expand Up @@ -114,9 +118,12 @@ func (ctlr *Controller) responseHandler(respChan chan resourceStatusMeta) {
}
virtual := obj.(*cisapiv1.TransportServer)
if virtual.Namespace+"/"+virtual.Name == rscKey {
if _, found := rscUpdateMeta.failedTenants[partition]; !found {
if tenantResponse, found := rscUpdateMeta.failedTenants[partition]; found {
// update the status for transport server as tenant posting is failed
ctlr.updateResourceStatus(TransportServer, virtual, "", "", errors.New(tenantResponse.message))
} else {
// update the status for transport server as tenant posting is success
ctlr.updateTransportServerStatus(virtual, virtual.Status.VSAddress, "Ok")
ctlr.updateResourceStatus(TransportServer, virtual, virtual.Status.VSAddress, "Ok", nil)
// Update Corresponding Service Status of Type LB
var svcNamespace string
if virtual.Spec.Pool.ServiceNamespace != "" {
Expand All @@ -132,6 +139,34 @@ func (ctlr *Controller) responseHandler(respChan chan resourceStatusMeta) {
}
}
}

case IngressLink:
// update status
crInf, ok := ctlr.getNamespacedCRInformer(ns)
if !ok {
log.Debugf("IngressLink Informer not found for namespace: %v", ns)
continue
}
obj, exist, err := crInf.ilInformer.GetIndexer().GetByKey(rscKey)
if err != nil {
log.Debugf("Could not fetch IngressLink: %v: %v", rscKey, err)
continue
}
if !exist {
log.Debugf("IngressLink Not Found: %v", rscKey)
continue
}
il := obj.(*cisapiv1.IngressLink)
if il.Namespace+"/"+il.Name == rscKey {
if tenantResponse, found := rscUpdateMeta.failedTenants[partition]; found {
// update the status for ingresslink as tenant posting is failed
ctlr.updateResourceStatus(IngressLink, il, "", "", errors.New(tenantResponse.message))
} else {
// update the status for ingresslink as tenant posting is success
ctlr.updateResourceStatus(IngressLink, il, il.Status.VSAddress, "Ok", nil)
}
}

case Route:
if _, found := rscUpdateMeta.failedTenants[partition]; found {
// TODO : distinguish between a 503 and an actual failure
Expand Down
3 changes: 2 additions & 1 deletion pkg/controller/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ type (

resourceStatusMeta struct {
id int
failedTenants map[string]struct{}
failedTenants map[string]tenantResponse
}

resourceRef struct {
Expand Down Expand Up @@ -842,6 +842,7 @@ type (
agentResponseCode int
taskId string
isDeleted bool
message string
}

tenantParams struct {
Expand Down
Loading

0 comments on commit d378057

Please sign in to comment.