Skip to main content
Skip table of contents

Upgrade Guide CX4.9.2 to CX4.9.3

  1. Clone the CX repository on the target server

    CODE
    # Create CX-4.9.3 directory from root
    mkdir CX-4.9.3
    # Navigate to CX-4.9.3
    cd CX-4.9.3
    # Clone the 4.9.3 branch of cim-solution repository
    git clone -b CX-4.9.3 https://efcx:RecRpsuH34yqp56YRFUb@gitlab.expertflow.com/cim/cim-solution.git $HOME/CX-4.9.3
    # Navigate to root(previous) directory
    cd ..
  2. Update helm repo

    CODE
    helm repo update expertflow
  3. Change the directory to the current deployment of CX

    CODE
    change directory to following path in current deployment
    cd CX-4.9.2/kubernetes
  4. Update the APISIX helm chart

    CODE
    #Update APSIX helm chart
    Edit/update the values file helm-values/apisix-custom-values.yaml with
    
    
    Add the following annotations  under annotations section.
        
        annotations: 
            nginx.ingress.kubernetes.io/proxy-body-size: "6m"
            nginx.ingress.kubernetes.io/proxy-read-timeout: "600s"
            nginx.ingress.kubernetes.io/proxy-send-timeout: "600s"
            nginx.ingress.kubernetes.io/proxy-connect-timeout: "60s"
    
    
    
    helm upgrade --install --namespace ef-external --values helm-values/apisix-custom-values.yaml apisix expertflow/apisix --version 4.2.2
  5. Update Conversation Controller ConfigMaps

    CODE
    #copy actions directory to current release 
    1) Copy From CX-4.9.3/kubernetes/pre-deployment/conversation-Controller/actions/participant_role_changed.py To /pre-deployment/conversation-Controller/actions
    2) Copy From CX-4.9.3/kubernetes/pre-deployment/conversation-Controller/utils/utility.py To pre-deployment/conversation-Controller/utils
    3) Delete and Create the ConfigMap
       kubectl -n expertflow delete configmap ef-conversation-controller-actions-cm
       kubectl -n expertflow delete configmap ef-conversation-controller-actions-utils-cm
       kubectl -n expertflow create configmap ef-conversation-controller-actions-cm --from-file=pre-deployment/conversation-Controller/actions
       kubectl -n expertflow create configmap ef-conversation-controller-actions-utils-cm --from-file=pre-deployment/conversation-Controller/utils
    4) kubectl -n expertflow delete pod <conversation-manager-pod-name>
  6. Update the ActiveMQ chart

    CODE
    Update the amq tag in helm-values/ef-activemq-custom-values.yaml
    tag: 6.1.6-alpine-zulu-K8s-4.9.3
    
    helm upgrade --install=true  --namespace=ef-external --values=helm-values/ef-activemq-custom-values.yaml activemq expertflow/activemq
  7. Update the CX-Transflux chart

    CODE
    #change the directory to transflux
    cd transflux 
    
    #Change transflux tag 
    vi helm-values/cx-transflux-custom-values.yaml
    
    tag: 4.9.3_b-CIM-29672
    
    #Re-deploy CX-Transflux
    helm upgrade --install --namespace expertflow   --set global.efCxReleaseName="ef-cx"  cx-transflux --debug --values helm-values/cx-transflux-custom-values.yaml expertflow/transflux --version 4.9.1
  8. Update the Agent-Desk helm chart

    CODE
    #Update Agent Desk helm chart
    Edit/update the values file helm-values/cx-agent-desk-custom-values.yaml with
    
    Add following new config under global section:
      apisixInternalServiceHostname: "apisix-data-plane.ef-external.svc.cluster.local" 
      apisixInternalServicePort: 80
    Add following new environment variables under unified-agent  extraEnvVars:
          - name: AUTO_ANSWER_DELAY
            value: "5000"
          - name: SOCKET_TIMEOUT
            value: "20000"
    
    
    
    Add following plugins under apisixRoutes below plugins: for every route of Agent Desk.
    
             customPlugins:
               - name: client-control
                 enable: true
                 config:
                   max_body_size: 6291456
    
    Change the following "main" path in  grafana under apisixRoutes
          paths: ["/grafana", "/grafana/*"]
    
    
    unified-agent Tag: 4.9.3 (4.9_b-CIM-29774)
    
    helm upgrade --install --namespace expertflow   --set global.efCxReleaseName="ef-cx"  cx-agent-desk  --debug --values helm-values/cx-agent-desk-custom-values.yaml expertflow/agent-desk --version 4.9.3
  9. Update the Channel helm chart

    CODE
    # Update Channel helm chart
    Edit/update the values file helm-values/cx-channels-custom-values.yaml with following 
    
    Add following new config under global section:
      apisixInternalServiceHostname: "apisix-data-plane.ef-external.svc.cluster.local" 
      apisixInternalServicePort: 80
    
    Telegram-Connector Tag: 4.9.3
    Twilio-Connector Tag: 4.9.3
    Linkedin-Connector Tag: 4.9.3
    ms-exchange-email-connector Tag: 4.9.3
    
    helm upgrade --install --namespace expertflow  --set global.efCxReleaseName="ef-cx"   --debug   cx-channels --values  helm-values/cx-channels-custom-values.yaml  expertflow/channels --version 4.9.3
  10. Update the Core helm chart

    CODE
    #Update Core Component helm chart
    Edit/update the values file helm-values/ef-cx-custom-values.yaml with
    
    Add following new config under global section:
      apisixInternalServiceHostname: "apisix-data-plane.ef-external.svc.cluster.local" 
      apisixInternalServicePort: 80 
      efCommonVars_RSA_SERVER_URL: ""
      efCommonVars_RSA_CLIENT_KEY: ""
      efCommonVars_RSA_CLIENT_ID: ""
    
      
      
    Update the following environment variable in web-channel-manager under extraEnvVar
            - name: CCM_URL
              value: "http://apisix-data-plane.ef-external.svc.cluster.local:80/internal-wcm-to-ccm/"
    
    
    Add the following variable in agent-manager under extraEnvVar
    
            - name: RSA_SERVER_URL
              value: '{{ .Values.global.efCommonVars_RSA_SERVER_URL }}'
            - name: RSA_CLIENT_KEY
              value: '{{ .Values.global.efCommonVars_RSA_CLIENT_KEY }}'
            - name: RSA_CLIENT_ID
              value: '{{ .Values.global.efCommonVars_RSA_CLIENT_ID }}'
            - name: SOCKET_PING_INTERVAL
              value: "25000"
            - name: SOCKET_PING_TIMEOUT
              value: "20000"  
    
    Add the following variable in unified-admin under extraEnvVar
    
            - name: UNIFIED_ADMIN_URL
              value: "http://{{ .Release.Name }}-unified-admin-svc.{{ .Release.Namespace }}.svc:3000"
            - name: FORM_DATA_ACTIVITY
              value: 'http://{{ .Release.Name }}-conversation-manager-svc.{{ .Release.Namespace }}.svc:8080'
            - name: RSA_SERVER_URL
              value: '{{ .Values.global.efCommonVars_RSA_SERVER_URL }}'
            - name: RSA_CLIENT_KEY
              value: '{{ .Values.global.efCommonVars_RSA_CLIENT_KEY }}'
            - name: RSA_CLIENT_ID
              value: '{{ .Values.global.efCommonVars_RSA_CLIENT_ID }}'
      
    
    
    Add following new route in unified-admin under apisixRoutes:
          - nameSuffix: "default-404-handler"
            enabled: false
            priority: -200 # Very low priority
            paths: ["/*"] # Catches all paths not matched by higher priority routes
            # No backend is needed as the mocking plugin will generate the response
            backendServicePort: 80 # Dummy, but APISIX schema might require it.
            backendServiceName: "dummy-service" # Dummy
            plugins:
              enableAuth: false # Typically, 404 pages don't require auth
              enableRewrite: false
              enableCors: false # Or configure as needed for your 404 page
              customPlugins:
                - name: "mocking"
                  enable: false
                  config:
                    response_status: 404
                    response_headers:
                      Content-Type: "text/html; charset=utf-8"
                      X-Custom-Error-Page: "true"
                    response_example: |
                      <!DOCTYPE html>
                      <html lang="en">
                      <head>
                          <meta charset="UTF-8">
                          <meta name="viewport" content="width=device-width, initial-scale=1.0">
                          <title>Page Not Found</title>
                          <style>
                              body { font-family: Arial, sans-serif; text-align: center; padding: 50px; color: #333; }
                              h1 { font-size: 48px; color: #555; }
                              p { font-size: 18px; }
                              a { color: #007bff; text-decoration: none; }
                          </style>
                      </head>
                      <body>
                          <h1>404 - Page Not Found</h1>
                          <p>Sorry, the page you are looking for does not exist or has been moved.</p>
                          <p><a href="/">Return to Homepage</a></p>
                          <hr>
                          <p><small>Request ID: $request_id</small></p>
                          </body>
                      </html>
     
    
    
    
    
    Add following plugin under apisixRoutes below plugins: for every route of customer-widget,unified-admin.
    
             customPlugins:
               - name: client-control
                 enable: true
                 config:
                   max_body_size: 6291456
                   
    Add following new routes in agent-manager under apisixRoutes:
          # New Route 4: Send SMS OTP (Unsecured)
          - nameSuffix: "send-sms-otp-unsecured"
            enabled: true
            priority: 10 # Same high priority as other unsecured paths
            paths: ["/agent-manager/agent/send-sms-otp*"]
            backendServicePort: 3000
            plugins:
              enableAuth: false
              enableRewrite: true
              rewriteStripPrefix: false # Use custom rewrite
              rewriteRegexUriFrom: "^/agent-manager(/agent/send-sms-otp.*)$" # Capture /agent/send-sms-otp...
              rewriteRegexUriTo: "$1"
      
          # New Route 5: Register Phone (Unsecured)
          - nameSuffix: "register-phone-unsecured"
            enabled: true
            priority: 10 # Same high priority
            paths: ["/agent-manager/agent/register-phone*"]
            backendServicePort: 3000
            plugins:
              enableAuth: false
              enableRewrite: true
              rewriteStripPrefix: false # Use custom rewrite
              rewriteRegexUriFrom: "^/agent-manager(/agent/register-phone.*)$" # Capture /agent/register-phone...
              rewriteRegexUriTo: "$1"
          # New Route 6: Validate OTP (Unsecured)
          - nameSuffix: "validate-otp-unsecured"
            enabled: true
            priority: 10 # Same high priority
            paths: ["/agent-manager/agent/validate-otp*"]
            backendServicePort: 3000
            plugins:
              enableAuth: false
              enableRewrite: true
              rewriteStripPrefix: false # Use custom rewrite
              rewriteRegexUriFrom: "^/agent-manager(/agent/validate-otp.*)$" # Capture /agent/validate-otp...
              rewriteRegexUriTo: "$1"                
    
    
    Add following plugin under Agent-Manager apisixRoutes --> Main Route --> Plugin --> customPlugins
                - name: "error-page-rewrite"
                  enable: false
                  config:
                    # For each status code you want to override:
                    body: | # Default body if no specific status code matches below
                      <!DOCTYPE html><html><head><title>Error</title></head><body><h1>An Unexpected Error Occurred</h1><p>Please try again later. Request ID: $request_id</p></body></html>
                    status_codes:
                      # For a 500 error, redirect to an internal error page service
                      - 500
                      # For a 502 error, provide custom content directly
                      - 502
                      # For a 503 error, redirect to a different page
                      - 503
                    # Define what to do for each status code
                    # This is an array of rewrite rules. APISIX will pick the first one that matches.
                    # You can serve content directly or redirect to an error page service.
                    rewrites:
                      # Rule for 500 errors
                      - status_code: 500
                        # Option 1: Redirect to a full HTML page served by another internal service
                        # This service (e.g., 'error-pages-svc') would serve /error_pages/500.html
                        # target_uri: "/_internal_error_page_handler" # Path to an internal APISIX route
                        # target_host: "error-pages-svc.your-namespace.svc" # K8s service for error pages
                        # target_scheme: "http"
                        # OR Option 2: Provide the body directly (can be limited in complexity)
                        body: "<!DOCTYPE html><html><head><title>Internal Server Error</title></head><body><h1>500 - Internal Server Error</h1><p>We are experiencing technical difficulties. Please try again later. Request ID: $request_id</p></body></html>"
                        headers:
                          Content-Type: "text/html; charset=utf-8"
                      # Rule for 502 errors
                      - status_code: 502
                        body: "<!DOCTYPE html><html><head><title>Bad Gateway</title></head><body><h1>502 - Bad Gateway</h1><p>The server received an invalid response from an upstream server. Request ID: $request_id</p></body></html>"
                        headers:
                          Content-Type: "text/html; charset=utf-8"
                      # Rule for 503 errors - redirect to a static maintenance page
                      # - status_code: 503
                      #   target_uri: "https://status.example.com/maintenance.html" # External redirect
                      #   is_redirect: true
                      
                                       
                      
                      
    Add following new route in ccm under apisixRoutes:
          - nameSuffix: "internal-wcm-access"
            enabled: true
            priority: 20
            hosts:
              # This string will be processed by `tpl` (via common.tplvalues.render) in the template
              - "{{  .Values.global.apisixInternalServiceHostname  }}"
            paths:
              - "/internal-wcm-to-ccm/*"
            #backendServiceName: "ef-cx-ccm-svc" # Adjust if your naming differs
            backendServicePort: 8081
            #backendNamespace: "expertflow" # Assuming ccm service is in expertflow namespace
            plugins:
              enableAuth: false
              enableRewrite: true
              rewriteStripPrefix: false
              rewriteRegexUriFrom: "^/internal-wcm-to-ccm/(.*)"
              rewriteRegexUriTo: "/$1"
              enableCors: false
              customPlugins:
                - name: "real-ip"
                  enable: true
                  config:
                    source: "X-Forwarded-For"
                    trusted_addresses: ["10.42.0.0/16"] # Replace with your K8s Pod CIDR
                - name: "limit-count"
                  enable: true
                  config:
                    count: 10
                    time_window: 1
                    key_type: "var"
                    key: "remote_addr"
                    rejected_code: 429
                    rejected_msg: "{\"error\":\"Internal rate limit exceeded.\"}"
                    show_limit_quota_header: true
                    
                    
    Add the following new Route in file-engine under apisixRoutes:
          - nameSuffix: "public-svg-downloads"
            enabled: false
            priority: 10
            paths:
              - "/file-engine/api/downloadFileStream"
            methods: ["GET"]
            exprs:
              - subject:
                  scope: Query
                  name: "filename"
                op: RegexMatch
                value: "^(_CISCO_CC\\.svg|_CX_VOICE\\.svg|_EMAIL\\.svg|_FACEBOOK\\.svg|_GENERIC\\.svg|_INSTAGRAM\\.svg|_LINKEDIN\\.svg|_SMS\\.svg|_TELEGRAM\\.svg|_TWITTER\\.svg|_VIBER\\.svg|_VOICEh\\.svg|_VOICE\\.svg|_WEB_RTC\\.svg|_WEB\\.svg|_WHATSAPP\\.svg|_YOUTUBE\\.svg)$"
            backendServicePort: 8080
            plugins:
              enableAuth: false
              enableRewrite: true
              rewriteStripPrefix: false
              rewriteRegexUriFrom: "^/file-engine/(api/downloadFileStream.*)$"
              rewriteRegexUriTo: "/$1"
              enableCors: true
              corsAllowOrigins: "*"
              corsAllowMethods: "GET, OPTIONS"
              corsAllowCredentials: true
              customPlugins:
                - name: response-rewrite
                  enable: true
                  config:
                    headers:
                      set:
                        X-XSS-Protection: "1; mode=block"        
          
    Add following customPlugin in file-engine under main route --> plugins:  
              customPlugins:      
                 - name: client-control
                   enable: true
                   config:
                     max_body_size: 6291456 # 5MB in bytes
                 - name: response-rewrite
                   enable: true
                   config:
                     headers:
                       set:
                         X-XSS-Protection: "1; mode=block"
                 # Note: proxy-body-size needs APISIX global config or maybe a specific plugin if available                                            
    Update following extraEnvVars under file-engine, add '/' at the start of the value 
          - name: CERTIFICATE
            value: /https/localhost.cert
          - name: CERTIFICATE_AUTHORITY
            value: /https/file-engine.ca-bundle
          - name: PRIVATEKEY
            value: /https/localhost.key
    
    Change the following "main" path in unified admin under apisixRoutes
    
            paths: ["/unified-admin","/unified-admin/*"]
    
    Add the following volume and volume mounts under file-engine
       extraVolumes:
          - name: ef-file-engine-https-certs-vol
            secret:
                secretName: ef-file-engine-https-certs-secret
       extraVolumeMounts:
          - name: ef-file-engine-https-certs-vol
            mountPath: /https        
    
    unified-admin Tag: 4.9.3
    web-channel-manager Tag: 4.9.3
    agent-manager Tag: 4.9.3
    customer-widget Tag: 4.9.3
    routing-engine Tag: 4.9.3
    conversation manager Tag: 4.9.3
    conversation monitor Tag: 4.9.3
    cim customer Tag:4.9.3
    file engine Tag: 4.9.3
    team-announcement Tag: 4.9.3
    Business-Calendar Tag: 4.9.3
    
    Apply the static-tls for file-engine
    kubectl apply -f pre-deployment/static-tls/ef-file-engine-https-certs.yaml
    
    helm upgrade --install --namespace expertflow --create-namespace   ef-cx  --debug --values helm-values/ef-cx-custom-values.yaml expertflow/cx --version 4.9.3
  11. Update the Campaigns helm chart

    CODE
    #Update Campaigns helm chart
    Edit/update the values file helm-values/cx-campaigns-custom-values.yaml with
    
    campaigns-backend Tag: /build 4.9.3_b-CIM-29663-cdfb02689e3703cb92add40e954aca725bfca0b7
    campaign-studio Tag: /build 4.9.3_b-CIM-29663-34bf793c0ea60353c865d329edfd0be5e32f5d4d
    
    helm upgrade --install --namespace expertflow   --set global.efCxReleaseName="ef-cx"  cx-campaigns --debug --values helm-values/cx-campaigns-custom-values.yaml expertflow/campaigns --version 4.9.3
  12. Update the Surveys helm chart

    CODE
    #Update Agent Desk helm chart
    Edit/update the values file helm-values/cx-surveys-custom-values.yaml with
    
    survey-backend Tag : /build  4.9.3 (4.9.3_b-CIM-29671-04_06_2025-14_42_31)
    survey-nodes Tag : /build  4.9.3 ( 4.9.3_b-CIM-29671)
    
    helm upgrade --install --namespace expertflow  --set global.efCxReleaseName="ef-cx"  cx-surveys  --debug --values helm-values/cx-surveys-custom-values.yaml expertflow/surveys --version 4.9.3
  13. Update the Eleveo helm chart

    CODE
    helm upgrade --install --namespace expertflow  --set global.efCxReleaseName="ef-cx"  cx-eleveo --debug --values helm-values/ef-cx-eleveo-custom-values.yaml  expertflow/eleveo --version 4.9.3
  14. Configuration Guides

    1. If you want to customise the file upload size (5 MB by default), use the following guide

    2. If you want to customise the IP-Rate Limiting(10 by default), use the following guide

    3. RSA Two Factor Authentication

      1. To enable Two-Factor authentication- RSA configuration guide

      2. User guide

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.