-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3599 from wireapp/outlook-integration-helm-chart
Outlook integration helm chart
- Loading branch information
Showing
9 changed files
with
440 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
apiVersion: v1 | ||
name: outlook-addin | ||
version: 4.38.0 | ||
description: Helm chart for outlook addin for Wire |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
# How to install Outlook AddIn for Wire-Server | ||
|
||
WIP: Some of these configurations are subject to change down the line. This documentation will be updated accordingly as they happen. | ||
|
||
This document assumes you already have an instance of wire-server running. If you don't, follow this [documentation](https://github.com/wireapp/wire-server-deploy/blob/master/offline/docs.md) | ||
|
||
## Set up OAuth with wire-server | ||
|
||
To use OAuth, first you will need to enable it by editing `values/wire-server/values.yaml` as follows: | ||
|
||
``` | ||
brig: | ||
# ... | ||
config: | ||
# ... | ||
optSettings: | ||
# ... | ||
setOAuthEnabled: true | ||
``` | ||
|
||
Then you will need to generate a key using "OKP" (Octet Key Pair) and the "Ed25519" curve with OpenSSL that will be used as JWK (JSON Web Key) in the wire-server helm chart. This key will be used to sign and verify [OAuth](https://docs.wire.com/developer/reference/oauth.html#setting-up-public-and-private-keys) access tokens. | ||
|
||
``` | ||
openssl genpkey -algorithm Ed25519 -out private_key.pem | ||
``` | ||
|
||
You can find a `generate_jwk.py` in this chart which you can use to generate the JWK in JSON format that can be used in your wire-server helm chart. Use it in `brig` and `nginz` namespaces in `values/wire-server/secrets.yaml` like shown below. | ||
|
||
``` | ||
brig: | ||
secrets: | ||
oauthJwkKeyPair: | | ||
{ | ||
"kty": "OKP", | ||
"crv": "Ed25519", | ||
"x": "...", | ||
"d": "...", | ||
"kid": "..." | ||
} | ||
``` | ||
|
||
``` | ||
# values.yaml or secrets.yaml | ||
nginz: | ||
secrets: | ||
oAuth: | ||
publicKeys: | | ||
{ | ||
"kty": "OKP", | ||
"crv": "Ed25519", | ||
"x": "...", | ||
"kid": "..." | ||
} | ||
``` | ||
|
||
Now redeploy wire-server chart: | ||
|
||
``` | ||
d helm upgrade --install wire-server charts/wire-server --values values/wire-server/values.yaml --values/wire-server/secrets.yaml | ||
``` | ||
|
||
## Outlook integration feature flag | ||
|
||
By default, outlook addin as a feature is disabled for all teams. To change this make the following changes in your configuration in `galley` namespace: | ||
|
||
``` | ||
galley: | ||
config: | ||
# ... | ||
settings: | ||
# ... | ||
featureFlags: | ||
# ... | ||
outlookCalIntegration: | ||
defaults: | ||
status: enabled | ||
lockStatus: unlocked | ||
``` | ||
|
||
Redeploy wire-server for these changes to take effect. | ||
|
||
NOTE: As of the time of writing `outlookCalIntegration` is not a typo! (at least not in this documentation) | ||
|
||
If you have an existing team in your wire-server that did not have this feature flag enabled prior to this. You will need to enable that feature flag through [Backoffice API](https://github.com/wireapp/wire-server/tree/05778a2b14ac5aaffca937d6e2cdd9b7b5f3106d/charts/backoffice). | ||
|
||
NOTE: As of the time of writing Backoffice API endpoint for enabling this feature flag is not working as intended so please follow this manual on how to do it with curl on the machine wire-server is running on. | ||
|
||
### How to manually enable outlookCalIntegration feature flag for a team | ||
|
||
You will need your `teamId` (you can find it in TeamSettings under Customization tab). | ||
List all your pods in your Kubernetes cluster with: | ||
|
||
``` | ||
d kubectl get pods -owide | ||
``` | ||
|
||
Copy the name of one of your galley pods and run: | ||
|
||
``` | ||
d kubectl exec -it galley_pod_name /bin/bash | ||
``` | ||
|
||
In the new terminal type: | ||
|
||
``` | ||
curl -v -XPATCH 'http://localhost:8080/i/teams/your_teamID/features/outlookCalIntegration' -H 'content-type: application/json;charset=utf-8' -d '{"status": "enabled", "lockStatus": "unlocked"}' | ||
``` | ||
|
||
Do this for all the teams you want to enable the feature for. | ||
|
||
## Create new client service for OAuth in Brig | ||
|
||
List all your pods in your Kubernetes cluster with: | ||
|
||
``` | ||
d kubectl get pods -owide | ||
``` | ||
|
||
Copy the name of one of your brig pods and run: | ||
|
||
``` | ||
d kubectl exec -it brig_pod_name /bin/bash | ||
``` | ||
|
||
In the new terminal type: | ||
|
||
``` | ||
curl -s -X POST localhost:8080/i/oauth/clients \ | ||
-H "Content-Type: application/json" \ | ||
-d '{ | ||
"application_name":"Wire Microsoft Outlook Calendar Add-in", | ||
"redirect_url":"https://outlook.example.com/callback.html" | ||
}' | ||
``` | ||
|
||
You will get back a response in JSON format that should look like: | ||
|
||
``` | ||
{"client_id":"b2b3...","client_secret":"9ee60..."} | ||
``` | ||
|
||
Write down your client_id as it will be needed later. | ||
|
||
## Deploying Wire Outlook AddIn | ||
|
||
Create a new `values.yaml` file in `values/outlook-addin` directory (create the directory too if missing). | ||
Append the following configuration (change the example.com with your domain). | ||
|
||
``` | ||
host: "outlook.example.com" # this entry has to be without https://!!! | ||
wireApiBaseUrl: "https://nginz-https.example.com" | ||
wireAuthorizationEndpoint: "https://webapp.example.com/auth" | ||
clientId: "" | ||
``` | ||
|
||
As of the time of writing nginz used by wire-server is not set up to whitelist outlook subdomain for CORS requests. So please edit `charts/wire-server/charts/nginz/values.yaml` and find under `nginx_conf`: | ||
|
||
``` | ||
allowlisted_origins: | ||
- webapp | ||
- teams | ||
- account | ||
- outlook # add outlook entry so your addin doesnt get CORS blocked | ||
``` | ||
|
||
### Certificates | ||
|
||
If you are using cert-manager just make the following configuration in values.yaml: | ||
|
||
``` | ||
tls: | ||
issuerRef: | ||
name: letsencrypt-http01 # letsencrypt-http01 is a default config in wire-server, change if needed in your instance | ||
``` | ||
|
||
Now deploy outlook addin chart with: | ||
|
||
``` | ||
d helm upgrade --install outlook-addin charts/outlook-addin --values values/outlook-addin/values.yaml | ||
``` | ||
|
||
If you are using your own provided certificates, deploy the addin with this command: | ||
|
||
``` | ||
d helm upgrade --install outlook-addin charts/outlook-addin --values values/outlook-addin/values.yaml --set-file tls.crt=/path/to/tls.crt --set-file tls.key=/path/to/tls.key | ||
``` | ||
|
||
## Install Wire AddIn in Microsoft Outlook | ||
|
||
After deploying `outlook-addin` you will be able to find `manifest.xml` file on https://outlook.example.com/manifest.xml which you can use to install the addin in your outlook. You can find instructions and screenshots how to do it [here](https://github.com/tlebon/outlook-addin/blob/staging/README.md#how-to-install-the-add-in-in-ms-outlook). | ||
NOTE: Links in the outlined documents are hardcoded for a testing/prod environment, any reference to zinfra.io or wire.com in it should be treated as example.com. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import json | ||
from jwcrypto import jwk | ||
import base64 | ||
|
||
def pem_to_jwk(pem_key, is_private=True): | ||
key = jwk.JWK.from_pem(pem_key) | ||
if is_private: | ||
key_dict = key.export(as_dict=True, private_key=True) | ||
else: | ||
key_dict = key.export(as_dict=True, private_key=False) | ||
return key_dict | ||
|
||
def convert_to_pem(base64_key): | ||
pem_key = base64.b64decode(base64_key) | ||
return pem_key | ||
|
||
with open("private_key.pem", "rb") as f: | ||
private_key_pem = f.read() | ||
private_key_b64 = base64.b64encode(private_key_pem).decode('utf-8') | ||
private_jwk = pem_to_jwk(convert_to_pem(private_key_b64), is_private=True) | ||
|
||
print("Private JWK:") | ||
print(json.dumps(private_jwk, indent=2)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
{{/* | ||
Expand the name of the chart. | ||
*/}} | ||
{{- define "outlook.name" -}} | ||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} | ||
{{- end }} | ||
|
||
{{/* | ||
Create a default fully qualified app name. | ||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). | ||
If release name contains chart name it will be used as a full name. | ||
*/}} | ||
{{- define "outlook.fullname" -}} | ||
{{- if .Values.fullnameOverride }} | ||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} | ||
{{- else }} | ||
{{- $name := default .Chart.Name .Values.nameOverride }} | ||
{{- if contains $name .Release.Name }} | ||
{{- .Release.Name | trunc 63 | trimSuffix "-" }} | ||
{{- else }} | ||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} | ||
{{- end }} | ||
{{- end }} | ||
{{- end }} | ||
|
||
{{/* | ||
Create chart name and version as used by the chart label. | ||
*/}} | ||
{{- define "outlook.chart" -}} | ||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} | ||
{{- end }} | ||
|
||
{{/* | ||
Common labels | ||
*/}} | ||
{{- define "outlook.labels" -}} | ||
helm.sh/chart: {{ include "outlook.chart" . }} | ||
{{ include "outlook.selectorLabels" . }} | ||
{{- if .Chart.AppVersion }} | ||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} | ||
{{- end }} | ||
app.kubernetes.io/managed-by: {{ .Release.Service }} | ||
{{- end }} | ||
|
||
{{/* | ||
Selector labels | ||
*/}} | ||
{{- define "outlook.selectorLabels" -}} | ||
app.kubernetes.io/name: {{ include "outlook.name" . }} | ||
app.kubernetes.io/instance: {{ .Release.Name }} | ||
{{- end }} | ||
|
||
{{/* Allow KubeVersion to be overridden. */}} | ||
{{- define "kubeVersion" -}} | ||
{{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} | ||
{{- end -}} | ||
|
||
{{/* Get Ingress API Version */}} | ||
{{- define "ingress.apiVersion" -}} | ||
{{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" (include "kubeVersion" .)) -}} | ||
{{- print "networking.k8s.io/v1" -}} | ||
{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} | ||
{{- print "networking.k8s.io/v1beta1" -}} | ||
{{- else -}} | ||
{{- print "extensions/v1beta1" -}} | ||
{{- end -}} | ||
{{- end -}} | ||
|
||
{{/* Check Ingress stability */}} | ||
{{- define "ingress.isStable" -}} | ||
{{- eq (include "ingress.apiVersion" .) "networking.k8s.io/v1" -}} | ||
{{- end -}} | ||
|
||
{{/* Check Ingress supports pathType */}} | ||
{{/* pathType was added to networking.k8s.io/v1beta1 in Kubernetes 1.18 */}} | ||
{{- define "ingress.supportsPathType" -}} | ||
{{- or (eq (include "ingress.isStable" .) "true") (and (eq (include "ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" (include "kubeVersion" .))) -}} | ||
{{- end -}} | ||
|
||
{{- define "ingress.FieldNotAnnotation" -}} | ||
{{- (semverCompare ">= 1.27-0" (include "kubeVersion" .)) -}} | ||
{{- end -}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: {{ include "outlook.fullname" . }} | ||
labels: | ||
{{- include "outlook.labels" . | nindent 4 }} | ||
spec: | ||
replicas: 3 | ||
selector: | ||
matchLabels: | ||
app: {{ include "outlook.fullname" . }} | ||
template: | ||
metadata: | ||
labels: | ||
app: {{ include "outlook.fullname" . }} | ||
spec: | ||
containers: | ||
- name: {{ include "outlook.fullname" . }} | ||
image: {{ .Values.containerImage }} | ||
ports: | ||
- name: http | ||
containerPort: 80 | ||
env: | ||
- name: BASE_URL | ||
value: "https://{{ .Values.host }}" | ||
- name: CLIENT_ID | ||
value: "{{ .Values.clientId }}" | ||
- name: WIRE_API_BASE_URL | ||
value: "{{ .Values.wireApiBaseUrl }}" | ||
- name: WIRE_AUTHORIZATION_ENDPOINT | ||
value: "{{ .Values.wireAuthorizationEndpoint }}" | ||
- name: SUPPORT_URL | ||
value: "{{ .Values.supportUrl }}" | ||
livenessProbe: | ||
httpGet: | ||
path: / | ||
port: http | ||
readinessProbe: | ||
httpGet: | ||
path: / | ||
port: http |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{{- $apiIsStable := eq (include "ingress.isStable" .) "true" -}} | ||
{{- $ingressFieldNotAnnotation := eq (include "ingress.FieldNotAnnotation" .) "true" -}} | ||
{{- $ingressSupportsPathType := eq (include "ingress.supportsPathType" .) "true" -}} | ||
apiVersion: {{ include "ingress.apiVersion" . }} | ||
kind: Ingress | ||
metadata: | ||
name: "{{ include "outlook.fullname" . }}" | ||
labels: | ||
{{- include "outlook.labels" . | nindent 4 }} | ||
annotations: | ||
{{- if not $ingressFieldNotAnnotation }} | ||
kubernetes.io/ingress.class: "{{ .Values.config.ingressClass }}" | ||
{{- end }} | ||
nginx.ingress.kubernetes.io/enable-cors: "true" | ||
nginx.ingress.kubernetes.io/cors-allow-origin: "{{ required "Must specify allowOrigin" .Values.allowOrigin }}" | ||
spec: | ||
{{- if $ingressFieldNotAnnotation }} | ||
ingressClassName: "{{ .Values.config.ingressClass }}" | ||
{{- end }} | ||
tls: | ||
- hosts: | ||
- "{{ .Values.host }}" | ||
secretName: "{{ include "outlook.fullname" . }}" | ||
rules: | ||
- host: "{{ .Values.host }}" | ||
http: | ||
paths: | ||
- path: / | ||
pathType: Prefix | ||
backend: | ||
service: | ||
name: {{ include "outlook.fullname" . }} | ||
port: | ||
number: 8080 |
Oops, something went wrong.