<commit_before>#Online force-sleep controller

Controller for monitoring and restricting resource usage of free tier accounts. Listens to pod and replication controller events in a cluster and caches data on these resources by namespace (project).

The `PERIOD` is a rolling timeframe during which pod, replication controller, and deployment config resource usage is considered.

`QUOTA_HOURS` refers to the maximum number of quota-hours usable within the `PERIOD` before the resource (or project) is put into force-sleep mode. A quota-hour is defined for pods as a pod using its full memory quota for one hour. For replication controllers, it is defined as simply having one or more active replicas for one hour. For deployment configs, it is having one or more active deployments for one hour.

Once a replication controller has exceeded the `QUOTA_HOURS` limit, that RC is scaled to 0 replicas. Any RCs active for a deployment config contribute cumulatively toward that DC's quota-hour usage, and once it is exceeded all RCs connected to that DC will be scaled to 0 replicas. As a catch-all to deter users from skirting these rules, pods' quota-hour usage within a project accumulate during the rolling `PERIOD` until `QUOTA_HOURS` is met. In that case, a `force-sleep` quota is placed on the project with a hard limit on `pods=0`. This quota persists for `PROJECT_SLEEP_LENGTH`. 

Every `SLEEP_SYNC_PERIOD`, the cached data on each project will be queried and the projects' quota-hour usage will be calculated and, if necessary, force-sleep will be added to (or removed from) the project.

Every `IDLE_SYNC_PERIOD`, the cached data on each project will be queried and the projects' network traffic received will be calculated and, if network traffic recieved is below a configured threshold, services in the project will be idled.

usage:
```
oc new-app -n openshift-infra \
   -f template.yaml \
   -p QUOTA_HOURS=16h \
   -p PERIOD=24h \
   -p SLEEP_SYNC_PERIOD=1h \
   -p PROJECT_SLEEP_LENGTH=8h \
   -p WORKERS=10 \
   -p EXCLUDE_NAMESPACES="openshift,openshift-infra,<etc...>" \
   -p TERMINATING_QUOTA=1Gi \
   -p NONTERMINATING_QUOTA=1Gi
   -p IDLE_SYNC_PERIOD=30m \
   -p HAWKULAR_URL="https://hawkular-metrics.openshift-infra.svc.cluster.local"
   -p HAWKULAR_INSECURE=true \
   -p IDLE_THRESHOLD=500 \
   -p IN_CLUSTER=true \
   -p IDLE_DRYRUN=true

```

Building locally:
`docker build -f Dockerfile.local -t openshift/force-sleep .`

`glog` levels generally follow this structure:
* 3: Resource/watch event level messages
* 2: Project/sleep/idle level messages
* 1: Sleeper/Idler/cluster level messages

(WIP) Ansible role contained in `../ansible/roles/force_sleep/tasks/main.yml`
<commit_msg>Fix markdown title<commit_after># Online force-sleep controller

Controller for monitoring and restricting resource usage of free tier accounts. Listens to pod and replication controller events in a cluster and caches data on these resources by namespace (project).

The `PERIOD` is a rolling timeframe during which pod, replication controller, and deployment config resource usage is considered.

`QUOTA_HOURS` refers to the maximum number of quota-hours usable within the `PERIOD` before the resource (or project) is put into force-sleep mode. A quota-hour is defined for pods as a pod using its full memory quota for one hour. For replication controllers, it is defined as simply having one or more active replicas for one hour. For deployment configs, it is having one or more active deployments for one hour.

Once a replication controller has exceeded the `QUOTA_HOURS` limit, that RC is scaled to 0 replicas. Any RCs active for a deployment config contribute cumulatively toward that DC's quota-hour usage, and once it is exceeded all RCs connected to that DC will be scaled to 0 replicas. As a catch-all to deter users from skirting these rules, pods' quota-hour usage within a project accumulate during the rolling `PERIOD` until `QUOTA_HOURS` is met. In that case, a `force-sleep` quota is placed on the project with a hard limit on `pods=0`. This quota persists for `PROJECT_SLEEP_LENGTH`.

Every `SLEEP_SYNC_PERIOD`, the cached data on each project will be queried and the projects' quota-hour usage will be calculated and, if necessary, force-sleep will be added to (or removed from) the project.

Every `IDLE_SYNC_PERIOD`, the cached data on each project will be queried and the projects' network traffic received will be calculated and, if network traffic recieved is below a configured threshold, services in the project will be idled.

usage:
```
oc new-app -n openshift-infra \
   -f template.yaml \
   -p QUOTA_HOURS=16h \
   -p PERIOD=24h \
   -p SLEEP_SYNC_PERIOD=1h \
   -p PROJECT_SLEEP_LENGTH=8h \
   -p WORKERS=10 \
   -p EXCLUDE_NAMESPACES="openshift,openshift-infra,<etc...>" \
   -p TERMINATING_QUOTA=1Gi \
   -p NONTERMINATING_QUOTA=1Gi
   -p IDLE_SYNC_PERIOD=30m \
   -p HAWKULAR_URL="https://hawkular-metrics.openshift-infra.svc.cluster.local"
   -p HAWKULAR_INSECURE=true \
   -p IDLE_THRESHOLD=500 \
   -p IN_CLUSTER=true \
   -p IDLE_DRYRUN=true

```

Building locally:
`docker build -f Dockerfile.local -t openshift/force-sleep .`

`glog` levels generally follow this structure:
* 3: Resource/watch event level messages
* 2: Project/sleep/idle level messages
* 1: Sleeper/Idler/cluster level messages

(WIP) Ansible role contained in `../ansible/roles/force_sleep/tasks/main.yml`

{'fraction_non_alphanumeric': 0.06783410138248848, 'fraction_numerical': 0.007741935483870968, 'mean_word_length': 4.252662149080349, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1478501', 'n_tokens_mistral': 1736, 'n_tokens_neox': 1591, 'n_words': 707}