Skip to main content
Skip table of contents

Helm Charts for Expertflow CX Solution - Developer Edition

Instructions for Developers

Component Chart 

A general Chart  has a hierarchy like below

chart-name/
├── charts
├── Chart.yaml
├── templates
│   ├── configmap.yaml
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   └── service.yaml
└── values.yaml


Chart.yaml contains metadata about the chart, like its version, appVersion and related information. Whenever there is a change in the application , the appVersion is incremented using semantic versioning. The chart version is incremented when there is a change in the chart. In simpler words a single appVersion can be maintained across different chart version and vice a versa 

templates directory contains actual deployment contents for the component, with every single file being evaluated by a certain variable or function in the values file ( details given below )

values.yaml file for component is main file where end-user is allowed to change/update their required parameters and based on those evaluations are made when generating templates.

Meta Chart ( ef-cx )

For Expertflow Solution, a meta Chart is created which on its own doesn't do any thing except it 

  • Create a generic FQDN variable which will be used across all the sub-charts 
  • defines a global registry variable to provide offline deployments
  • creates commonEFConnection configmap which is populated in component charts where needed.
  • creates Image Pull Secret for the images to be pulled from a certain registry
  • creates SSL certificate as secrete required for all ingress routes.
  • declares sub-charts.

details are given below for actions performed by the meta-chart.( values.yaml ).

Generally, below given parameters are evaluated when the Chart is deployed.

{{ .Release.Name }} is replaced with the release name of the helm install command

{{ .Release.Namespace }} refers to the current namespace where the solution is to be deployed.

{{ .Values.global.ingressRouter }} will be replaced with the corresponding value from the values.yaml file.

common as sub-chart

A special library chart is included in the charts directory named as "common". This chart includes many commonly required functions which may help perform complex evaluations using simpler function calls. One of the function that is more commonly used in all charts ( both meta and sub-charts ) is the "common.tplvalues.render", which can help placing a function call in values.yaml file and then evaluate it. Note: This functionality is normally not possible without using rendering function.

demo as sub-chart

This chart is provided as a template chart to evaluate and perform testing for any one with requirements not enabled in any of the existing charts. You can place your test files in demo/templates folder and run evaluations using this chart.

Meta Chart Detailed

In addition to sub-chart details, below given are the details for this meta chart. Any key:value pair present in this file supersedes the values file in sub-chart's values file.

ItemDetailsdefault

global.ingressRouter

This parameter defines the FQDN used across the Expertflow Solution and is evaluated as a standard FQDN expression i-e can be a FQDN or, subdomain only."ef.com"

global.registry

this parameter gives the end user ability to customize the deployment in an air-gapped environment.

Changing its values will evaluate all images below this variable and must be changed in "imageCredentials.registry "

"gitimages.expertflow.com"

imageCredentials.registry

provides the registry URL"gitimages.expertflow.com"

imageCredentials.username

username to use"efcx"

imageCredentials.password

Password for the user"RecRpsuH34yqp56YRFUb"

imageCredentials.email

an email address for the user "devops@expertflow.com"

ssl.enabled

 when enabled to true, a self-Signed-Certificate  ( includes .Values.global.ingressRouter, 127.0.0.1 and ef.expertflow  as default Domain Names )

ssl.generateTLS

If False use the external/customer's SSL Cert/Key pair (mentioned below for defaultKey and defaultCert)

ssl.defaultSANList

Additional Domains to be included in the list of SANS ef.expertflow

ssl.defaultIPList

Additional IP address list for inclusion127.0.0.1

ssl.defaultKey

custom SSL KeyKey should be Base64 encoded

ssl.defaultCert 

custom SSL Cert Cert should be Base64 encoded


SubChart Declaration

MetaChart includes declaration of sub-charts in below given format. 

Subchart ItemDetailsDefault
subchart.installEnable or Disable this chart TRUE/FALSEtrue
subchart.replicaCount

Replica Count for this sub-Chart's pods

