| // Copyright 2016 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // The following enables go generate to generate the doc.go file. |
| //go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help |
| |
| package main |
| |
| import ( |
| "fmt" |
| "io/ioutil" |
| "strings" |
| |
| "v.io/v23" |
| "v.io/v23/context" |
| "v.io/v23/security" |
| |
| "v.io/x/lib/cmdline" |
| "v.io/x/ref/lib/signals" |
| "v.io/x/ref/lib/v23cmd" |
| _ "v.io/x/ref/runtime/factories/roaming" |
| "v.io/x/ref/services/allocator" |
| "v.io/x/ref/services/cluster" |
| ) |
| |
| var ( |
| nameFlag string |
| serverNameFlag string |
| serverNameRootFlag string |
| deploymentTemplateFlag string |
| globalAdminsFlag string |
| maxInstancesFlag int |
| maxInstancesPerUserFlag int |
| diskSizeFlag string |
| gcloudBinFlag string |
| vkubeBinFlag string |
| vkubeCfgFlag string |
| clusterAgentFlag string |
| blessingSecretFlag string |
| monitoringKeyFileFlag string |
| |
| // HTTP flags. |
| assetsFlag string |
| httpAddrFlag string |
| externalURLFlag string |
| oauthCredsFileFlag string |
| secureCookiesFlag bool |
| dashboardGCMMetricFlag string |
| dashboardGCMProjectFlag string |
| staticAssetsPrefixFlag string |
| |
| cmdRoot = &cmdline.Command{ |
| Runner: v23cmd.RunnerFunc(runAllocator), |
| Name: "allocatord", |
| Short: "Runs the allocator service", |
| Long: "Runs the allocator service", |
| } |
| ) |
| |
| const ( |
| serverNameFlagName = "server-name" |
| serverNameRootFlagName = "server-name-root" |
| oauthCredsFileFlagName = "oauth-client-creds-file" |
| ) |
| |
| func main() { |
| cmdRoot.Flags.StringVar(&nameFlag, "name", "", "Name to publish for this service.") |
| cmdRoot.Flags.StringVar(&serverNameFlag, serverNameFlagName, "", "Name of the servers to allocate. This name is part of the published names in the Vanadium namespace and the names of the Deployments in Kubernetes.") |
| cmdRoot.Flags.StringVar(&serverNameRootFlag, serverNameRootFlagName, "", "Namespace root for allocated servers to use when publishing in the Vanadium namespace. If not set, the namespace root of the allocator server is used.") |
| cmdRoot.Flags.StringVar(&deploymentTemplateFlag, "deployment-template", "", "The template for the deployment of the servers to allocate.") |
| cmdRoot.Flags.StringVar(&globalAdminsFlag, "global-admins", "", "A comma-separated list of blessing patterns that have access to all the server instances.") |
| cmdRoot.Flags.IntVar(&maxInstancesFlag, "max-instances", 10, "The maximum total number of server instances to create.") |
| cmdRoot.Flags.IntVar(&maxInstancesPerUserFlag, "max-instances-per-user", 1, "The maximum number of server instances to create per user.") |
| cmdRoot.Flags.StringVar(&diskSizeFlag, "server-disk-size", "50GB", "The size of the persistent disk to allocate with the servers.") |
| cmdRoot.Flags.StringVar(&gcloudBinFlag, "gcloud", "gcloud", "The gcloud binary to use.") |
| cmdRoot.Flags.StringVar(&vkubeBinFlag, "vkube", "vkube", "The vkube binary to use.") |
| cmdRoot.Flags.StringVar(&vkubeCfgFlag, "vkube-cfg", "vkube.cfg", "The vkube.cfg to use.") |
| cmdRoot.Flags.StringVar(&clusterAgentFlag, "cluster-agent", "", "The address of the cluster-agent.") |
| cmdRoot.Flags.StringVar(&blessingSecretFlag, "blessings-secret-file", "", "If set, this file contains the secret to present to the cluster-agent to get the base blessings for the allocated servers.") |
| cmdRoot.Flags.StringVar(&assetsFlag, "assets", "", "If set, the directory containing assets (template definitions, css, javascript files etc.) to use in the web interface. If not set, compiled-in assets will be used instead.") |
| cmdRoot.Flags.StringVar(&httpAddrFlag, "http-addr", "", "Address on which the HTTP server listens on. If empty, no HTTP server is started.") |
| cmdRoot.Flags.StringVar(&externalURLFlag, "external-url", "", "Public URL for the HTTP server. Must be specified if --http-addr is specified.") |
| cmdRoot.Flags.StringVar(&monitoringKeyFileFlag, "monitoring-key-file", "", "The path to the service account's JSON credentials file.") |
| cmdRoot.Flags.StringVar(&oauthCredsFileFlag, oauthCredsFileFlagName, "", "JSON-encoded file containing Google Oauth2 client ID and secret (https://developers.google.com/identity/protocols/OAuth2#basicsteps), as well as the HMAC cookie signing key") |
| cmdRoot.Flags.BoolVar(&secureCookiesFlag, "secure-cookies", true, "Whether to use only secure cookies. Should be true unless running the server without TLS for testing.") |
| cmdRoot.Flags.StringVar(&dashboardGCMMetricFlag, "dashboard-gcm-metric", "", "The metric name used to get data from GCM to render dashboard charts.") |
| cmdRoot.Flags.StringVar(&dashboardGCMProjectFlag, "dashboard-gcm-project", "", "The project name used to get data from GCM to render dashboard charts.") |
| cmdRoot.Flags.StringVar(&staticAssetsPrefixFlag, "static-assets-prefix", "", "Host serving the web assets.") |
| cmdline.HideGlobalFlagsExcept() |
| cmdline.Main(cmdRoot) |
| } |
| |
| func runAllocator(ctx *context.T, env *cmdline.Env, args []string) error { |
| if len(serverNameFlag) > 30 { |
| // The names in Kubernetes have to be 63 characters or less. We |
| // use <server-name>-<md5> as name, where "-<md5>" is 33 chars. |
| return env.UsageErrorf("--%s value too long. Must be <= 30 characters", serverNameFlagName) |
| } |
| if nameRoot(ctx) == "" { |
| return env.UsageErrorf("--%s not specified, and no default namespace root found", serverNameRootFlagName) |
| } |
| |
| var ( |
| baseBlessings security.Blessings |
| baseBlessingNames []string |
| ) |
| if clusterAgentFlag == "" || blessingSecretFlag == "" { |
| fmt.Fprintln(env.Stderr, "WARNING: Using self-blessed blessings for allocated servers") |
| const selfName = "allocator" |
| var err error |
| if baseBlessings, err = v23.GetPrincipal(ctx).BlessSelf(selfName); err != nil { |
| return err |
| } |
| baseBlessingNames = []string{selfName} |
| } else { |
| secret, err := ioutil.ReadFile(blessingSecretFlag) |
| if err != nil { |
| return err |
| } |
| baseBlessings, err = cluster.ClusterAgentClient(clusterAgentFlag).SeekBlessings(ctx, strings.TrimSpace(string(secret))) |
| if err != nil { |
| return err |
| } |
| baseBlessingNames = security.BlessingNames(v23.GetPrincipal(ctx), baseBlessings) |
| } |
| |
| ctx, server, err := v23.WithNewServer( |
| ctx, |
| nameFlag, |
| allocator.AllocatorServer(&allocatorImpl{baseBlessings, baseBlessingNames}), |
| security.AllowEveryone(), |
| ) |
| if err != nil { |
| return err |
| } |
| ah, err := newAssetsHelper(assetsFlag) |
| if err != nil { |
| return err |
| } |
| ctx.Infof("Listening on: %v", server.Status().Endpoints) |
| if httpAddrFlag != "" { |
| if oauthCredsFileFlag == "" { |
| return env.UsageErrorf("--%s must be provided", oauthCredsFileFlagName) |
| } |
| oauthCreds, err := clientCredsFromFile(oauthCredsFileFlag) |
| if err != nil { |
| return err |
| } |
| cleanup := startHTTP(ctx, httpArgs{ |
| addr: httpAddrFlag, |
| externalURL: externalURLFlag, |
| dashboardGCMMetric: dashboardGCMMetricFlag, |
| dashboardGCMProject: dashboardGCMProjectFlag, |
| monitoringKeyFile: monitoringKeyFileFlag, |
| oauthCreds: oauthCreds, |
| serverName: serverNameFlag, |
| secureCookies: secureCookiesFlag, |
| baseBlessings: baseBlessings, |
| baseBlessingNames: baseBlessingNames, |
| staticAssetsPrefix: staticAssetsPrefixFlag, |
| assets: ah, |
| }) |
| defer cleanup() |
| } |
| <-signals.ShutdownOnSignals(ctx) |
| return nil |
| } |