forked from goharbor/harbor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
controller.go
153 lines (127 loc) · 3.97 KB
/
controller.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
package chartserver
import (
"errors"
"fmt"
"net/url"
"os"
"strings"
hlog "github.com/vmware/harbor/src/common/utils/log"
)
const (
userName = "chart_controller"
passwordKey = "UI_SECRET"
)
//Credential keeps the username and password for the basic auth
type Credential struct {
Username string
Password string
}
//Controller is used to handle flows of related requests based on the corresponding handlers
//A reverse proxy will be created and managed to proxy the related traffics between API and
//backend chart server
type Controller struct {
//The access endpoint of the backend chart repository server
backendServerAddr *url.URL
//To cover the server info and status requests
baseHandler *BaseHandler
//To cover the chart repository requests
repositoryHandler *RepositoryHandler
//To cover all the manipulation requests
manipulationHandler *ManipulationHandler
//To cover the other utility requests
utilityHandler *UtilityHandler
}
//NewController is constructor of the chartserver.Controller
func NewController(backendServer *url.URL) (*Controller, error) {
if backendServer == nil {
return nil, errors.New("failed to create chartserver.Controller: backend sever address is required")
}
//Try to create credential
cred := &Credential{
Username: userName,
Password: os.Getenv(passwordKey),
}
//Use customized reverse proxy
proxy := NewProxyEngine(backendServer, cred)
//Create http client with customized timeouts
client := NewChartClient(cred)
//Initialize chart operator for use
operator := &ChartOperator{}
//Creat cache
cacheCfg, err := getCacheConfig()
if err != nil {
//just log the error
//will not break the whole flow if failed to create cache
hlog.Errorf("failed to get cache configuration with error: %s", err)
}
cache := NewChartCache(cacheCfg)
if !cache.IsEnabled() {
hlog.Info("No cache is enabled for chart caching")
}
return &Controller{
backendServerAddr: backendServer,
baseHandler: &BaseHandler{proxy},
repositoryHandler: &RepositoryHandler{
trafficProxy: proxy,
apiClient: client,
backendServerAddress: backendServer,
},
manipulationHandler: &ManipulationHandler{
trafficProxy: proxy,
chartOperator: operator,
apiClient: client,
backendServerAddress: backendServer,
chartCache: cache,
},
utilityHandler: &UtilityHandler{
apiClient: client,
backendServerAddress: backendServer,
chartOperator: operator,
},
}, nil
}
//GetBaseHandler returns the reference of BaseHandler
func (c *Controller) GetBaseHandler() *BaseHandler {
return c.baseHandler
}
//GetRepositoryHandler returns the reference of RepositoryHandler
func (c *Controller) GetRepositoryHandler() *RepositoryHandler {
return c.repositoryHandler
}
//GetManipulationHandler returns the reference of ManipulationHandler
func (c *Controller) GetManipulationHandler() *ManipulationHandler {
return c.manipulationHandler
}
//GetUtilityHandler returns the reference of UtilityHandler
func (c *Controller) GetUtilityHandler() *UtilityHandler {
return c.utilityHandler
}
//What's the cache driver if it is set
func parseCacheDriver() (string, bool) {
driver, ok := os.LookupEnv(cacheDriverENVKey)
return strings.ToLower(driver), ok
}
//Get and parse the configuration for the chart cache
func getCacheConfig() (*ChartCacheConfig, error) {
driver, isSet := parseCacheDriver()
if !isSet {
return nil, nil
}
if driver != cacheDriverMem && driver != cacheDriverRedis {
return nil, fmt.Errorf("cache driver '%s' is not supported, only support 'memory' and 'redis'", driver)
}
if driver == cacheDriverMem {
return &ChartCacheConfig{
DriverType: driver,
}, nil
}
redisConfigV := os.Getenv(redisENVKey)
redisCfg, err := parseRedisConfig(redisConfigV)
if err != nil {
return nil, fmt.Errorf("failed to parse redis configurations from '%s' with error: %s", redisCfg, err)
}
return &ChartCacheConfig{
DriverType: driver,
Config: redisCfg,
}, nil
}