1
subchart.image.repositorystorage path on the registryper component
subchart.image.tagtag to be used for this chartper component
subchart.includeCommonEfConnectionsWhether CommonEFConnection CM be added to this component. TRUE/FALSEtrue
Note:

Image Pull Secret is created at runtime based on these variables, a valid dockerconfig in JSON format is created at runtime and added to the kubernetes engine as secret with the name of expertflow-gitlab-creds 

CommonEfConnections ConfigMap

this configmap is now part of the global values.yaml file under commonEfConnections  array and any addition/removal should be done in the values.yaml file only. It is created unconditionally ( no true/false switch is available ) and is available to the specified sub-charts

sub-charts

All sub-charts are named after the component name  for which it is developed and its values are evaluated from its values.yaml file 

list of sub-chart values evaluated and used during installation

itemdetailsdefault 
replicaCountgives the total number of replicas for this deployment1
image.repository:repository to fetch the image fromper component
image.pullPolicywhen to pull the image 'Always', 'Never','IfNotPresent''IfNotPresent'
image.tagimage tag 
imagePullSecrets:image pull secrets

expertflow-gitlab-creds. generated automatically during helm install

nameOverrideString to partially override common.names.fullname (DO NOT USE)""
fullnameOverrideString to fully override common.names.fullname(DO NOT USE)""
environment.enabledwhether this component has its own env from a config-maptrue
includeCommonEfConnectionswhether to load the commonEFConnection configmap into this component's envfalse
envOverrideInclude component level environement variables. Evaluated as Array

'[]'

includeCommonEfConnectionscontainerPortwhether to load the commonEFConnection configmap into this component's envPort this component exposesfalse""     [ 0-9 ]+



containerPortNameName of the Port ""     [ a-z0-9 ] + must be 15 characters long
restartPolicywhether to restart the container process if it diesAlways
extraContainerPorts

List of extra ports to be added to the deployment for this component.Also add this port to the service

{}
sidecarsAny sidecar container for this component. Evaluated as YAML template{}
initContainersAny initContainer for this component. Evaluated as YAML template{}
serviceAccountWhether to add a service account for this component. false
podAnnotationsAnnotation to be added to the pod. YAML template{}
podSecurityContextSecurityContext for this Pod{}
securityContextSecutiryContext to the Pod {}
service.enabledWhether to enable the service for this component.true
service.typeType of the serviceClusterIP
service.portPort of the service exposed
service.targetPortthe destination port in the deployment/pods""
service.nameName of the service to be exposed ( not used , use template )'{{ .Release.Name }}-{{ .Release.Chart }}-svc
service.extraPortswhether to expose any additional ports on this service. Evaluated as list

'[]'

ingress.enabledwhether to expose this component via ingresstrue
ingress.classNameingress class to be used for this ingress""
ingress.annotations:ingress related annotation which are required for the ingress to work properly""
ingress.paths:list of paths this ingress will be exposing to the ingress controller""
ingress.tlsdefaults  to true for the https/SSL based ingresstrue
customLivenessProbelivenessProbe for this component. Evaluated as Yaml

'{}'

customReadinessProbereadinessProbe for this component. Evaluated as Yaml'{}'
customStartupProbestartupProbe for this component. Evaluated as Yaml'{}'
resourcesresource allocation and limits for this component{}
autoscaling.enabledWhether to enable autoscaling for this componenetfalse
autoscaling.minReplicasminimum number of replicas to maintain1
autoscaling.maxReplicas: 100maximum number of replicas to scale upto100
autoscaling.targetCPUUtilizationPercentage: 80At what percentage of CPU utilization do the autoscaling80
autoscaling.targetMemoryUtilizationPercentage: 80At what percentage of RAM utilization do the autoscaling80
nodeSelectorNode selector '{}'
tolerationPod Tolerations'[]'
affinityPod Affinity'{}'

Attention:

