internal/service/handler.go (106 lines of code) (raw):
package service
import (
"context"
"encoding/json"
"errors"
"fmt"
kmssdk "github.com/alibabacloud-go/kms-20160120/v3/client"
"github.com/aliyun/alibabacloud-kms-agent/internal/model"
"net/http"
"time"
)
const (
QueryParamsSecretId = "secretId"
QueryParamsVersionId = "versionId"
QueryParamsVersion = "version"
QueryParamsVersionStage = "versionStage"
)
func (s *Server) handlePing(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprintln(w, "healthy")
}
func (s *Server) handleGetSecret(w http.ResponseWriter, r *http.Request) {
params, err := getSecretParams(r, s.pathPrefix)
if err != nil {
s.loggerWrapper.Error("get secret params error:%v", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
ctx, cancel := context.WithTimeout(r.Context(), time.Second*10)
defer cancel()
secret, err := s.FetchSecret(ctx, params)
if err != nil {
var v *model.ErrorResponse
if errors.As(err, &v) {
http.Error(w, v.Error(), v.StatusCode)
} else {
http.Error(w, err.Error(), http.StatusFailedDependency)
}
return
}
payload, err := transResponseFormat(secret, s.responseType)
if err != nil {
s.loggerWrapper.Error("trans response format error:%v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, err = w.Write(payload)
if err != nil {
http.Error(w, "Failed to write data", http.StatusInternalServerError)
}
}
func transResponseFormat(secret string, t model.ResponseType) (payload []byte, err error) {
// alibaba cloud kms format
if t == model.ResponseTypeForAliyunKMS {
return []byte(secret), nil
}
var secretValue kmssdk.GetSecretValueResponseBody
err = json.Unmarshal([]byte(secret), &secretValue)
if err != nil {
err = fmt.Errorf("unmarshal secret value error:%w", err)
return
}
// aws format
if t == model.ResponseTypeForAWSSecretManager {
secretInfo := &model.SecretManagerResponse{
Name: *secretValue.SecretName,
VersionId: *secretValue.VersionId,
SecretString: *secretValue.SecretData,
VersionStages: make([]string, 0),
CreatedDate: *secretValue.CreateTime,
}
if len(secretValue.VersionStages.VersionStage) > 0 {
for _, v := range secretValue.VersionStages.VersionStage {
secretInfo.VersionStages = append(secretInfo.VersionStages, *v)
}
}
payload, err = json.MarshalIndent(secretInfo, "", " ")
if err != nil {
err = fmt.Errorf("marshal secret info error:%w", err)
return
}
}
// vault kv format
if t == model.ResponseTypeForVaultKvSecret {
var data map[string]interface{}
err = json.Unmarshal([]byte(*secretValue.SecretData), &data)
if err != nil {
err = errors.New("secret data not kv format")
return
}
kvSecret := &model.KVSecret{
Data: data,
Metadata: &model.SecretMetadata{
CreatedTime: *secretValue.CreateTime,
},
}
kvV2SecretData := model.KvV2SecretData{
Data: kvSecret,
}
payload, err = json.Marshal(kvV2SecretData)
if err != nil {
err = fmt.Errorf("marshal secret data error:%w", err)
return
}
}
return
}