Added seed code for caas-helm.
[ta/caas-helm.git] / src / chart-repo-handler / main.go
diff --git a/src/chart-repo-handler/main.go b/src/chart-repo-handler/main.go
new file mode 100644 (file)
index 0000000..5cf35b4
--- /dev/null
@@ -0,0 +1,159 @@
+// Copyright 2019 Nokia
+//
+// 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 main
+
+import (
+  "crypto/tls"
+  "log"
+  "net/http"
+  "pkg/api"
+  "pkg/config"
+  "pkg/repo"
+  "github.com/kelseyhightower/envconfig"
+  "github.com/ncw/swift"
+  "os"
+  "os/signal"
+  "syscall"
+  "strconv"
+  "time"
+  "errors"
+  "crypto/x509"
+  "io/ioutil"
+)
+
+var (
+  chartRepo *http.Server
+)
+
+const (
+  regenRetryCounter = 10
+)
+
+func main() {
+  var envConfig config.EnvConfig
+  err := envconfig.Process("chartrepohandler", &envConfig)
+  if err != nil {
+    log.Fatal(err.Error())
+    }
+
+  swiftCon := connectSwift(envConfig)
+  log.Println("Chart repo handler v0.9 started up.")
+  log.Printf("Config: %s\n", envConfig.ToString())
+  log.Println("Regenerating index for:", envConfig.IndexPath)
+  if err := regenerateIndexYaml(envConfig, &swiftCon); err != nil {
+    log.Println(err.Error())
+    os.Exit(-1)
+    }
+  startHttpServer(envConfig, &swiftCon)
+  signalChan := make(chan os.Signal, 1)
+  signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
+  for {
+    select {
+      case <-signalChan:
+        log.Println("Shutdown signal received, exiting...")
+        if (chartRepo != nil) {
+          chartRepo.Close()
+          }
+        os.Exit(0)
+    }
+  }
+}
+
+func connectSwift(envConfig config.EnvConfig) swift.Connection {
+  swiftCon := swift.Connection{
+    UserName:  envConfig.AuthUser,
+    ApiKey:    envConfig.AuthKey,
+    AuthUrl:   envConfig.AuthUrl,
+    }
+  if envConfig.TlsCaPath != "" {
+    log.Printf("INFO: TlsCaPath is presented: Trying to enforce TLS Authentication on swift backend using the server certs")
+    file, err := ioutil.ReadFile(envConfig.TlsCaPath)
+    if err != nil {
+      log.Fatal(err)
+      log.Printf("Wrong or missing value in paramteter: TlsCaPath")
+      os.Exit(-1)
+      }
+    certPool := x509.NewCertPool()
+    ok := certPool.AppendCertsFromPEM([]byte(file))
+    if !ok {
+      log.Fatal("Corrupt CACert file")
+      os.Exit(-1)
+      }
+    cert, err := tls.LoadX509KeyPair(envConfig.TlsCertPath, envConfig.TlsKeyPath)
+    if err != nil {
+      log.Fatal(err)
+      log.Printf("Wrong or missing value in paramteter: TlsCertPath or TlsKeyPath")
+      os.Exit(-1)
+      }
+    swiftCon.Transport = &http.Transport{
+      TLSClientConfig: &tls.Config{
+        RootCAs: certPool,
+        Certificates: []tls.Certificate{cert}, 
+        },
+      }
+    }
+  return swiftCon
+}
+
+func regenerateIndexYaml(envConfig config.EnvConfig, swiftConn *swift.Connection) error {
+  var err error
+  for i := 0; i <= regenRetryCounter; i++ {
+    err = repo.Index(swiftConn, envConfig.Container, envConfig.RepoUrl+":"+envConfig.ListenOnPort, envConfig.IndexPath, "/index.yaml")
+    if err != nil {
+      log.Println("INFO: Regenerating index.yaml in Swift try no.: " + strconv.Itoa(i) + " was unsuccessful at: " + swiftConn.AuthUrl +
+                  " with error:" + err.Error())
+      time.Sleep(10 * time.Second)
+      continue
+    } else {
+      return nil
+    }
+  }
+  return errors.New("ERROR: Swift is not responsive, giving-up regeneration!")
+}
+
+func startHttpServer(envConfig config.EnvConfig, swiftConn *swift.Connection) {
+  router := api.NewRouter(swiftConn, envConfig)
+  var tlsCfg *tls.Config
+  if envConfig.TlsCertPath != "" && envConfig.TlsKeyPath != "" {
+    log.Println("TLS used")
+    tlsCfg = &tls.Config{
+      MinVersion:               tls.VersionTLS12,
+      CurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
+      PreferServerCipherSuites: true,
+      CipherSuites: []uint16{
+        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+        tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+        tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
+        tls.TLS_RSA_WITH_AES_256_CBC_SHA,
+      },
+    }
+  } else {
+    tlsCfg = &tls.Config{}
+  }
+  chartRepo = &http.Server{
+    Addr:         envConfig.ListenOnIP + ":" + envConfig.ListenOnPort,
+    Handler:      router,
+    TLSConfig:    tlsCfg,
+    TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
+  }
+  go func() {
+    if chartRepo.TLSConfig != nil {
+      log.Fatal(chartRepo.ListenAndServeTLS(envConfig.TlsCertPath, envConfig.TlsKeyPath))
+    } else {
+      log.Fatal(chartRepo.ListenAndServe())
+    }
+  }()
+}
+