OCI SDK を環境変数で利用するためのライブラリ(envprovider)を作ってみた

# はじめに

Oracle Cloud Infrastructure の SDK を使ったことありますか？ SDKを実行するために必要な作業があります。
OCI へ接続するために、configファイルや秘密鍵をファイルとして保存する必要があります。
めんどくさくないですか？ **自分はめんどくさいです。**
なにがめんどくさいかを書くと、コンテナからSDKを操作したいときに、コンテナの中に秘密鍵を格納するのはセキュリティ的に回避したい、と考えだす必要があることです。

これを簡単するために、`envprovider `という名前のライブラリを作りました。Go言語のSDKで使用可能です。
https://github.com/Sugi275/oci-env-configprovider

OCIへ接続するために必要な全ての情報を、環境変数で渡すことが出来るので、ファイルを事前に作成しておく必要がありません。
使い方を紹介します。



# envprovider の install

go コマンドの標準的な方法で install が出来ます。

```
go get -u github.com/Sugi275/oci-env-configprovider/envprovider
```



# 環境変数の設定

OCIへ接続するために必要な情報を、環境変数に設定します。以下の7種類の情報を環境変数へ設定します。



- OCI_PRIVKEY_BASE64 : OCIへ接続するための秘密鍵を、base64でエンコードした文字列
- OCI_PRIVKEY_PASS : 秘密鍵に紐づくパスフレーズ。パスフレーズを指定していない場合は、環境変数を設定しなくても良い。`""` を指定しても良い。
- OCI_TENANCY_OCID : 操作したいテナンシーの OCID
- OCI_USER_OCID : 操作したいユーザの OCID (秘密鍵にひもづくユーザ)
- OCI_PUBKEY_FINGERPRINT : OCIへ登録した公開鍵のフィンガープリント
- OCI_REGION : リージョン名
- OCI_COMPARTMENT_OCID : CompartmentのOCID



## bash

```
export OCI_PRIVKEY_BASE64=`base64 ~/.oci/oci_api_key.pem`
export OCI_PRIVKEY_PASS="secret"
export OCI_TENANCY_OCID="ocid1.tenancy.oc1..secret"
export OCI_USER_OCID="ocid1.user.oc1..secret"
export OCI_PUBKEY_FINGERPRINT="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"
export OCI_REGION="us-phoenix-1"
export OCI_COMPARTMENT_OCID="ocid1.tenancy.oc1..secret"
```



## fish

fish shell を使用している場合は、区切り文字 (Internal Filed Separator) を変更する必要があります。
default の IFS には改行も含まれているため、改行を一時的にIFSから外す必要があります。

```
set IFS
set -x OCI_PRIVKEY_BASE64 (base64 /home/ubuntu/.oci/oci_api_key.pem)
set IFS \n" "\t

set -x OCI_PRIVKEY_PASS 'secret'
set -x OCI_TENANCY_OCID 'ocid1.tenancy.oc1..secret'
set -x OCI_USER_OCID 'ocid1.user.oc1..secret'
set -x OCI_PUBKEY_FINGERPRINT '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00'
set -x OCI_REGION 'us-phoenix-1'
set -x OCI_COMPARTMENT_OCID 'ocid1.tenancy.oc1..secret'
```



# Go言語のソースコード例

`"github.com/Sugi275/oci-env-configprovider/envprovider" `をImport する必要があります。
以下に例を記載します。

```go
import (
	"context"
	"fmt"
    
	"github.com/Sugi275/oci-env-configprovider/envprovider"
	"github.com/oracle/oci-go-sdk/common"
	"github.com/oracle/oci-go-sdk/dns"
)
```



OCI へ接続するためには、以下の作業が必要です。

- `envprovider.GetEnvConfigProvider()` Functionを使用して、OCI SDK に必要な ConfigrationProvider を生成。設定された環境変数を使用
- 操作したいOCIのサービスに応じた client を生成



抜粋してソースコードの例を書きます。わかりやすくするために、冗長に書きます。

```go
// 環境変数に設定された情報を使用して、OCI SDK に必要な ConfigrationProvider を生成
var envConfigProvider common.ConfigurationProvider 
envConfigProvider = envprovider.GetEnvConfigProvider()

// envConfigProviderを引数に渡して、操作したいOCIサービスのclientを生成。今回は、DNS用のclientを生成
var dnsClient dns.DnsClient
dnsClient, err = dns.NewDnsClientWithConfigurationProvider(envConfigProvider)

// Clientを使用してよしなに処理を書く
```



OCI DNS に、登録している `test.enc` のゾーンに対して、`_acme-challenge.test.enc` の TXT レコードを生成するためのソースコードを例として記載します。
なお、GitHub上にアップロードしているため、これを利用するとわかりやすいです
https://github.com/Sugi275/oci-create-dnsrecords/blob/master/ocidnstest.go

```go
package main

import (
	"context"
	"fmt"

	"github.com/Sugi275/oci-env-configprovider/envprovider"
	"github.com/oracle/oci-go-sdk/dns"
)

func main() {
	zn := "test.enc"
	dn := "_acme-challenge.test.enc"

	client, err := dns.NewDnsClientWithConfigurationProvider(envprovider.GetEnvConfigProvider())
	if err != nil {
		panic(err)
	}

	compartmentid, err := envprovider.GetCompartmentID()
	if err != nil {
		panic(err)
	}

	// DNSのレコードを作成するパラメータを生成
	txttype := "TXT"
	falseFlg := false
	rdata := "testdayo"
	ttl := 30

	recordDetails := dns.RecordDetails{
		Domain:      &dn,
		Rdata:       &rdata,
		Rtype:       &txttype,
		Ttl:         &ttl,
		IsProtected: &falseFlg,
	}

	var recordDetailsList []dns.RecordDetails
	recordDetailsList = append(recordDetailsList, recordDetails)

	updateDomainRecordsDetails := dns.UpdateDomainRecordsDetails{
		Items: recordDetailsList,
	}

	request := dns.UpdateDomainRecordsRequest{
		ZoneNameOrId:               &zn,
		Domain:                     &dn,
		UpdateDomainRecordsDetails: updateDomainRecordsDetails,
		CompartmentId:              &compartmentid,
	}

	ctx := context.Background()
	response, err := client.UpdateDomainRecords(ctx, request)
	if err != nil {
		panic(err)
	}
	fmt.Println(response)
}
```





# 参考URL

https://github.com/Sugi275/oci-env-configprovider

https://github.com/oracle/oci-go-sdk