# Workloads

RCTL can be used to manage the end-to-end lifecycle of a workload from an external CI system such as Jenkins etc. The table below describes the workload operations that can be automated using RCTL.

| Resource | Create | Get | Update | Delete | Publish | Unpublish |
| --- | --- | --- | --- | --- | --- | --- |
| Workload | YES | YES | YES | YES | YES | YES |

It is strongly recommended that customers version control their workload definition files in their Git repositories.

## Create and apply Workload

Create a new workload using a definition file as the input. The workload definition is a YAML file that captures all the necessary details required for the Controller to manage the lifecycle of the workload.

- When uploading an artifact file, the file path should be relative to the config YAML file (applicable for all types)
- With the `apply` command, `--v3` is not required. The API version is included in the YAML file. The `apply` command creates and publishes the workload

```bash
./rctl apply -f config.yaml
```

### Helm Chart Workloads

For Helm3 type workloads, the controller acts as the Helm client.

When using `apply` to create a workload, the workload is published to the cluster if the `placement` selector is configured (see example below). The workload is added to the GitOps Workload tab in the Console.

An illustrative example for a Helm3 type workload definition is shown below

```yaml
apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: helm3-chart-upload-multi-v2
  project: prod-test
  annotations:
    "apps.k8smgmt.io/workload-description": "A workload to yet test deploy busybox replica."
    "demo.dev/created-by": "demo-annotation"
spec:
  artifact:
    artifact:
      chartPath:
        name: file://artifacts/helm3-chart-upload-multi-v2/nginx-8.2.0-rafay.tgz
      valuesPaths:
      - name: file://artifacts/helm3-chart-upload-multi-v2/nginx-values-1-with-rauto-automation-ecr-registry.yaml
      - name: file://artifacts/helm3-chart-upload-multi-v2/nginx-values-2-with-rauto-automation-ecr-registry.yaml
      - name: file://artifacts/helm3-chart-upload-multi-v2/nginx-values-3-with-rauto-automation-ecr-registry.yaml
    options:
      maxHistory: 10
      timeout: 5m0s
    type: Helm
  namespace: demo-ns
  placement:
    selector: rafay.dev/clusterName in (prod-test-mks-1,prod-test-eks-1)
  version: helm3-chart-upload-multi-v2-v3
```

#### Helm Workloads from different Repos

Below is an example config file to create a workload with Helm Chart and values from different repositories

```yaml
apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: workload-v3-different-repo
  project: test
spec:
  artifact:
    artifact:
      chartPath:
        name: nginx-9.5.8.tgz
      repository: repo-test
      revision: main
      valuesRef:
        repository: repo-test2
        revision: main
        valuesPaths:
        - name: values.yaml
    options:
      maxHistory: 10
      timeout: 5m0s
    type: Helm
  drift:
    enabled: false
  namespace: demo-ns
  placement:
    selector: rafay.dev/clusterName=demo-stage-eks-10
  version: workload-helmingit-v2
```

### K8s Yaml Workloads

An illustrative example of a Kubernetes YAML workload with the path name as the artifact is shown below.

```yaml
apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: nativeyamlupload-v2
  project: prod-test
spec:
  artifact:
    artifact:
      paths:
      - name: file://artifacts/nativeyamlupload-v2/nativeyamlupload-v2.yaml
    options: {}
    type: Yaml
  namespace: demo-ns
  placement:
    selector: rafay.dev/clusterName in (prod-test-mks-1,prod-test-eks-1)
  version: nativeyamlupload-v2-v1
```

Example of artifact path when the workload and artifact files are in the same directory:

```yaml
spec:
  artifact:
    artifact:
      paths:
      - name: file://demo.yaml
    options: {}
    type: Yaml
```

Example of artifact path when the workload and artifact files are in the different directory:

```yaml
spec:
  artifact:
    artifact:
      paths:
      - name: file://./directory/demo.yaml
    options: {}
    type: Yaml
```

An illustrative example of a K8s YAML workload with encoded data as an artifact is shown below.

```yaml
apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: nativeyamlupload-v2
  project: prod-test
spec:
  artifact:
    type: Yaml
    artifact:
      paths:
        - data: YXBpVmVyc2lvbjogYXBwcy92MQpraW5kOiBEZXBsb3ltZW50Cm1ldGFkYXRhOgogIG5hbWU6IG5naW54LWRlcGxveW1lbnQKICBsYWJlbHM6CiAgICBhcHA6IG5naW54CnNwZWM6CiAgcmVwbGljYXM6IDEgICMgTnVtYmVyIG9mIGRlc2lyZWQgcG9kcwogIHNlbGVjdG9yOgogICAgbWF0Y2hMYWJlbHM6CiAgICAgIGFwcDogbmdpbngKICB0ZW1wbGF0ZToKICAgIG1ldGFkYXRhOgogICAgICBsYWJlbHM6CiAgICAgICAgYXBwOiBuZ2lueAogICAgc3BlYzoKICAgICAgY29udGFpbmVyczoKICAgICAgLSBuYW1lOiBuZ2lueAogICAgICAgIGltYWdlOiBuZ2lueDpsYXRlc3QgICMgTkdJTlggaW1hZ2UgZnJvbSBEb2NrZXIgSHViCiAgICAgICAgcG9ydHM6CiAgICAgICAgLSBjb250YWluZXJQb3J0OiA4MCAgIyBQb3J0IG9uIHdoaWNoIE5HSU5YIGxpc3RlbnMK
  drift:
    action: Deny
    enabled: true
  namespace: demo-ns
  placement:
    selector: rafay.dev/clusterName in (prod-test-mks-1,prod-test-eks-1)
  version: yamlupload-v2-v1
```

