-
Notifications
You must be signed in to change notification settings - Fork 6
/
envs.go
169 lines (155 loc) · 4.12 KB
/
envs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package main
import (
"fmt"
"os"
"strings"
"sync"
)
// EnvVarTable is an environment variable table.
type EnvVarTable struct {
mux *sync.Mutex
et map[string]string
}
// Environment represents an environment.
type Environment struct {
name string
evt *EnvVarTable
}
const (
defaultBinaryImage = "alpine:3.11"
defaultNodeImage = "node:13.8.0-alpine3.11"
defaultPythonImage = "python:3.6.10-alpine3.11"
defaultRubyImage = "ruby:2.7.0-alpine3.11"
)
var (
globalEnv = "KUBED-SH_GLOBAL_ENVIRONMENT"
currentEnv *Environment
environments = make(map[string]Environment)
)
func currentenv() *Environment {
return currentEnv
}
func createenv(name string, showhint bool) {
// set up the environment variables table for our new environment:
evt := &EnvVarTable{
mux: new(sync.Mutex),
et: make(map[string]string),
}
// load and/or set default environment variables for the environment variables table:
evt.init()
env := Environment{
name: name,
evt: evt,
}
environments[name] = env
if showhint {
info("Created environment [" + name + "]")
info("To activate it, use env select " + name)
}
}
func selectenv(name string, showhint bool) error {
env, ok := environments[name]
if !ok {
return fmt.Errorf("provided environment doesn't seem to exist")
}
currentEnv = &env
setprompt()
if showhint && currentenv().name != globalEnv {
info("Selected environment [" + name + "]")
}
return nil
}
func deleteenv(name string, showhint bool) error {
_, ok := environments[name]
if !ok {
return fmt.Errorf("provided environment doesn't seem to exist")
}
// change the environment of all dprocs in the environment:
for dpid, dproc := range dpt.lt {
if dproc.Env == name {
dproc.Env = globalEnv
dpt.lt[dpid] = dproc
}
}
// re-label the resources to global env:
_, err := kubectl(false, "label", "deploy,rs,svc,po", "--selector=env="+name, "--overwrite", "env="+globalEnv)
if err != nil {
warn("Can't move processes from " + name + " to global environment")
}
// set current env to global env and get rid of env
_ = selectenv(globalEnv, true)
delete(environments, name)
if showhint {
info("Deleted environment [" + name + "], now all processes are in the global environment")
}
return nil
}
// set sets an environment variable
func (et *EnvVarTable) set(envar, value string) {
et.mux.Lock()
et.et[envar] = value
et.mux.Unlock()
}
// get returns the value of an environment variable
func (et *EnvVarTable) get(envar string) string {
et.mux.Lock()
val, ok := et.et[envar]
et.mux.Unlock()
if !ok {
return ""
}
return val
}
// unset removes an environment variable
func (et *EnvVarTable) unset(envar string) {
et.mux.Lock()
delete(et.et, envar)
et.mux.Unlock()
}
// init sets default env vars and loads some
// such as $PATH, $HOME, etc. from parent shell.
func (et *EnvVarTable) init() {
// set defaults:
et.set("SERVICE_PORT", "80")
et.set("SERVICE_NAME", "")
et.set("BINARY_IMAGE", defaultBinaryImage)
et.set("NODE_IMAGE", defaultNodeImage)
et.set("PYTHON_IMAGE", defaultPythonImage)
et.set("RUBY_IMAGE", defaultRubyImage)
et.set("HOTRELOAD", "false")
// load from parent shell, if present:
val, ok := os.LookupEnv("KUBECTL_BINARY")
if ok {
et.set("KUBECTL_BINARY", val)
}
val, ok = os.LookupEnv("PATH")
if ok {
et.set("PATH", val)
}
val, ok = os.LookupEnv("HOME")
if ok {
et.set("HOME", val)
}
}
func setprompt() {
context, err := kubectl(false, "config", "current-context")
if err != nil {
warn("Can't determine current context")
}
namespace, err := kubectl(false, "run", "ns", "--rm", "-i", "-t", "--restart=Never", "--image=alpine:3.7", "--", "cat", "/var/run/secrets/kubernetes.io/serviceaccount/namespace")
if err != nil {
warn("Can't determine namespace")
namespace = ""
}
namespace = strings.TrimSuffix(namespace, "pod \"ns\" deleted")
env := currentenv().name
debug(env + " " + context + " " + namespace)
if rl != nil {
switch env {
case globalEnv:
rl.SetPrompt(fmt.Sprintf("[\033[32m%s\033[0m::\033[36m%s\033[0m]$ ", context, namespace))
default:
rl.SetPrompt(fmt.Sprintf("[\033[95m%s\033[0m@\033[32m%s\033[0m::\033[36m%s\033[0m]$ ", env, context, namespace))
}
}
}