ProjectsveltoでのEventTriggerとConfigMapGeneratorの使い方

## はじめに

Kubernetesのクラスター管理ツールであるProjectsveltosには、イベント駆動型のリソース管理機能が複数あります。今回は特にEventTriggerとConfigMapGeneratorの関係と使い方について理解を深めていきます。この記事は自分の理解のための備忘録として書いています。

## 目次
1. EventTriggerの基本機能
2. EventReportとConfigMapGeneratorの違い
3. ConfigMapGeneratorの活用例
4. EventSourceのLuaスクリプトからの移行

## EventTriggerの基本機能

EventTriggerはKubernetesリソースに変更があった際に、対応するClusterProfilesを作成するためのメカニズムです。主な特徴は：

- リソースデータを使用してTemplateResourceRefsをインスタンス化
- ConfigMap/Secretの参照方法が注釈によって異なる動作
- ClusterProfile作成後はアドオンコントローラーに処理が移る

EventTriggerは、監視対象のリソースに変更があると、そのリソースデータを用いてClusterProfileを生成します。生成されたClusterProfileはアドオンコントローラーによって適切なクラスターにデプロイされます。

## EventReportとConfigMapGeneratorの違い

EventReportとConfigMapGeneratorの大きな違いは、リソースデータの扱い方にあります：

- **EventReport**: マッチしたリソースの全データが含まれるが、加工はされない
- **ConfigMapGenerator**: マッチしたリソースデータを元にテンプレート処理して新しいConfigMapを生成

EventReportのリソース名も予測可能ですが、**ConfigMapGeneratorはリソースデータを加工した状態でClusterProfileに渡せる**という大きなメリットがあります。

## ConfigMapGeneratorの活用例

### 1. テンプレートとなるConfigMapを定義

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: namespaces
  namespace: default
  annotations:
    projectsveltos.io/instantiate: "true" # イベントデータで置換される
data:
  namespaces: |
    {{- range $v := .MatchingResources }}
       {{ $v.Name }}: "ok"
    {{- end }}
```

### 2. 生成されるConfigMap

上記のテンプレートから、以下のようなConfigMapが生成されます：

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: default-workload-namespaces
  namespace: projectsveltos
data:
  namespaces: |
    eng: "ok"
    hr: "ok"
```

### 3. さらにテンプレート処理で活用

生成されたConfigMapは、別のテンプレート処理の入力として使用できます：

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: info
  namespace: default
  annotations:
    projectsveltos.io/template: "true" 
data:
  secret.yaml: |
    {{ $namespaces := ( ( index (getResource "Namespaces").data "namespaces" ) | fromYaml ) }}
    {{- range $key, $value := $namespaces }}
        apiVersion: v1
        kind: Secret
        metadata:
          namespace: {{ $key }}
          name: {{ (getResource "Credentials").metadata.name }}
        data:
          {{- range $secretKey, $secretValue := (getResource "Credentials").data }}
            {{ $secretKey }} : {{ $secretValue }}
          {{- end }}
    ---
    {{- end }}
```

### 4. 最終結果

上記の処理によって、各名前空間に対応したSecretリソースが生成されます：

```yaml
---
apiVersion: v1
kind: Secret
metadata:
  namespace: eng          # <- 1回目の$key
  name: <credentials-name>
data:
  <credentials-key-1>: <encoded-value-1>
  <credentials-key-2>: <encoded-value-2>
---
apiVersion: v1
kind: Secret
metadata:
  namespace: hr          # <- 2回目の$key
  name: <credentials-name>
data:
  <credentials-key-1>: <encoded-value-1>
  <credentials-key-2>: <encoded-value-2>
---
```

## EventSourceのLuaスクリプトからの移行

これまでEventSourceのaggregatedSelectionのLuaスクリプトを使ってリソース値を集約・加工し、EventTriggerに渡すというハックをしていた場合でも、ConfigMapGeneratorを使うことでその処理を置き換えられそうです。

ConfigMapGeneratorは：
- 集約されたデータを構造化された形で保存
- テンプレート処理によるさらなる加工が可能
- ClusterProfileから予測可能な方法でアクセス可能

これによって、Luaスクリプトによるハック的な処理をより宣言的な方法で実現できます。

## まとめ

ProjectsveltosのConfigMapGeneratorを利用することで、イベントデータをより柔軟に加工し、それをClusterProfileの処理に渡すことができます。この機能によって、これまでEventSourceのLuaスクリプトで行っていた複雑な処理も、より宣言的で管理しやすい方法に置き換えることができそうです。

参考文献: [Projectsveltos公式ドキュメント - Generators](https://projectsveltos.github.io/sveltos/events/generators/#configmapgenerators-and-secretgenerators)