Most of the configurable parameters are already adjusted in both component and global values files. However, for some components like Conversation Controller and other components which require adjustable configuration at runtime, configmaps are generates at the time of deployment of the helm chart. These must be compiled with proper indentation at required place in values.yaml file.

Creating a new sub-chart

Creating a new chart is simple. helm provides an option to create a new template chart which you can use to adjust according to the requirement

CODE
helm create <chart-name>

this will create a chart with the entered chart-name with all the required templates in templates directory.  Once created, please edit the chart and make necessary changes.

Duplicate the chart to minimize the effort.

For easily creating a chart adhering to Expertflow requirements, you can also copy an existing chart's values.yaml and templates folder within newly created chart and adjust it values. Below are the steps for such an exercise.

CODE
helm create new-connector

# Enter the newly created chart directory

cd new-connector

yes| cp ../connect360/values.yaml .
yes| cp ../connect360/templates/{deployment.yaml,service.yaml,configmap.yaml,ingress.yaml} templates/


NOTE: for MAC based systems please install the gnu sed using
# brew install gnu-sed

and use the `gsed` instead of the sed command.


# Change all the occurences of the source chart connect360 to new-connector

sed -i -e 's/connect360/<NEW-CONNECTOR>/g' values.yaml templates/*.yaml  ( for Linux users ) 

gsed -i -e 's/connect360/<NEW-CONNECTOR>/g' values.yaml templates/*.yaml ( for macOS users ) 


#however, some files need manual changes like port-name, service.port and other parameters 
* values.yaml
* Chart.yaml


Update  ConfigMaps

ConfigMaps for Environment Variables 

 For normal environment variables' substitution , please modify the templates/configmap.yaml   and add/update the environment variables.

Only add variables in <component-name>/templates/configmap.yaml file which are static across the deployment like reference to other services etc. For configurational parameters, add them to the global values file under the envOverride  section. otherwise a complete rebuild of the chart will be required.


ConfigMaps for Mount Points


If the component requires files to be mounted inside the pod, please follow these steps.

  • create  the folder containing files under <new-connector>/<new-folder> ( e.g <new-connector>/cache-builder )
  • under new-folder copy all files required for configmaps.  
  • create a new template under new-connector/templates/ with the relevant purposeful name ending with yaml  ( e.g new-connector/templates/cache-builder.yaml)
  • follow these guide lines
  • CODE
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: {{ include "<NEW-CONNECTOR>.fullname" . }}-actions-cm
      namespace: {{ .Release.Namespace }}
      labels:
        {{- include "<NEW-CONNECTOR>.labels" . | nindent 4 }}
    data:
    {{ (.Files.Glob "cache-builder/**").AsConfig | indent 2 }}
    
    

    The above given template will generate config-map containing all the files under cache-builder with file-name as the keyname

  • If the data files to be imported are binary , change the data:  tag to BinaryData  so that the kubernetes does not convert them to base64 encoded values.


once the newly created chart's values are adjusted, you will have rebuild the chart dependency by running

CODE
rm -f Chart.lock;
helm dependency update .
helm dependency build .


Update mechanism for a sub-chart

Developers are required to follow these guidelines when updating their respective subcharts.

  • All sub-charts a rendered using templates present in the templates folder. These templates are evaluated based on their decisions from the component's values.yaml 
  • All  config-maps, deployments, services are named after the chart name defined in the Chart.yaml file of each component.
  • All  config-maps must end with "-cm". added manually to the templated config-map name
  • All Service names must end with "-svc". added manually to the templated service name 
  • All Service name references in configmaps  must be  "{{ .Release.Name }}-{{ .Chart.Name }}-svc "  for example to reference agent-manager 's service endpoint, it should be referenced as "{{ .Release.Name }}-agent-manager-svc", where Release.Name is the deployment profile name of the whole CX solution.
  • All components must declare their exposed ports by name satisifying the port naming  convention. For example agent-manager port of 8080  serving on http protocol will be named as  http-ag-ma-8080. 
    • the portname must be 15 characters long otherwise Kubernetes engine will fail the deployment.
    • protocol must be at the start of the port name.
  • All Services must refer to the port of the container with the name of the port

Versioning of the Charts

All sub-charts must adhere to semvers conventions used and should be updated whenever there is a change in the chart's structure like env, cm, svc or deployment is changed.

  • Change the version of the chart to next available semver number 
  • update the sub-chart's version in meta-chart's Chart.yaml

Update dependencies 

CODE
rm -f Chart.lock; helm dependency build .


Package the existing sub-chart

CODE
helm package <component-dir-name>

Push the chart to the repo.

Login to the expertflow Charts repository . skip this step if already logged in.

CODE
helm registry login --username efcx --password Expertflow123$ charts.expertflow.com/library

push the chart to the EF repo using

CODE
helm push <component-name-version.tgz> oci://charts.expertflow.com/library

Update the ef-cx meta chart

Once new component is added, update the ef-cx/Charts.yaml file to represent the update information. This is a templated entry like below

CODE
  - name: new-connector
    condition: anew-connector.install
    version: "1.0.0"
    repository: oci://charts.expertflow.com


update the values.yaml file in ef-cx meta-chart. A sample entry will look like below:

CODE
###
new-connector:
  install: true
  replicaCount: 1
  envOverride:
     - name: variable
       value: value
  image:
    repository: cim/new-connector
    tag: "4.1-SR2"
  includeCommonEfConnections: true
###


Create the helm package archive ( new sub-chart ) 

for pushing to helm repo, create the package which we will push to repo in next step.

CODE
helm package <new-component-dir-name>

This command will create a file with the <component-name-version.tgz> format in current directory

Push the chart to the repo ( new sub-chart ) 

Login to the expertflow Charts repository . skip this step if already logged in.

CODE
helm registry login --username efcx --password Expertflow123$ charts.expertflow.com/library

push the chart to the EF repo using ( new sub-chart ) 

CODE
helm push <component-name-version.tgz> oci://charts.expertflow.com/library


Update the meta ef-cx chart 

Once all the sub-charts information is updated in both chart.yaml  and values.yaml  for ef-cx. 

Update the ef-cx meta chart version

Change the version of the meta ef-cx chart in its chart.yaml 

Update the ef-cx dependency 
CODE
helm dependency update ef-cx
 package the ef-cx chart
CODE
helm package ef-cx
push the ef-cx meta chart to repo
CODE
helm push <ef-cx-version.tgz> oci://charts.expertflow.com/library



Troubleshooting Steps.

Rendering Helm charts without installing them

As a developer of helm charts, You can also render the changes without installing the helm chart directly by

CODE
helm install --namespace expertflow  --set global.ingressRouter=devops218.ef.com  "ef-cx"  --dry-run --debug   .

Or Just to render the templates ( inside the chart directory )

CODE
helm template --debug  --values values.yaml .

 there are certain scenarios where the YAML is not rendered correctly ( due to incorrect spaces or tab characters )  You can disable the api-validation using ( inside the chart directory )

CODE
helm install --namespace <namespace>   <release-name>  --dry-run --disable-openapi-validation  --debug --values values.yaml .

this will show the incorrect YAML that needs proper indentation.


Dumping all the rendered manifests to a folder

You can also dump all the generated/rendered manifests into a folder for evaluation using

Check if the Go language is installed on your system

CODE
go version

if go lang is not installed, you can install the golang by following instruction on https://go.dev/doc/install

once golang is installed, run this command to fetch the required go module

CODE
go get -u github.com/databus23/schelm

export the required environment variables for golang

CODE
export GOPATH=$(go env GOPATH)

add the golang in your PATH 

CODE
export PATH=$PATH:$GOPATH/bin

export all the rendered charts into /root/rendered  folder

CODE
helm install --namespace <namespace>   <release-name>  --dry-run   --debug .|schelm /root/rendered
JavaScript errors detected

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

If this problem persists, please contact our support.