# Static Resources

* [Loading Grey Matter Control From Static Resources](#loading-gm-control-from-static-resources)
  * [Static File](#static-file)
    * [Configuration](#configuration)
    * [API](#api)
    * [Cluster Templates](#cluster-templates)
  * [Local Clusters](#local-clusters)
    * [Examples](#examples)

## Static File

Grey Matter Control has the ability to read in raw Envoy clusters and listeners from a static file on startup. This is different from file discovery, which continually reads and writes to the file dynamically during runtime. Static configs can be combined with discovery (see `--xds.static-resources.conflict-behavior`), but are themselves read only, and read in once at configuration time.

### Configuration

Static file configs are read in from the following configuration values:

| **Command Line Flag**                      | Environment Variable                                | Meaning                                                | Values                                                                                                                                                       |
| ------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--xds.static-resources.filename`          | `GM_CONTROL_XDS_STATIC_RESOURCES_FILENAME`          | The path of the filename to read in as a static config | `/path/to/file.type`                                                                                                                                         |
| `--xds.static-resources.format`            | `GM_CONTROL_XDS_STATIC_RESOURCES_FORMAT`            | Type of file                                           | `json` or `yaml` (default)                                                                                                                                   |
| `--xds.static-resources.conflict-behavior` | `GM_CONTROL_XDS_STATIC_RESOURCES_CONFLICT_BEHAVIOR` | How to handle conflicts with cluster discovery         | `overwrite` (static config overwrites all other configuration on startup) or `merge` (use static configuration when a config collision is detected, default) |

### API

The static resource configuration has the following API:

| **Name**          | Type                                                                                                                                                             | Meaning                                   |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| `clusters`        | Array of [envoy cluster](https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/cluster/v3/cluster.proto)                                                    | list of upstream clusters.                |
| `clusterTemplate` | [envoy cluster](https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/endpoint/v3/endpoint.proto#envoy-v3-api-msg-config-endpoint-v3-clusterloadassignment) |                                           |
| `listeners`       | Array of [envoy listener](https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/listener/v3/listener.proto)                                                 | list of listeners to apply to proxies.    |
| `loadAssignments` | Array of [envoy load assignment](https://godoc.org/github.com/cilium/proxy/go/envoy/api/v2#ClusterLoadAssignment)                                                | List of endpoints to match to a `cluster` |

### Cluster Templates

Instead of defining a large number of clusters statically, specifying a `clusterTemplate` attribute provides a base structure which is filled in by each cluster definition in `clusters`.

### Example

```javascript
{
  "cluster_template": {
    "type": "EDS",
    "edsClusterConfig": {
      "edsConfig": {
        "apiConfigSource": {
          "apiType": "gRPC",
          "clusterNames": [
            "xds_cluster"
          ],
          "refreshDelay": "120.000s"
        }
      }
    },
    "connectTimeout": "230.000s",
    "lbPolicy": "RING_HASH"
  },
  "clusters": [
    ...
  ]
}
```

## Local Clusters

Grey Matter Control provides a quick and easy utility to specify [envoy clusters](https://www.envoyproxy.io/docs/envoy/v1.15.0/api-v3/config/cluster/v3/cluster.proto) and [load assignments](https://godoc.org/github.com/cilium/proxy/go/envoy/api/v2#ClusterLoadAssignment) for hosts running on the same host as control (i.e. running on localhost). It This can be useful for testing locally when running everything in a development environment on the same machine. This should not be used for a production environment.

### Example

To enable loading of local clusters, set the environment variable `GM_CONTROL_LOCAL_CLUSTERS` to a comma delimited string of `cluster_name:port`. Here is an example:

```bash
GM_CONTROL_LOCAL_CLUSTERS=gm-proxy:8080
```

This will create a pre-canned config for the `gm-proxy` cluster and import it into gm-control with the host `127.0.0.1:8080`. The whole cluster config is listed below:

```javascript
{
  "clusters": [
    {
      "name": "gm-proxy",
      "type": "EDS",
      "edsClusterConfig": {
        "edsConfig": {
          "apiConfigSource": {
            "apiType": "gRPC",
            "grpcServices": [
              {
                "envoyGrpc": {
                  "clusterName": "tbn-xds"
                }
              }
            ],
            "refreshDelay": "30s"
          }
        },
        "serviceName": "gm-proxy"
      },
      "connectTimeout": "10s",
      "lbPolicy": "LEAST_REQUEST",
      "lbSubsetConfig": {
        "fallbackPolicy": "ANY_ENDPOINT"
      }
    }
  ],
  "loadAssignments": [
    {
      "clusterName": "gm-proxy",
      "endpoints": [
        {
          "lbEndpoints": [
            {
              "endpoint": {
                "address": {
                  "socketAddress": {
                    "address": "127.0.0.1",
                    "portValue": 8080
                  }
                }
              },
              "healthStatus": "HEALTHY"
            }
          ]
        }
      ]
    }
  ]
}
```
