forked from redhat-developer/odo
/
application.go
221 lines (186 loc) · 6.31 KB
/
application.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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
package application
import (
"fmt"
"github.com/golang/glog"
"github.com/pkg/errors"
applabels "github.com/redhat-developer/odo/pkg/application/labels"
"github.com/redhat-developer/odo/pkg/config"
"github.com/redhat-developer/odo/pkg/occlient"
"github.com/redhat-developer/odo/pkg/project"
)
// getDefaultAppName returns application name to be used as a default name in case the user doesn't provide a name.
// In future this function should generate name with unique suffix (app-xy1h), because there might be multiple applications.
func getDefaultAppName() string {
return "app"
}
// Create a new application
func Create(client *occlient.Client, applicationName string) error {
project := project.GetCurrent(client)
exists, err := Exists(client, applicationName)
if err != nil {
return errors.Wrap(err, "unable to create new application")
}
if exists {
return fmt.Errorf("unable to create new application, %s application already exists", applicationName)
}
cfg, err := config.New()
if err != nil {
return errors.Wrap(err, "unable to create new application")
}
err = cfg.AddApplication(applicationName, project)
if err != nil {
return errors.Wrap(err, "unable to create new application")
}
return nil
}
// List all application in current project
// Queries cluster and config file.
// Shows also empty applications (empty applications are those that are just
// mentioned in config file but don't have any object associated with it on cluster).
func List(client *occlient.Client) ([]config.ApplicationInfo, error) {
applications := []config.ApplicationInfo{}
project := project.GetCurrent(client)
cfg, err := config.New()
if err != nil {
return nil, errors.Wrap(err, "unable to create new application")
}
// All applications of the current project from config file
for i := range cfg.ActiveApplications {
if cfg.ActiveApplications[i].Project == project {
applications = append(applications, cfg.ActiveApplications[i])
}
}
// Get applications from cluster
appNames, err := client.GetLabelValues(project, applabels.ApplicationLabel, applabels.ApplicationLabel)
if err != nil {
return nil, errors.Wrap(err, "unable to list applications")
}
for _, name := range appNames {
// skip applications that are already in the list (they were mentioned in config file)
found := false
for _, app := range applications {
if app.Project == project && app.Name == name {
found = true
}
}
if !found {
applications = append(applications, config.ApplicationInfo{
Name: name,
// if this application is not in config file, it can't be active
Active: false,
Project: project,
})
}
}
return applications, nil
}
// Delete deletes the given application
func Delete(client *occlient.Client, name string) error {
glog.V(4).Info("Deleting application %s", name)
labels := applabels.GetLabels(name, false)
// delete application from cluster
err := client.Delete(labels)
if err != nil {
return errors.Wrapf(err, "unable to delete application %s", name)
}
// delete from config
cfg, err := config.New()
if err != nil {
return errors.Wrapf(err, "unable to delete application %s", name)
}
project := project.GetCurrent(client)
err = cfg.DeleteApplication(name, project)
if err != nil {
return errors.Wrapf(err, "unable to delete application %s", name)
}
return nil
}
// GetCurrent returns currently active application.
// If no application is active this functions returns empty string
func GetCurrent(client *occlient.Client) (string, error) {
project := project.GetCurrent(client)
cfg, err := config.New()
if err != nil {
return "", errors.Wrap(err, "unable to get active application")
}
app := cfg.GetActiveApplication(project)
return app, nil
}
// GetCurrentOrGetCreateSetDefault returns currently active application.
// If no application is active, a defaultApplication is created and set as
// default as well.
// Use this carefully only in places where user expects the state to be altered
// Do not use for read operations like get, list; only for write operations like
// create
func GetCurrentOrGetCreateSetDefault(client *occlient.Client) (string, error) {
currentApp, err := GetCurrent(client)
if err != nil {
return "", errors.Wrap(err, "unable to get active application")
}
// if no Application is active use default
if currentApp == "" {
// get default application name
currentApp = getDefaultAppName()
// create if default application does not exist
exists, err := Exists(client, currentApp)
if err != nil {
return "", errors.Wrapf(err, "unable to check if app %v exists", currentApp)
}
if !exists {
if err := Create(client, currentApp); err != nil {
return "", errors.Wrapf(err, "unable to create app %v", currentApp)
}
}
// set default application as the current application
if err := SetCurrent(client, currentApp); err != nil {
return "", errors.Wrapf(err, "unable to set %v as the current application", currentApp)
}
}
return currentApp, nil
}
// SetCurrent set application as active
func SetCurrent(client *occlient.Client, name string) error {
glog.V(4).Infof("Setting application %s as current.\n", name)
project := project.GetCurrent(client)
cfg, err := config.New()
if err != nil {
return errors.Wrap(err, "unable to set current application")
}
exists, err := Exists(client, name)
if err != nil {
return errors.Wrap(err, "unable to set current application")
}
if !exists {
return fmt.Errorf("application %s doesn't exist", name)
}
// There might be a situation where application is not defined in local config
// but it is present in OpenShift cluster. This situation can happen for example if user deleted config file.
// In that case we need to add application back to the the config before we set it as active.
found := false
for _, cfgApp := range cfg.ActiveApplications {
if cfgApp.Project == project && cfgApp.Name == name {
found = true
break
}
}
if !found {
cfg.AddApplication(name, project)
}
err = cfg.SetActiveApplication(name, project)
if err != nil {
return errors.Wrap(err, "unable to set current application")
}
return nil
}
func Exists(client *occlient.Client, name string) (bool, error) {
apps, err := List(client)
if err != nil {
return false, errors.Wrap(err, "unable to list applications")
}
for _, app := range apps {
if app.Name == name {
return true, nil
}
}
return false, nil
}