1 // Copyright 2019 Nokia
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
24 "github.com/kelseyhightower/envconfig"
25 "github.com/ncw/swift"
37 chartRepo *http.Server
41 regenRetryCounter = 10
45 var envConfig config.EnvConfig
46 err := envconfig.Process("chartrepohandler", &envConfig)
48 log.Fatal(err.Error())
51 swiftCon := connectSwift(envConfig)
52 log.Println("Chart repo handler v0.9 started up.")
53 log.Printf("Config: %s\n", envConfig.ToString())
54 log.Println("Regenerating index for:", envConfig.IndexPath)
55 if err := regenerateIndexYaml(envConfig, &swiftCon); err != nil {
56 log.Println(err.Error())
59 startHttpServer(envConfig, &swiftCon)
60 signalChan := make(chan os.Signal, 1)
61 signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
65 log.Println("Shutdown signal received, exiting...")
66 if (chartRepo != nil) {
74 func connectSwift(envConfig config.EnvConfig) swift.Connection {
75 swiftCon := swift.Connection{
76 UserName: envConfig.AuthUser,
77 ApiKey: envConfig.AuthKey,
78 AuthUrl: envConfig.AuthUrl,
80 if envConfig.TlsCaPath != "" {
81 log.Printf("INFO: TlsCaPath is presented: Trying to enforce TLS Authentication on swift backend using the server certs")
82 file, err := ioutil.ReadFile(envConfig.TlsCaPath)
85 log.Printf("Wrong or missing value in paramteter: TlsCaPath")
88 certPool := x509.NewCertPool()
89 ok := certPool.AppendCertsFromPEM([]byte(file))
91 log.Fatal("Corrupt CACert file")
94 cert, err := tls.LoadX509KeyPair(envConfig.TlsCertPath, envConfig.TlsKeyPath)
97 log.Printf("Wrong or missing value in paramteter: TlsCertPath or TlsKeyPath")
100 swiftCon.Transport = &http.Transport{
101 TLSClientConfig: &tls.Config{
103 Certificates: []tls.Certificate{cert},
110 func regenerateIndexYaml(envConfig config.EnvConfig, swiftConn *swift.Connection) error {
112 for i := 0; i <= regenRetryCounter; i++ {
113 err = repo.Index(swiftConn, envConfig.Container, envConfig.RepoUrl+":"+envConfig.ListenOnPort, envConfig.IndexPath, "/index.yaml")
115 log.Println("INFO: Regenerating index.yaml in Swift try no.: " + strconv.Itoa(i) + " was unsuccessful at: " + swiftConn.AuthUrl +
116 " with error:" + err.Error())
117 time.Sleep(10 * time.Second)
123 return errors.New("ERROR: Swift is not responsive, giving-up regeneration!")
126 func startHttpServer(envConfig config.EnvConfig, swiftConn *swift.Connection) {
127 router := api.NewRouter(swiftConn, envConfig)
128 var tlsCfg *tls.Config
129 if envConfig.TlsCertPath != "" && envConfig.TlsKeyPath != "" {
130 log.Println("TLS used")
131 tlsCfg = &tls.Config{
132 MinVersion: tls.VersionTLS12,
133 CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
134 PreferServerCipherSuites: true,
135 CipherSuites: []uint16{
136 tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
137 tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
138 tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
139 tls.TLS_RSA_WITH_AES_256_CBC_SHA,
143 chartRepo = &http.Server{
144 Addr: envConfig.ListenOnIP + ":" + envConfig.ListenOnPort,
147 TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
150 if chartRepo.TLSConfig != nil {
151 log.Fatal(chartRepo.ListenAndServeTLS(envConfig.TlsCertPath, envConfig.TlsKeyPath))
153 log.Fatal(chartRepo.ListenAndServe())