Files
kubevela/pkg/utils/env/env.go
2021-03-31 21:21:28 +08:00

273 lines
7.1 KiB
Go

/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package env
import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8stypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/utils/system"
)
// GetEnvDirByName will get env dir from name
func GetEnvDirByName(name string) string {
envdir, _ := system.GetEnvDir()
return filepath.Join(envdir, name)
}
// GetEnvByName will get env info by name
func GetEnvByName(name string) (*types.EnvMeta, error) {
data, err := ioutil.ReadFile(filepath.Join(GetEnvDirByName(name), system.EnvConfigName))
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("env %s not exist", name)
}
return nil, err
}
var meta types.EnvMeta
if err = json.Unmarshal(data, &meta); err != nil {
return nil, err
}
return &meta, nil
}
// CreateOrUpdateEnv will create or update env.
// If it does not exist, create it and set to the new env.
// If it exists, update it and set to the new env.
func CreateOrUpdateEnv(ctx context.Context, c client.Client, envName string, envArgs *types.EnvMeta) (string, error) {
createOrUpdated := "created"
old, err := GetEnvByName(envName)
if err == nil {
createOrUpdated = "updated"
if envArgs.Domain == "" {
envArgs.Domain = old.Domain
}
if envArgs.Email == "" {
envArgs.Email = old.Email
}
if envArgs.Namespace == "" {
envArgs.Namespace = old.Namespace
}
}
if envArgs.Namespace == "" {
envArgs.Namespace = "default"
}
var message = ""
// Check If Namespace Exists
if err := c.Get(ctx, k8stypes.NamespacedName{Name: envArgs.Namespace}, &corev1.Namespace{}); err != nil {
if !apierrors.IsNotFound(err) {
return message, err
}
// Create Namespace if not found
if err := c.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: envArgs.Namespace}}); err != nil {
return message, err
}
}
data, err := json.Marshal(envArgs)
if err != nil {
return message, err
}
envdir, err := system.GetEnvDir()
if err != nil {
return message, err
}
subEnvDir := filepath.Join(envdir, envName)
if _, err = system.CreateIfNotExist(subEnvDir); err != nil {
return message, err
}
// nolint:gosec
if err = ioutil.WriteFile(filepath.Join(subEnvDir, system.EnvConfigName), data, 0644); err != nil {
return message, err
}
curEnvPath, err := system.GetCurrentEnvPath()
if err != nil {
return message, err
}
// nolint:gosec
if err = ioutil.WriteFile(curEnvPath, []byte(envName), 0644); err != nil {
return message, err
}
message = fmt.Sprintf("environment %s %s, Namespace: %s", envName, createOrUpdated, envArgs.Namespace)
if envArgs.Email != "" {
message += fmt.Sprintf(", Email: %s", envArgs.Email)
}
return message, nil
}
// CreateEnv will only create. If env already exists, return error
func CreateEnv(ctx context.Context, c client.Client, envName string, envArgs *types.EnvMeta) (string, error) {
_, err := GetEnvByName(envName)
if err == nil {
message := fmt.Sprintf("Env %s already exist", envName)
return message, errors.New(message)
}
return CreateOrUpdateEnv(ctx, c, envName, envArgs)
}
// UpdateEnv will update Env, if env does not exist, return error
func UpdateEnv(ctx context.Context, c client.Client, envName string, namespace string) (string, error) {
var message = ""
envMeta, err := GetEnvByName(envName)
if err != nil {
return err.Error(), err
}
if err := c.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: envMeta.Namespace}}); err != nil && !apierrors.IsAlreadyExists(err) {
return message, err
}
envMeta.Namespace = namespace
data, err := json.Marshal(envMeta)
if err != nil {
return message, err
}
envdir, err := system.GetEnvDir()
if err != nil {
return message, err
}
subEnvDir := filepath.Join(envdir, envName)
// nolint:gosec
if err = ioutil.WriteFile(filepath.Join(subEnvDir, system.EnvConfigName), data, 0644); err != nil {
return message, err
}
message = "Update env succeed"
return message, err
}
// ListEnvs will list all envs
func ListEnvs(envName string) ([]*types.EnvMeta, error) {
var envList []*types.EnvMeta
if envName != "" {
env, err := GetEnvByName(envName)
if err != nil {
if os.IsNotExist(err) {
err = fmt.Errorf("env %s not exist", envName)
}
return envList, err
}
envList = append(envList, env)
return envList, err
}
envDir, err := system.GetEnvDir()
if err != nil {
return envList, err
}
files, err := ioutil.ReadDir(envDir)
if err != nil {
return envList, err
}
curEnv, err := GetCurrentEnvName()
if err != nil {
curEnv = types.DefaultEnvName
}
for _, f := range files {
if !f.IsDir() {
continue
}
data, err := ioutil.ReadFile(filepath.Clean(filepath.Join(envDir, f.Name(), system.EnvConfigName)))
if err != nil {
continue
}
var envMeta types.EnvMeta
if err = json.Unmarshal(data, &envMeta); err != nil {
continue
}
if curEnv == f.Name() {
envMeta.Current = "*"
}
envList = append(envList, &envMeta)
}
return envList, nil
}
// GetCurrentEnvName will get current env name
func GetCurrentEnvName() (string, error) {
currentEnvPath, err := system.GetCurrentEnvPath()
if err != nil {
return "", err
}
data, err := ioutil.ReadFile(filepath.Clean(currentEnvPath))
if err != nil {
return "", err
}
return string(data), nil
}
// DeleteEnv will delete env locally
func DeleteEnv(envName string) (string, error) {
var message string
var err error
curEnv, err := GetCurrentEnvName()
if err != nil {
return message, err
}
if envName == curEnv {
err = fmt.Errorf("you can't delete current using environment %s", curEnv)
return message, err
}
envdir, err := system.GetEnvDir()
if err != nil {
return message, err
}
envPath := filepath.Join(envdir, envName)
if _, err := os.Stat(envPath); err != nil {
if os.IsNotExist(err) {
err = fmt.Errorf("%s does not exist", envName)
return message, err
}
}
if err = os.RemoveAll(envPath); err != nil {
return message, err
}
message = envName + " deleted"
return message, err
}
// SetEnv will set the current env to the specified one
func SetEnv(envName string) (string, error) {
var msg string
currentEnvPath, err := system.GetCurrentEnvPath()
if err != nil {
return msg, err
}
envMeta, err := GetEnvByName(envName)
if err != nil {
return msg, err
}
//nolint:gosec
if err = ioutil.WriteFile(currentEnvPath, []byte(envName), 0644); err != nil {
return msg, err
}
msg = fmt.Sprintf("Set environment succeed, current environment is " + envName + ", namespace is " + envMeta.Namespace)
return msg, nil
}