mirror of
https://github.com/onepanelio/onepanel.git
synced 2025-10-10 08:00:10 +08:00
188 lines
5.1 KiB
Go
188 lines
5.1 KiB
Go
package kube
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
goerrors "errors"
|
|
|
|
"github.com/onepanelio/core/model"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
)
|
|
|
|
func (c *Client) CreateSecret(namespace string, secret *model.Secret) (err error) {
|
|
_, err = c.CoreV1().Secrets(namespace).Create(&corev1.Secret{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: secret.Name,
|
|
},
|
|
StringData: secret.Data,
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
func (c *Client) SecretExists(namespace string, secret *model.Secret) (*model.Secret, error) {
|
|
secretK8s, err := c.CoreV1().Secrets(namespace).Get(secret.Name, metav1.GetOptions{})
|
|
if err != nil {
|
|
return &model.Secret{}, err
|
|
}
|
|
retSecret := model.Secret{
|
|
Name: secretK8s.Name,
|
|
}
|
|
return &retSecret, nil
|
|
}
|
|
|
|
func (c *Client) GetSecret(namespace string, secret *model.Secret) (*model.Secret, error) {
|
|
foundSecret, err := c.CoreV1().Secrets(namespace).Get(secret.Name, metav1.GetOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if foundSecret != nil {
|
|
return &model.Secret{
|
|
Name: foundSecret.Name,
|
|
Data: convertSecretToMap(foundSecret),
|
|
}, nil
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (c *Client) ListSecrets(namespace string) (secrets []*model.Secret, err error) {
|
|
secretsList, err := c.CoreV1().Secrets(namespace).List(metav1.ListOptions{})
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, secret := range secretsList.Items {
|
|
secretModel := model.Secret{
|
|
Name: secret.Name,
|
|
Data: convertSecretToMap(&secret),
|
|
}
|
|
secrets = append(secrets, &secretModel)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (c *Client) DeleteSecret(namespace string, secret *model.Secret) (err error) {
|
|
return c.CoreV1().Secrets(namespace).Delete(secret.Name, &metav1.DeleteOptions{})
|
|
}
|
|
|
|
func (c *Client) DeleteSecretKey(namespace string, name string, key string) (deleted bool, err error) {
|
|
//Check if the secret has the key to delete
|
|
secretFound, secretFindErr := c.GetSecret(namespace, name)
|
|
if secretFindErr != nil {
|
|
return false, secretFindErr
|
|
}
|
|
secretDataKeyExists := false
|
|
for secretDataKey := range secretFound.Data {
|
|
if secretDataKey == key {
|
|
secretDataKeyExists = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if secretDataKeyExists {
|
|
// patchStringPath specifies a patch operation for a secret key.
|
|
type patchStringPath struct {
|
|
Op string `json:"op"`
|
|
Path string `json:"path"`
|
|
}
|
|
payload := []patchStringPath{{
|
|
Op: "remove",
|
|
Path: "/data/" + key,
|
|
}}
|
|
payloadBytes, _ := json.Marshal(payload)
|
|
_, errSecret := c.CoreV1().Secrets(namespace).Patch(name, types.JSONPatchType, payloadBytes)
|
|
if errSecret != nil {
|
|
return false, errSecret
|
|
}
|
|
return true, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (c *Client) AddSecretKeyValue(namespace string, name string, key string, value string) (inserted bool, err error) {
|
|
//Check if the secret has the key already
|
|
secretFound, secretFindErr := c.GetSecret(namespace, name)
|
|
if secretFindErr != nil {
|
|
return false, secretFindErr
|
|
}
|
|
|
|
if secretFound == nil {
|
|
return false, goerrors.New("Secret was not found.")
|
|
}
|
|
|
|
if len(secretFound.Data) > 0 {
|
|
secretDataKeyExists := false
|
|
for secretDataKey := range secretFound.Data {
|
|
if secretDataKey == key {
|
|
secretDataKeyExists = true
|
|
break
|
|
}
|
|
}
|
|
if secretDataKeyExists {
|
|
errorMsg := "Key: " + key + " already exists in secret."
|
|
return false, goerrors.New(errorMsg)
|
|
}
|
|
}
|
|
// patchStringPathAddNode specifies an add operation for a node
|
|
type patchStringPathAddNode struct {
|
|
Op string `json:"op"`
|
|
Path string `json:"path"`
|
|
Value map[string]string `json:"value"`
|
|
}
|
|
|
|
// "/data" may not exist due to 0 items. Create it so we can add an element.
|
|
if len(secretFound.Data) == 0 {
|
|
valMap := make(map[string]string)
|
|
valueEnc := base64.StdEncoding.EncodeToString([]byte(value))
|
|
valMap[key] = valueEnc
|
|
payloadAddNode := []patchStringPathAddNode{{
|
|
Op: "add",
|
|
Path: "/data",
|
|
Value: valMap,
|
|
}}
|
|
payloadAddNodeBytes, err := json.Marshal(payloadAddNode)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
_, errSecret := c.CoreV1().Secrets(namespace).Patch(name, types.JSONPatchType, payloadAddNodeBytes)
|
|
if errSecret != nil {
|
|
return false, errSecret
|
|
}
|
|
return true, nil
|
|
}
|
|
// patchStringPathAddKeyValue specifies an add operation, a key and value
|
|
type patchStringPathAddKeyValue struct {
|
|
Op string `json:"op"`
|
|
Path string `json:"path"`
|
|
Value string `json:"value"`
|
|
}
|
|
valueEnc := base64.StdEncoding.EncodeToString([]byte(value))
|
|
payload := []patchStringPathAddKeyValue{{
|
|
Op: "add",
|
|
Path: "/data/" + key,
|
|
Value: valueEnc,
|
|
}}
|
|
payloadBytes, _ := json.Marshal(payload)
|
|
_, errSecret := c.CoreV1().Secrets(namespace).Patch(name, types.JSONPatchType, payloadBytes)
|
|
if errSecret != nil {
|
|
return false, errSecret
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (c *Client) UpdateSecretKeyValue(namespace string, name string, payloadBytes []byte) (err error) {
|
|
_, err = c.CoreV1().Secrets(namespace).Patch(name, types.JSONPatchType, payloadBytes)
|
|
return
|
|
}
|
|
|
|
func convertSecretToMap(foundSecret *corev1.Secret) (modelData map[string]string) {
|
|
modelData = make(map[string]string)
|
|
for secretKey, secretData := range foundSecret.Data {
|
|
modelData[secretKey] = string(secretData)
|
|
}
|
|
return modelData
|
|
}
|