Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜GitHub Integration編〜

はじめに
[前回の記事](https://qiita.com/shin7446/items/b54ebda4ee91ea5f4ca2)では、Red Hat Developer Hub(RHDH)にログインするためのGitHub OAuth設定を行いました。
ここではGolden Pathの登録前に必要なGitHubとRHDHの連携設定を行います。


# 実現する環境
今回は以下の環境を構成します。
![ScreenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/e5c69ce7-0a0a-9d3d-5e72-bc99bae59a0a.png)


# 章項目
今回のテーマは6つの記事で構成されています。
* [Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜環境導入編〜](https://qiita.com/shin7446/items/bafb3619caf5c8ba28c1) 
* [Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜認証設定編〜](https://qiita.com/shin7446/items/b54ebda4ee91ea5f4ca2) 
* [Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜GitHub Integration編〜](https://qiita.com/shin7446/items/c35010c3ea566beadc5a) この記事
* [Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜Golden Path作成編①〜](https://qiita.com/shin7446/items/ce86d9bbb5121579f9ce)
* [Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜Golden Path作成編②〜](https://qiita.com/shin7446/items/0c181c2f7cc63917bd7c)
* Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜Component UI改善編〜

# 前提条件
以下の記事の実行が完了していること
1. [Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜環境導入編〜](https://qiita.com/shin7446/items/bafb3619caf5c8ba28c1) 
1. [Red Hat Developer Hub (Backstage) でGolden Pathを作ろう〜認証設定編〜](https://qiita.com/shin7446/items/b54ebda4ee91ea5f4ca2)


# RHDH(Backstage)の設定方法 おさらい
RHDHは、基本的に以下の4つの方法で設定を適用していきます。
1. Helmのvaluesに追加の設定を記載の上、`helm upgrade`を実行する
1. `app-config.yaml`というファイルに各種設定を記載の上、`Configmap`でPodにアタッチする
1. `app-config.yaml`にGithub上のファイルパスを記載し、GitHub上から設定情報を取得してくる
1. `Configmap`や`Secret`で設定ファイルや環境変数をマウントし、それを読み込む


そのために前回までいくつかファイルを作成してきました。
```
app-config-rhdh.yaml
create-secret.sh
values.yaml
```

この記事では上記のファイルの更新だけでなく、追加の設定ファイルをいくつか作成し適用していきます。

# GitHubとの連携
まずはじめにGitHubとの連携設定を行います。
RHDHは開発ポータルという特性上、Gitと様々な連携機能を具備しています。
そのため、最初にお使いのGitサービス(GitHub/GitLab)と連携設定を済ませておくことで後の機能追加が楽になります。
今回はGitHub.comとの連携を前提に作業を進めていきます。

## GitHub Appを作成する
Backstageの公式ドキュメントにある通り、GitHub連携の大元となるGitHub Appを作成していきます。
基本的にRHDHでも手順はBackstageと同様になるので、以下の2つのページを参考に作業します。

* GitHub Appの作成

https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app

* GitHub AppとBackstageの連携

https://backstage.io/docs/integrations/github/github-apps


まずはGitHub Appを作成しましょう。
前回の記事でGitHub Organizationを作成したので、こちらにGitHub Appを作っていきます。

Organizationのページから`Settings`を選択します。
![ScreenShot 137.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/d00d2b64-4792-117f-ab92-1df069ac9b2a.png)

左から`Developer settings`→`GitHub Apps`を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/f495428e-e407-cae7-fe2f-9e8a79e9ae86.png"  width=50%>

`New GitHub App`を選択します。
![ScreenShot 139.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/e0eeb0b8-aaba-b6db-a2cc-f52bf1c92e2e.png)


* `GitHub App name`
    * 任意のApp名を入力します。
* `Homepage URL`
    * RHDHのRouteのURLを入力します。
* `Callback URL`
    * `RHDHのRouteのURL`+`/api/auth/github/handler/frame`を記載します。
    *  `Expire user authorization tokens`のチェックは外しておきます。
* `Post installation`
    * 今回は入力不要です。
* `Webhook URL`
    * RHDHのRouteのURLを入力します。
* Webhook secret
    * こちらは任意の値でOKです。
* `Permissions`
    * Backstageで必要となる権限は以下のページに記載されていますので、こちらを参考に許可設定します。

https://backstage.io/docs/integrations/github/github-apps#app-permissions

* `Where can this GitHub App be installed?`
    * `Only on this account`を選択します。


この状態で`Create GitHub App`を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/4d33c9bf-827d-2cf4-cd93-1b48141e69ef.png"  width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/56604c46-be4e-1561-01f5-1f433110a236.png"  width=50%>


GitHub Appの作成が完了すると、以下のページに遷移し、`APP ID`と`Client ID`が払い出されます。
これらを環境変数に格納しておきましょう。
```
export GITHUB_APP_APP_ID="<App ID>"
export GITHUB_APP_CLIENT_ID="<Client ID>"
```
![ScreenShot 142.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/442b38c8-f689-7c29-8d97-186f4eddbe9b.png)

そのまま`Generate a new client secret`を選択し、Client Secretを払い出します。
こちらも環境変数に格納しておきます。
```
export GITHUB_APP_CLIENT_SECRET="<Client secret>"
```
![ScreenShot 143.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/3b74dd51-7908-316f-bcc1-13698ac8574d.png)

さらに画面下に移動し、`Generate a private key`でPrivate keyも作成しておきます。
![ScreenShot 144.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/de5230d3-1e3e-e534-5256-179472223563.png)

するとPrivate Key　のファイルがダウンロードされるので、こちらの中身も環境変数に格納します。
```
export GITHUB_APP_PRIVATE_KEY=$(cat <ファイルパス/ファイル名>)
```

また、Webhookで設定した値も環境変数に格納します。Webhook URLにはきちんと`https://`が含まれていることを確認してください。
```
export GITHUB_APP_WEBHOOK_URL="<Webhook URL(RHDHのRoute URL)>"
export GITHUB_APP_WEBHOOK_SECRET="<Webhook secret(任意の値)>"
```


最後に作成したGitHub AppをOrganizationにインストールします。
左の`Install App`を選択し、表示されたOrganizationの`Install`を選択します。
![ScreenShot 146.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/2c468425-62ec-dd6f-f4c5-e2ce159f3a70.png)


確認画面が出るので`Install`を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/249c0e97-487d-29d0-8294-2962a2de2f4a.png"  width=50%>

以上でGitHub側の作業は完了です。

## RHDHへ連携設定を行う
次にRHDHへの連携設定を進めます。
まずは`app-config-rhdh.yaml`に以下の内容を追記します。
```app-config-rhdh.yaml
data:
  app-config-rhdh.yaml: |
    app:
      title: Red Hat Developer Hub
    auth:
    ____omit____
    # ここから
    integrations:
      github:
      - host: github.com
        apps:
          - appId: ${GITHUB_APP_APP_ID}
            clientId: ${GITHUB_APP_CLIENT_ID}
            clientSecret: ${GITHUB_APP_CLIENT_SECRET}
            webhookUrl: ${GITHUB_APP_WEBHOOK_URL}
            webhookSecret: ${GITHUB_APP_WEBHOOK_SECRET}
            privateKey: |
              ${GITHUB_APP_PRIVATE_KEY}
    # ここまで
```
先ほど環境変数に格納した値を設定しているのが分かるかと思います。
これらの値は`Secret`から渡すため、あわせて`create-secret.sh`も修正します。
```create-secret.sh
#/bin/bash

# 古いSecretを削除
oc delete -n rhdh secret rhdh-secrets

# Secret作成
oc -n rhdh create secret generic rhdh-secrets \
  --from-literal=AUTH_GITHUB_CLIENT_ID="${AUTH_GITHUB_CLIENT_ID}" \
  --from-literal=AUTH_GITHUB_CLIENT_SECRET="${AUTH_GITHUB_CLIENT_SECRET}" \
  --from-literal=GITHUB_APP_CLIENT_ID="${GITHUB_APP_CLIENT_ID}" \
  --from-literal=GITHUB_APP_CLIENT_SECRET="${GITHUB_APP_CLIENT_SECRET}" \
  --from-literal=GITHUB_APP_WEBHOOK_URL="${GITHUB_APP_WEBHOOK_URL}" \
  --from-literal=GITHUB_APP_WEBHOOK_SECRET="${GITHUB_APP_WEBHOOK_SECRET}" \
  --from-literal=GITHUB_APP_PRIVATE_KEY="${GITHUB_APP_PRIVATE_KEY}"

# Configmapの更新
oc apply -f $(dirname $0)/app-config-rhdh.yaml

# Configmap/Secretの変更を反映させるためにPodを再起動
oc rollout restart deploy developer-hub -n rhdh
```

環境変数がきちんと格納できているのかを一度確認しておきましょう。
```
envsubst < create-secret.sh
```

確認ができたら`create-secret.sh`を実行してConfigmapとSecretを反映させます。
```
cat create-secret.sh | envsubst | bash
```

しばらく待って、問題なくPodが`Running`になるか確認しましょう。`Error`が出ているとどこかで設定がうまく行っていません。ログを見て被疑箇所を特定しましょう。
![ScreenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/8f8e6143-af45-7912-db9c-65e659cac1ec.png)

これでGitHub　AppとRHDHの連携設定が完了しました。
この状態でRHDHにアクセスしても、実は何も変化はありません。これまでの作業はこれから反映させる設定の前段階の作業になります。
この先で実際にRHDHの利用に関わる設定を行っていきます。

# ユーザー管理
RHDHでは、専用のユーザー／グループ管理機能を具備しています。どのCatalogがどのユーザーでデプロイされたのかや、だれがどのグループに属しているかなどを管理できます。

この機能は将来的に柔軟な権限管理に利用される予定ですが、現在ではCatalogの管理目的の側面が強いです。Catalogってなんなの？というのはのちの記事で詳しく説明します。

現在の状態でRHDHの画面下の`Settings`を選択すると、`General`画面で今のログインしているユーザー名と、`Backstage Identity`という項目が表示されます。
この`Backstage Identity`というのがまさにRHDHにおけるユーザー管理機能です。
![ScreenShot 152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/c28de8b5-9d44-a800-ffdf-76c5c2009f0b.png)

この`User Entity`のユーザー名のリンクを選択すると、以下のようにエラーが表示されます。これはRHDH内にユーザーが登録されていないため発生しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/c7069e08-de6d-6e17-55ce-984d0fb0328c.png"  width=50%>

ではRHDHにユーザーやグループの登録を行いましょう。

RHDHにユーザーを登録する手順は大きく2つあります。
1. ユーザーやグループを定義するyamlファイルをGitHub上に格納し、URLを指定して読み込む
1. GitHubのOrganizationの情報と連携させる

1の場合、RHDHの利用ユーザーを追加するたびにyamlファイルを編集する必要があり手間なので、今回はGitHubのOrganizationと連携させます。

## プラグインのインストール
GitHubからユーザー情報を取得するにあたり、追加でプラグインをインストールする必要があります。
このプラグインというのがBackstageのメイン機能のひとつになります。
Backstageは様々なベンダーやユーザーが作成したプラグインを導入することで、様々な追加機能を実現することができます。
今後のGolden Pathの作成・実行やCatalogの表示の部分でも、いろんなプラグインを適宜導入しながらUIを改善させていきます。
今回の`GitHub Organizationとの連携によるユーザー管理`においても、このプラグインの導入によって実現可能になります。


### 動的プラグイン
実はこの`プラグインのインストール`において、RHDHはBackstageと比べて便利な機能を具備しています。
現在、Backstageではプラグインのインストールに**再コンパイル**が必要になります。要はプラグイン導入の度に毎回Backstageのコンテナビルドが必要になるということです。
一方でRHDHでは`動的プラグインのインストール`機能を提供しており、ユーザーは必要となるプラグインを設定ファイルに記載し、コンテナを再起動するだけでプラグインの導入を実現できます。

RHDHが現在動的プラグインとして導入可能としているものの一覧はRHDHの公式ドキュメントに記載されています。2024年1月時点で47個あります。　

https://access.redhat.com/documentation/ja-jp/red_hat_developer_hub/1.0/html/administration_guide_for_red_hat_developer_hub/rhdh-supported-plugins

早速この動的プラグインを使って、GitHub Organizationのユーザー情報を連携させてみましょう。


まず、helmのvalue.yamlを書き換えます。
以下のように、`global.dynamic`配下に`plugins`を準備し、`package`情報を記載します。
この`package`の情報は、上記RHDH公式ドキュメントの`表5.1 動的プラグインのサポートマトリクス`の`パス(Path)`にあります。
今回はGitHub Organizationの情報を取得すべく、`plugin-catalog-backend-module-github-org`を導入します。
そして`disable: false`にしてインストールを許可します。
```values.yaml(抜粋)
global:
  dynamic:
    plugins:
      - package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic
        disabled: false
```

ではhelm upgradeを実行しましょう。
```
helm upgrade -i developer-hub -n rhdh -f values.yaml openshift-helm-charts/redhat-developer-hub
```

実行すると、おそらくPodがErrorになるかと思います。これはプラグインの導入に必要なConfigが渡されていないことが原因です。
```
NAME                             READY   STATUS    RESTARTS      AGE
developer-hub-68bd78c985-2t2rr   1/1     Running   0             5h18m
developer-hub-c64f7dc57-hh8k7    0/1     Error     1 (14s ago)   36s
developer-hub-postgresql-0       1/1     Running   0             5h18m
```
```
oc logs developer-hub-c64f7dc57-hh8k7 
Error: Missing required config value at 'catalog.providers.githubOrg.default.orgUrl'
```

そのため、`app-config-rhdh.yaml`に必要な設定を追加してあげましょう。
```app-config-rhdh.yaml
    app:
      title: Red Hat Developer Hub
    auth:
    ___omit___
    integrations:
    ___omit___
    # ここから
    catalog:
      providers:
        githubOrg:
          default:
            id: production
            orgUrl: 'https://github.com/${GITHUB_ORG_NAME}'
    # ここまで
```
`GITHUB_ORG_NAME`は`Secret`から渡すため、`create-secret.sh`も編集します。
```create-secret.sh(抜粋)
# Secret作成
oc -n rhdh create secret generic rhdh-secrets \
___omit___
--from-literal=GITHUB_ORG_NAME="${GITHUB_ORG_NAME}" # ここを追記
```
値を環境変数に格納します。
```
export GITHUB_ORG_NAME="<GitHub Organizationの名前>"
```

これで準備は完了です。
`Configmap`と`Secret`の変更の前に、GitHub Organizationのメンバー情報を少し変えておきます。

きちんとGitHubからユーザー情報を連携できていることを確認するために、以下のように設定しました。
* 作成した`Organization`に新たにユーザーを1名追加
* `Organization`配下に`Team`を作成し、メンバーの2名を`Team`に所属
![ScreenShot 154.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/f9718e87-45b3-7cf8-e5a9-484a50a7b256.png)
![ScreenShot 155.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/d38fd2d2-9636-4091-367e-12a1b39bf5ff.png)

この情報を取得できるかを確認します。ではConfigmapとSecretを変更します。
```
cat create-secret.sh | envsubst | bash
```

しばらくまってPodが正常にRunningになることを確認し、RHDHにアクセスします。
`Settings`画面に移動すると、`Backstage Identity`の部分が少し変わっていることがわかります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/3388b38d-a20c-8aff-9850-fe56eb95b6dd.png"  width=50%>
`Ownership Entities`に`group`が追加されています。
このように、GitHub Organization上の`Team`がRHDHでは`Group`として認識されます。

まずは`user`の情報を選択してみましょう。
すると先ほどエラーだった画面が正常に表示されました。
![ScreenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/03015786-dcfe-2c54-7f94-158fac83fb77.png)
さらに`team`情報も表示されているため、そこを選択するとGroup(Team)情報も確認できます。
![ScreenShot 157.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419286/e1f61a74-bb1a-99b1-f005-ac8eae24d4f2.png)

これでGitHub Organizationのユーザー情報とRHDHを連携することができました。
ちなみにこのOrganization情報との同期は現在1時間に1回実行されます。将来的にはこの間隔も設定可能になる想定です。


# おわりに
この記事では、GitHubとの連携設定とOrganizationのユーザー情報の取得を行いました。
次回の記事ではいよいよGolden Pathの作成に入っていきます。