2019-11-18 09:00:37 +03:00
# github.com/jim-minter/rp
2019-10-16 06:29:17 +03:00
2019-11-18 09:00:37 +03:00
## Install
2019-10-16 06:29:17 +03:00
2019-11-18 09:00:37 +03:00
1. Install the following:
2019-10-16 06:29:17 +03:00
2019-11-18 09:00:37 +03:00
* go 1.12 or later
* az client
2019-10-16 06:29:17 +03:00
2019-11-18 09:05:38 +03:00
1. Log in to Azure:
2019-10-16 06:29:17 +03:00
2019-11-18 09:05:38 +03:00
```
az login
```
2019-10-28 23:56:18 +03:00
2019-11-18 09:00:37 +03:00
1. You will need a publicly resolvable DNS zone resource in Azure. For RH ARO
engineering, this is the `osadev.cloud` zone in the `dns` resource group.
2019-10-28 23:56:18 +03:00
2019-11-18 09:00:37 +03:00
1. You will need an AAD application with:
2019-10-28 23:56:18 +03:00
2019-11-18 09:00:37 +03:00
* client certificate and (for now) client secret authentication enabled
* (for now) User Access Administrator role granted on the subscription
* (for now) `Azure Active Directory Graph / Application.ReadWrite.OwnedBy`
privileges granted
2019-10-19 04:20:51 +03:00
2019-11-18 09:00:37 +03:00
For RH ARO engineering, this is the `aro-team-shared` AAD application. You
will need the client ID, client secret, and a key/certificate file
2019-11-18 09:05:38 +03:00
(`aro-team-shared.pem`) that can be loaded into your key vault. Ask if you
do not have these.
2019-10-28 23:56:18 +03:00
2019-11-18 09:00:37 +03:00
For non-RH ARO engineering, a suitable key/certificate file can be generated
using the following helper utility:
2019-10-28 23:56:18 +03:00
2019-11-18 09:05:38 +03:00
```
# Non-RH ARO engineering only
2019-11-18 09:55:32 +03:00
go run ./hack/genkey -extKeyUsage client "$AZURE_CLIENT_ID"
2019-11-18 09:05:38 +03:00
```
2019-10-28 23:56:18 +03:00
2019-11-18 09:00:37 +03:00
1. Copy env.example to env, edit the values and source the env file. This file
holds (only) the environment variables necessary for the RP to run.
* AZURE_TENANT_ID: Azure tenant UUID
* AZURE_SUBSCRIPTION_ID: Azure subscription UUID
* AZURE_CLIENT_ID: Azure AD application client UUID
* AZURE_CLIENT_SECRET: Azure AD application client secret
* LOCATION: Azure location where RP and cluster(s) will run (default: `eastus` )
* RESOURCEGROUP: Name of a new resource group which will contain the RP resources
2019-11-18 09:07:28 +03:00
* PULL_SECRET: A cluster pull secret retrieved from [Red Hat OpenShift Cluster Manager ](https://cloud.redhat.com/openshift/install/azure/installer-provisioned )
2019-10-19 04:20:51 +03:00
2019-11-19 03:51:39 +03:00
* RP_MODE: Set to `development` when not in production.
2019-11-18 09:05:38 +03:00
```
cp env.example env
vi env
. ./env
```
2019-10-28 23:56:18 +03:00
2019-11-18 09:05:38 +03:00
1. Choose the RP deployment parameters:
2019-10-28 23:56:18 +03:00
2019-11-18 09:00:37 +03:00
* COSMOSDB_ACCOUNT: Name of a new CosmosDB account
2019-11-18 09:06:22 +03:00
* DOMAIN: DNS subdomain shared by all clusters (RH: $something.osadev.cloud)
2019-11-18 09:00:37 +03:00
* KEYVAULT_NAME: Name of a new key vault
* ADMIN_OBJECT_ID: AAD object ID for key vault admin(s) (RH: `az ad group list --query "[?displayName=='Engineering'].objectId" -o tsv` )
* RP_OBJECT_ID: AAD object ID for AAD application (RH: `az ad app list --all --query "[?appId=='$AZURE_CLIENT_ID'].objectId" -o tsv` )
2019-10-19 04:20:51 +03:00
2019-11-18 09:05:38 +03:00
1. Create the resource group and deploy the RP resources:
2019-10-19 04:20:51 +03:00
2019-11-18 09:05:38 +03:00
```
COSMOSDB_ACCOUNT=mycosmosdb
DOMAIN=mydomain.osadev.cloud
KEYVAULT_NAME=mykeyvault
ADMIN_OBJECT_ID=$(az ad group list --query "[?displayName=='Engineering'].objectId" -o tsv)
2019-11-28 06:26:12 +03:00
RP_OBJECT_ID=$(az ad sp list --all --query "[?appId=='$AZURE_CLIENT_ID'].objectId" -o tsv)
2019-11-18 06:43:35 +03:00
2019-11-18 09:05:38 +03:00
az group create -g "$RESOURCEGROUP" -l "$LOCATION"
2019-10-19 04:20:51 +03:00
2019-11-18 09:05:38 +03:00
az group deployment create -g "$RESOURCEGROUP" --mode complete --template-file deploy/rp.json --parameters "location=$LOCATION" "databaseAccountName=$COSMOSDB_ACCOUNT" "domainName=$DOMAIN" "keyvaultName=$KEYVAULT_NAME" "adminObjectId=$ADMIN_OBJECT_ID" "rpObjectId=$RP_OBJECT_ID"
```
2019-11-18 06:32:53 +03:00
2019-11-18 09:05:38 +03:00
1. Load the application key/certificate into the key vault:
2019-11-18 06:32:53 +03:00
2019-11-18 09:05:38 +03:00
```
2019-11-18 09:55:32 +03:00
AZURE_KEY_FILE=aro-team-shared.pem
2019-11-18 09:00:37 +03:00
2019-11-18 09:55:32 +03:00
az keyvault certificate import --vault-name "$KEYVAULT_NAME" --name azure --file "$AZURE_KEY_FILE"
```
1. Generate a self-signed serving key/certificate and load it into the key vault:
```
TLS_KEY_FILE=localhost.pem
go run ./hack/genkey localhost
az keyvault certificate import --vault-name "$KEYVAULT_NAME" --name tls --file "$TLS_KEY_FILE"
2019-11-18 09:05:38 +03:00
```
2019-11-18 06:43:35 +03:00
2019-11-18 09:05:38 +03:00
1. Create a glue record in the parent DNS zone:
2019-11-18 06:32:53 +03:00
2019-11-18 09:05:38 +03:00
```
PARENT_DNS_RESOURCEGROUP=dns
2019-10-19 04:20:51 +03:00
2019-11-18 09:05:38 +03:00
az network dns record-set ns create --resource-group "$PARENT_DNS_RESOURCEGROUP" --zone "$(cut -d. -f2- < < < "$DOMAIN")" --name "$(cut -d. -f1 < < < "$DOMAIN")"
2019-10-16 06:29:17 +03:00
2019-11-18 09:05:38 +03:00
for ns in $(az network dns zone show --resource-group "$RESOURCEGROUP" --name "$DOMAIN" --query nameServers -o tsv); do az network dns record-set ns add-record --resource-group "$PARENT_DNS_RESOURCEGROUP" --zone "$(cut -d. -f2- < < < "$DOMAIN")" --record-set-name "$(cut -d. -f1 < < < "$DOMAIN")" --nsdname $ns; done
```
2019-11-18 09:00:37 +03:00
## Running the RP
2019-10-19 04:20:51 +03:00
```
go run ./cmd/rp
```
2019-10-16 06:29:17 +03:00
## Useful commands
2019-10-19 04:20:51 +03:00
```
2019-11-21 05:32:34 +03:00
export CLUSTER=cluster
2019-10-19 04:20:51 +03:00
```
2019-11-28 20:32:24 +03:00
* Register a subscription:
curl -k -X PUT "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID?api-version=2.0" -H 'Content-Type: application/json' -d '{"state": "Registered"}'
2019-11-18 09:05:38 +03:00
* Create a cluster:
2019-10-19 04:20:51 +03:00
```
2019-11-21 05:32:34 +03:00
az group create -g "$CLUSTER-vnet" -l "$LOCATION"
az network vnet create -g "$CLUSTER-vnet" -n "$CLUSTER-vnet" --address-prefixes 10.0.0.0/16
az network vnet subnet create -g "$CLUSTER-vnet" --vnet-name "$CLUSTER-vnet" -n master --address-prefixes 10.0.0.0/24
az network vnet subnet create -g "$CLUSTER-vnet" --vnet-name "$CLUSTER-vnet" -n worker --address-prefixes 10.0.1.0/24
2019-11-21 07:31:34 +03:00
envsubst < examples / cluster-v20191231 . json | curl -k -X PUT " https: / / localhost:8443 / subscriptions / $ AZURE_SUBSCRIPTION_ID / resourceGroups / $ CLUSTER / providers / Microsoft . RedHatOpenShift / openShiftClusters / $ CLUSTER ? api-version = 2019-12-31-preview" -H ' Content-Type: application / json ' -d @ -
2019-10-19 04:20:51 +03:00
```
2019-11-18 09:05:38 +03:00
* Get a cluster:
2019-10-19 04:20:51 +03:00
```
2019-11-21 07:31:34 +03:00
curl -k "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$CLUSTER/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER?api-version=2019-12-31-preview"
2019-10-19 04:20:51 +03:00
```
2019-11-18 09:05:38 +03:00
* Get a cluster's kubeadmin credentials:
2019-10-19 04:20:51 +03:00
```
2019-11-21 07:31:34 +03:00
curl -k -X POST "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$CLUSTER/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER/credentials?api-version=2019-12-31-preview" -H 'Content-Type: application/json' -d '{}'
2019-10-19 04:20:51 +03:00
```
2019-11-18 09:05:38 +03:00
* List clusters in resource group:
2019-10-19 04:20:51 +03:00
```
2019-11-21 07:31:34 +03:00
curl -k "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$CLUSTER/providers/Microsoft.RedHatOpenShift/openShiftClusters?api-version=2019-12-31-preview"
2019-10-19 04:20:51 +03:00
```
2019-10-16 06:29:17 +03:00
2019-11-18 09:05:38 +03:00
* List clusters in subscription:
2019-10-16 06:29:17 +03:00
2019-10-19 04:20:51 +03:00
```
2019-11-21 07:31:34 +03:00
curl -k "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID/providers/Microsoft.RedHatOpenShift/openShiftClusters?api-version=2019-12-31-preview"
2019-10-19 04:20:51 +03:00
```
2019-10-16 06:29:17 +03:00
2019-11-18 09:05:38 +03:00
* Scale a cluster:
2019-10-16 06:29:17 +03:00
2019-10-19 04:20:51 +03:00
```
COUNT=3
2019-10-19 01:39:32 +03:00
2019-11-21 07:31:34 +03:00
curl -k -X PATCH "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$CLUSTER/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER?api-version=2019-12-31-preview" -H 'Content-Type: application/json' -d '{"properties": {"workerProfiles": [{"name": "worker", "count": '"$COUNT"'}]}}'
2019-10-19 04:20:51 +03:00
```
2019-10-19 01:39:32 +03:00
2019-11-18 09:05:38 +03:00
* Delete a cluster:
2019-10-19 01:39:32 +03:00
2019-10-19 04:20:51 +03:00
```
2019-11-21 07:31:34 +03:00
curl -k -X DELETE "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$CLUSTER/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER?api-version=2019-12-31-preview"
2019-11-21 05:32:34 +03:00
az group delete -g "$CLUSTER-vnet"
2019-11-21 18:36:22 +03:00
```
* List operations:
2019-11-21 05:32:34 +03:00
2019-11-21 18:36:22 +03:00
```
curl -k "https://localhost:8443/providers/Microsoft.RedHatOpenShift/operations?api-version=2019-12-31-preview"
2019-10-19 04:20:51 +03:00
```
2019-10-16 06:29:17 +03:00
## Basic architecture
* pkg/frontend is intended to become a spec-compliant RP web server. It is
backed by CosmosDB. Incoming PUT/DELETE requests are written to the database
2019-10-19 04:20:51 +03:00
with an non-terminal (Updating/Deleting) provisioningState.
2019-10-16 06:29:17 +03:00
2019-10-18 21:46:27 +03:00
* pkg/backend reads documents with non-terminal provisioningStates,
asynchronously updates them and finally updates document with a terminal
provisioningState (Succeeded/Failed). The backend updates the document with a
heartbeat - if this fails, the document will be picked up by a different
worker.
2019-10-16 06:29:17 +03:00
* As CosmosDB does not support document patch, care is taken to correctly pass
through any fields in the internal model which the reader is unaware of (see
`github.com/ugorji/go/codec.MissingFielder` ). This is intended to help in
upgrade cases and (in the future) with multiple microservices reading from the
database in parallel.
* Care is taken to correctly use optimistic concurrency to avoid document
corruption through concurrent writes (see `RetryOnPreconditionFailed` ).
* The pkg/api architecture differs somewhat from
`github.com/openshift/openshift-azure` : the intention is to fix the broken
merge semantics and try pushing validation into the versioned APIs to improve
error reporting.
2019-10-19 04:20:51 +03:00
* Everything is intended to be crash/restart/upgrade-safe, horizontally
scaleable, upgradeable...
2019-11-14 04:08:34 +03:00
## Debugging
2019-11-18 09:05:38 +03:00
* Get an admin kubeconfig:
2019-11-14 04:08:34 +03:00
2019-11-18 09:05:38 +03:00
```
2019-11-21 07:31:34 +03:00
hack/get-admin-kubeconfig.sh /subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$CLUSTER/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER
2019-11-18 09:05:38 +03:00
export KUBECONFIG=admin.kubeconfig
oc version
```
2019-11-14 04:08:34 +03:00
2019-11-18 09:05:38 +03:00
* SSH to the bootstrap node:
2019-11-14 04:08:34 +03:00
2019-11-18 09:05:38 +03:00
```
2019-11-21 07:31:34 +03:00
hack/ssh-bootstrap.sh /subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$CLUSTER/providers/Microsoft.RedHatOpenShift/openShiftClusters/$CLUSTER
2019-11-18 09:05:38 +03:00
```
2019-11-18 09:00:37 +03:00
## Useful links
2019-11-18 09:05:38 +03:00
* https://github.com/Azure/azure-resource-manager-rpc
2019-11-18 09:00:37 +03:00
2019-11-18 09:05:38 +03:00
* https://github.com/microsoft/api-guidelines
2019-11-18 09:00:37 +03:00
2019-11-18 09:05:38 +03:00
* https://docs.microsoft.com/en-gb/rest/api/cosmos-db
2019-11-18 09:00:37 +03:00
2019-11-18 09:05:38 +03:00
* https://github.com/jim-minter/go-cosmosdb