Below is an example specification for the `K8s YAML type` with the `Pull files from URL` artifact sync option:

```yaml
apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: demo-workload
  project: defaultproject
spec:
  version: v2
  artifact:
    artifact:
      url: ["https://raw.githubusercontent.com/user1/testnetworkpolicy/refs/heads/main/test/nginx-app.yaml"]
    type: Yaml
  drift:
    enabled: false
  namespace: sample-ns
  placement:
    labels:
    - key: rafay.dev/clusterName
      value: demo-label
```

On successful creation, workload is published.

## List Workloads

Use the below command to retrieve all the workloads

```bash
./rctl get workload --v3
```

Use the below RCTL command to retrieve/list all workloads in the specified Project.

```bash
./rctl get workload --project qa --v3
```

The command will return all the workloads with metadata similar to that in the Web Console.

- Name
- Namespace
- Type
- State
- ID

## Unpublish Workload

Use RCTL to unpublish a workload.

The following command unpublishes **V1 and V2 workloads**:

```bash
./rctl unpublish workload <workload name>
```

To unpublish a **V3 workload**, include the `--v3` flag:

```bash
./rctl unpublish workload <workload name> --v3
```

## Delete Workload

Use RCTL to delete a workload identified by name. Note that a delete operation will unpublish the workload first.

```bash
./rctl delete workload <workload name> --v3
```

## Status

Use this command to check status of a workload. The status of a workload can be checked on all deployed clusters with a single command.

```bash
./rctl status workload <workload name>
```

If the workload has not yet been published, it will return a "Status = Not Ready". If the publish is in progress, it will return a "Status = Pending". Once publish is successful, it will return a "Status = Ready". Status is presented by cluster for all configured clusters. The workload states transition as follows "Not Ready -> Pending -> Ready".

```bash
./rctl status workload apache --project qa
```

## Update Workload Config

Use this when you need to update the "Workload Definition" for an existing workload. For example, you may want to add a new cluster location where the workload needs to be deployed.

```bash
./rctl update workload <path-to-workload-definition-json-file> [flags] --v3
```

## Templating

Users can also create multiple workloads with a set of defined configurations. The template file contains a list of objects that helps to create multiple workload(s) from a single template.

Below is an example of a workload config template

```yaml
# Generated: {{now.UTC.Format "2006-01-02T15:04:05UTC"}}
#      With: {{command_line}}
{{ $envName := environment "PWD" | basename}}
{{ $glbCtx := . }}{{ range $i, $project := .ProjectNames }}
apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: node
  project: {{$envName}}-{{$project}}
spec:
  artifact:
    artifact:
      catalog: default-bitnami
      chartName: node
      chartVersion: {{$glbCtx.NodeChartVersion}}
    options:
      maxHistory: 10
      timeout: 5m0s
    type: Helm
  drift:
    enabled: false
  namespace: ns-frontend
  placement:
    labels:{{$c := $glbCtx}}{{range $l, $cluster := $glbCtx.ClusterNames}}
      - key: rafay.dev/clusterName
        value: {{$envName}}-{{$project}}-{{ $cluster }}{{end}}

---

apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: phpbb
  project: {{$envName}}-{{$project}}
spec:
  artifact:
    artifact:
      catalog: default-bitnami
      chartName: phpbb
      chartVersion: {{$glbCtx.PHPbbChartVersion}}
    options:
      maxHistory: 10
      timeout: 5m0s
    type: Helm
  drift:
    enabled: false
  namespace: ns-backend
  placement:
    labels:{{$c := $glbCtx}}{{range $l, $cluster := $glbCtx.ClusterNames}}
      - key: rafay.dev/clusterName
        value: {{$envName}}-{{$project}}-{{ $cluster }}{{end}}

---

apiVersion: apps.k8smgmt.io/v3
kind: Workload
metadata:
  name: mysql
  project: {{$envName}}-{{$project}}
spec:
  artifact:
    artifact:
      catalog: default-bitnami
      chartName: mysql
      chartVersion: {{$glbCtx.MySqlChartVersion}}
    options:
      maxHistory: 10
      timeout: 5m0s
    type: Helm
  drift:
    enabled: false
  namespace: ns-database
  placement:
    labels:{{$c := $glbCtx}}{{range $l, $cluster := $glbCtx.ClusterNames}}
      - key: rafay.dev/clusterName
        value: {{$envName}}-{{$project}}-{{ $cluster }}{{end}}

---
{{end}}
```

This template allows users to create one or more workloads with the required configuration defined in the template file.
