nixery/server/config/config.go
Vincent Ambo 672673db3b refactor(server): Load GCS signing key from service account key
The JSON file generated for service account keys already contains the
required information for signing URLs in GCS, thus the environment
variables for toggling signing behaviour have been removed.

Signing is now enabled automatically in the presence of service
account credentials (i.e. `GOOGLE_APPLICATION_CREDENTIALS`).
2019-10-27 13:58:04 +01:00

98 lines
3.0 KiB
Go

// Copyright 2019 Google LLC
//
// 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
//
// https://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 config implements structures to store Nixery's configuration at
// runtime as well as the logic for instantiating this configuration from the
// environment.
package config
import (
"io/ioutil"
"os"
"cloud.google.com/go/storage"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2/google"
)
// Configure GCS URL signing in the presence of a service account key
// (toggled if the user has set GOOGLE_APPLICATION_CREDENTIALS).
func signingOptsFromEnv() *storage.SignedURLOptions {
path := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
if path == "" {
return nil
}
key, err := ioutil.ReadFile(path)
if err != nil {
log.WithError(err).WithField("file", path).Fatal("failed to read service account key")
}
conf, err := google.JWTConfigFromJSON(key)
if err != nil {
log.WithError(err).WithField("file", path).Fatal("failed to parse service account key")
}
log.WithField("account", conf.Email).Info("GCS URL signing enabled")
return &storage.SignedURLOptions{
Scheme: storage.SigningSchemeV4,
GoogleAccessID: conf.Email,
PrivateKey: conf.PrivateKey,
Method: "GET",
}
}
func getConfig(key, desc, def string) string {
value := os.Getenv(key)
if value == "" && def == "" {
log.WithFields(log.Fields{
"option": key,
"description": desc,
}).Fatal("missing required configuration envvar")
} else if value == "" {
return def
}
return value
}
// Config holds the Nixery configuration options.
type Config struct {
Bucket string // GCS bucket to cache & serve layers
Signing *storage.SignedURLOptions // Signing options to use for GCS URLs
Port string // Port on which to launch HTTP server
Pkgs PkgSource // Source for Nix package set
Timeout string // Timeout for a single Nix builder (seconds)
WebDir string // Directory with static web assets
PopUrl string // URL to the Nix package popularity count
}
func FromEnv() (Config, error) {
pkgs, err := pkgSourceFromEnv()
if err != nil {
return Config{}, err
}
return Config{
Bucket: getConfig("BUCKET", "GCS bucket for layer storage", ""),
Port: getConfig("PORT", "HTTP port", ""),
Pkgs: pkgs,
Signing: signingOptsFromEnv(),
Timeout: getConfig("NIX_TIMEOUT", "Nix builder timeout", "60"),
WebDir: getConfig("WEB_DIR", "Static web file dir", ""),
PopUrl: os.Getenv("NIX_POPULARITY_URL"),
}, nil
}