feat: make flags in one place (#4452)

This commit is contained in:
Garrett Delfosse
2022-10-11 11:16:19 -04:00
committed by GitHub
parent b1a095e486
commit a70278e0e1
10 changed files with 246 additions and 201 deletions

View File

@ -2,6 +2,7 @@ package deployment
import ( import (
"flag" "flag"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
@ -11,6 +12,7 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/coder/coder/cli/cliflag" "github.com/coder/coder/cli/cliflag"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/codersdk" "github.com/coder/coder/codersdk"
) )
@ -18,21 +20,21 @@ const (
secretValue = "********" secretValue = "********"
) )
func Flags() codersdk.DeploymentFlags { func Flags() *codersdk.DeploymentFlags {
return codersdk.DeploymentFlags{ return &codersdk.DeploymentFlags{
AccessURL: codersdk.StringFlag{ AccessURL: &codersdk.StringFlag{
Name: "Access URL", Name: "Access URL",
Flag: "access-url", Flag: "access-url",
EnvVar: "CODER_ACCESS_URL", EnvVar: "CODER_ACCESS_URL",
Description: "External URL to access your deployment. This must be accessible by all provisioned workspaces.", Description: "External URL to access your deployment. This must be accessible by all provisioned workspaces.",
}, },
WildcardAccessURL: codersdk.StringFlag{ WildcardAccessURL: &codersdk.StringFlag{
Name: "Wildcard Address URL", Name: "Wildcard Address URL",
Flag: "wildcard-access-url", Flag: "wildcard-access-url",
EnvVar: "CODER_WILDCARD_ACCESS_URL", EnvVar: "CODER_WILDCARD_ACCESS_URL",
Description: `Specifies the wildcard hostname to use for workspace applications in the form "*.example.com".`, Description: `Specifies the wildcard hostname to use for workspace applications in the form "*.example.com".`,
}, },
Address: codersdk.StringFlag{ Address: &codersdk.StringFlag{
Name: "Bind Address", Name: "Bind Address",
Flag: "address", Flag: "address",
EnvVar: "CODER_ADDRESS", EnvVar: "CODER_ADDRESS",
@ -40,197 +42,201 @@ func Flags() codersdk.DeploymentFlags {
Description: "Bind address of the server.", Description: "Bind address of the server.",
Default: "127.0.0.1:3000", Default: "127.0.0.1:3000",
}, },
AutobuildPollInterval: codersdk.DurationFlag{ AutobuildPollInterval: &codersdk.DurationFlag{
Name: "Autobuild Poll Interval", Name: "Autobuild Poll Interval",
Flag: "autobuild-poll-interval", Flag: "autobuild-poll-interval",
EnvVar: "CODER_AUTOBUILD_POLL_INTERVAL", EnvVar: "CODER_AUTOBUILD_POLL_INTERVAL",
Description: "Interval to poll for scheduled workspace builds.", Description: "Interval to poll for scheduled workspace builds.",
Hidden: true,
Default: time.Minute, Default: time.Minute,
}, },
DerpServerEnable: codersdk.BoolFlag{ DerpServerEnable: &codersdk.BoolFlag{
Name: "DERP Server Enabled", Name: "DERP Server Enabled",
Flag: "derp-server-enable", Flag: "derp-server-enable",
EnvVar: "CODER_DERP_SERVER_ENABLE", EnvVar: "CODER_DERP_SERVER_ENABLE",
Description: "Whether to enable or disable the embedded DERP relay server.", Description: "Whether to enable or disable the embedded DERP relay server.",
Default: true, Default: true,
}, },
DerpServerRegionID: codersdk.IntFlag{ DerpServerRegionID: &codersdk.IntFlag{
Name: "DERP Server Region ID", Name: "DERP Server Region ID",
Flag: "derp-server-region-id", Flag: "derp-server-region-id",
EnvVar: "CODER_DERP_SERVER_REGION_ID", EnvVar: "CODER_DERP_SERVER_REGION_ID",
Description: "Region ID to use for the embedded DERP server.", Description: "Region ID to use for the embedded DERP server.",
Default: 999, Default: 999,
}, },
DerpServerRegionCode: codersdk.StringFlag{ DerpServerRegionCode: &codersdk.StringFlag{
Name: "DERP Server Region Code", Name: "DERP Server Region Code",
Flag: "derp-server-region-code", Flag: "derp-server-region-code",
EnvVar: "CODER_DERP_SERVER_REGION_CODE", EnvVar: "CODER_DERP_SERVER_REGION_CODE",
Description: "Region code to use for the embedded DERP server.", Description: "Region code to use for the embedded DERP server.",
Default: "coder", Default: "coder",
}, },
DerpServerRegionName: codersdk.StringFlag{ DerpServerRegionName: &codersdk.StringFlag{
Name: "DERP Server Region Name", Name: "DERP Server Region Name",
Flag: "derp-server-region-name", Flag: "derp-server-region-name",
EnvVar: "CODER_DERP_SERVER_REGION_NAME", EnvVar: "CODER_DERP_SERVER_REGION_NAME",
Description: "Region name that for the embedded DERP server.", Description: "Region name that for the embedded DERP server.",
Default: "Coder Embedded Relay", Default: "Coder Embedded Relay",
}, },
DerpServerSTUNAddresses: codersdk.StringArrayFlag{ DerpServerSTUNAddresses: &codersdk.StringArrayFlag{
Name: "DERP Server STUN Addresses", Name: "DERP Server STUN Addresses",
Flag: "derp-server-stun-addresses", Flag: "derp-server-stun-addresses",
EnvVar: "CODER_DERP_SERVER_STUN_ADDRESSES", EnvVar: "CODER_DERP_SERVER_STUN_ADDRESSES",
Description: "Addresses for STUN servers to establish P2P connections. Set empty to disable P2P connections.", Description: "Addresses for STUN servers to establish P2P connections. Set empty to disable P2P connections.",
Default: []string{"stun.l.google.com:19302"}, Default: []string{"stun.l.google.com:19302"},
}, },
DerpConfigURL: codersdk.StringFlag{ DerpConfigURL: &codersdk.StringFlag{
Name: "DERP Config URL", Name: "DERP Config URL",
Flag: "derp-config-url", Flag: "derp-config-url",
EnvVar: "CODER_DERP_CONFIG_URL", EnvVar: "CODER_DERP_CONFIG_URL",
Description: "URL to fetch a DERP mapping on startup. See: https://tailscale.com/kb/1118/custom-derp-servers/", Description: "URL to fetch a DERP mapping on startup. See: https://tailscale.com/kb/1118/custom-derp-servers/",
}, },
DerpConfigPath: codersdk.StringFlag{ DerpConfigPath: &codersdk.StringFlag{
Name: "DERP Config Path", Name: "DERP Config Path",
Flag: "derp-config-path", Flag: "derp-config-path",
EnvVar: "CODER_DERP_CONFIG_PATH", EnvVar: "CODER_DERP_CONFIG_PATH",
Description: "Path to read a DERP mapping from. See: https://tailscale.com/kb/1118/custom-derp-servers/", Description: "Path to read a DERP mapping from. See: https://tailscale.com/kb/1118/custom-derp-servers/",
}, },
PromEnabled: codersdk.BoolFlag{ PromEnabled: &codersdk.BoolFlag{
Name: "Prometheus Enabled", Name: "Prometheus Enabled",
Flag: "prometheus-enable", Flag: "prometheus-enable",
EnvVar: "CODER_PROMETHEUS_ENABLE", EnvVar: "CODER_PROMETHEUS_ENABLE",
Description: "Serve prometheus metrics on the address defined by `prometheus-address`.", Description: "Serve prometheus metrics on the address defined by `prometheus-address`.",
}, },
PromAddress: codersdk.StringFlag{ PromAddress: &codersdk.StringFlag{
Name: "Prometheus Address", Name: "Prometheus Address",
Flag: "prometheus-address", Flag: "prometheus-address",
EnvVar: "CODER_PROMETHEUS_ADDRESS", EnvVar: "CODER_PROMETHEUS_ADDRESS",
Description: "The bind address to serve prometheus metrics.", Description: "The bind address to serve prometheus metrics.",
Default: "127.0.0.1:2112", Default: "127.0.0.1:2112",
}, },
PprofEnabled: codersdk.BoolFlag{ PprofEnabled: &codersdk.BoolFlag{
Name: "pprof Enabled", Name: "pprof Enabled",
Flag: "pprof-enable", Flag: "pprof-enable",
EnvVar: "CODER_PPROF_ENABLE", EnvVar: "CODER_PPROF_ENABLE",
Description: "Serve pprof metrics on the address defined by `pprof-address`.", Description: "Serve pprof metrics on the address defined by `pprof-address`.",
}, },
PprofAddress: codersdk.StringFlag{ PprofAddress: &codersdk.StringFlag{
Name: "pprof Address", Name: "pprof Address",
Flag: "pprof-address", Flag: "pprof-address",
EnvVar: "CODER_PPROF_ADDRESS", EnvVar: "CODER_PPROF_ADDRESS",
Description: "The bind address to serve pprof.", Description: "The bind address to serve pprof.",
Default: "127.0.0.1:6060", Default: "127.0.0.1:6060",
}, },
CacheDir: codersdk.StringFlag{ CacheDir: &codersdk.StringFlag{
Name: "Cache Directory", Name: "Cache Directory",
Flag: "cache-dir", Flag: "cache-dir",
EnvVar: "CODER_CACHE_DIRECTORY", EnvVar: "CODER_CACHE_DIRECTORY",
Description: "The directory to cache temporary files. If unspecified and $CACHE_DIRECTORY is set, it will be used for compatibility with systemd.", Description: "The directory to cache temporary files. If unspecified and $CACHE_DIRECTORY is set, it will be used for compatibility with systemd.",
Default: defaultCacheDir(), Default: defaultCacheDir(),
}, },
InMemoryDatabase: codersdk.BoolFlag{ InMemoryDatabase: &codersdk.BoolFlag{
Name: "In-Memory Database", Name: "In-Memory Database",
Flag: "in-memory", Flag: "in-memory",
EnvVar: "CODER_INMEMORY", EnvVar: "CODER_INMEMORY",
Description: "Controls whether data will be stored in an in-memory database.", Description: "Controls whether data will be stored in an in-memory database.",
Hidden: true,
}, },
ProvisionerDaemonCount: codersdk.IntFlag{ ProvisionerDaemonCount: &codersdk.IntFlag{
Name: "Provisioner Daemons", Name: "Provisioner Daemons",
Flag: "provisioner-daemons", Flag: "provisioner-daemons",
EnvVar: "CODER_PROVISIONER_DAEMONS", EnvVar: "CODER_PROVISIONER_DAEMONS",
Description: "Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.", Description: "Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.",
Default: 3, Default: 3,
}, },
PostgresURL: codersdk.StringFlag{ PostgresURL: &codersdk.StringFlag{
Name: "Postgres URL", Name: "Postgres URL",
Flag: "postgres-url", Flag: "postgres-url",
EnvVar: "CODER_PG_CONNECTION_URL", EnvVar: "CODER_PG_CONNECTION_URL",
Description: "URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded from Maven (https://repo1.maven.org/maven2) and store all data in the config root. Access the built-in database with \"coder server postgres-builtin-url\"", Description: "URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded from Maven (https://repo1.maven.org/maven2) and store all data in the config root. Access the built-in database with \"coder server postgres-builtin-url\"",
Secret: true, Secret: true,
}, },
OAuth2GithubClientID: codersdk.StringFlag{ OAuth2GithubClientID: &codersdk.StringFlag{
Name: "Oauth2 Github Client ID", Name: "Oauth2 Github Client ID",
Flag: "oauth2-github-client-id", Flag: "oauth2-github-client-id",
EnvVar: "CODER_OAUTH2_GITHUB_CLIENT_ID", EnvVar: "CODER_OAUTH2_GITHUB_CLIENT_ID",
Description: "Client ID for Login with GitHub.", Description: "Client ID for Login with GitHub.",
}, },
OAuth2GithubClientSecret: codersdk.StringFlag{ OAuth2GithubClientSecret: &codersdk.StringFlag{
Name: "Oauth2 Github Client Secret", Name: "Oauth2 Github Client Secret",
Flag: "oauth2-github-client-secret", Flag: "oauth2-github-client-secret",
EnvVar: "CODER_OAUTH2_GITHUB_CLIENT_SECRET", EnvVar: "CODER_OAUTH2_GITHUB_CLIENT_SECRET",
Description: "Client secret for Login with GitHub.", Description: "Client secret for Login with GitHub.",
Secret: true, Secret: true,
}, },
OAuth2GithubAllowedOrganizations: codersdk.StringArrayFlag{ OAuth2GithubAllowedOrganizations: &codersdk.StringArrayFlag{
Name: "Oauth2 Github Allowed Organizations", Name: "Oauth2 Github Allowed Organizations",
Flag: "oauth2-github-allowed-orgs", Flag: "oauth2-github-allowed-orgs",
EnvVar: "CODER_OAUTH2_GITHUB_ALLOWED_ORGS", EnvVar: "CODER_OAUTH2_GITHUB_ALLOWED_ORGS",
Description: "Organizations the user must be a member of to Login with GitHub.", Description: "Organizations the user must be a member of to Login with GitHub.",
Default: []string{},
}, },
OAuth2GithubAllowedTeams: codersdk.StringArrayFlag{ OAuth2GithubAllowedTeams: &codersdk.StringArrayFlag{
Name: "Oauth2 Github Allowed Teams", Name: "Oauth2 Github Allowed Teams",
Flag: "oauth2-github-allowed-teams", Flag: "oauth2-github-allowed-teams",
EnvVar: "CODER_OAUTH2_GITHUB_ALLOWED_TEAMS", EnvVar: "CODER_OAUTH2_GITHUB_ALLOWED_TEAMS",
Description: "Teams inside organizations the user must be a member of to Login with GitHub. Structured as: <organization-name>/<team-slug>.", Description: "Teams inside organizations the user must be a member of to Login with GitHub. Structured as: <organization-name>/<team-slug>.",
Default: []string{},
}, },
OAuth2GithubAllowSignups: codersdk.BoolFlag{ OAuth2GithubAllowSignups: &codersdk.BoolFlag{
Name: "Oauth2 Github Allow Signups", Name: "Oauth2 Github Allow Signups",
Flag: "oauth2-github-allow-signups", Flag: "oauth2-github-allow-signups",
EnvVar: "CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS", EnvVar: "CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS",
Description: "Whether new users can sign up with GitHub.", Description: "Whether new users can sign up with GitHub.",
}, },
OAuth2GithubEnterpriseBaseURL: codersdk.StringFlag{ OAuth2GithubEnterpriseBaseURL: &codersdk.StringFlag{
Name: "Oauth2 Github Enterprise Base URL", Name: "Oauth2 Github Enterprise Base URL",
Flag: "oauth2-github-enterprise-base-url", Flag: "oauth2-github-enterprise-base-url",
EnvVar: "CODER_OAUTH2_GITHUB_ENTERPRISE_BASE_URL", EnvVar: "CODER_OAUTH2_GITHUB_ENTERPRISE_BASE_URL",
Description: "Base URL of a GitHub Enterprise deployment to use for Login with GitHub.", Description: "Base URL of a GitHub Enterprise deployment to use for Login with GitHub.",
}, },
OIDCAllowSignups: codersdk.BoolFlag{ OIDCAllowSignups: &codersdk.BoolFlag{
Name: "OIDC Allow Signups", Name: "OIDC Allow Signups",
Flag: "oidc-allow-signups", Flag: "oidc-allow-signups",
EnvVar: "CODER_OIDC_ALLOW_SIGNUPS", EnvVar: "CODER_OIDC_ALLOW_SIGNUPS",
Description: "Whether new users can sign up with OIDC.", Description: "Whether new users can sign up with OIDC.",
Default: true, Default: true,
}, },
OIDCClientID: codersdk.StringFlag{ OIDCClientID: &codersdk.StringFlag{
Name: "OIDC Client ID", Name: "OIDC Client ID",
Flag: "oidc-client-id", Flag: "oidc-client-id",
EnvVar: "CODER_OIDC_CLIENT_ID", EnvVar: "CODER_OIDC_CLIENT_ID",
Description: "Client ID to use for Login with OIDC.", Description: "Client ID to use for Login with OIDC.",
}, },
OIDCClientSecret: codersdk.StringFlag{ OIDCClientSecret: &codersdk.StringFlag{
Name: "OIDC Client Secret", Name: "OIDC Client Secret",
Flag: "oidc-client-secret", Flag: "oidc-client-secret",
EnvVar: "CODER_OIDC_CLIENT_SECRET", EnvVar: "CODER_OIDC_CLIENT_SECRET",
Description: "Client secret to use for Login with OIDC.", Description: "Client secret to use for Login with OIDC.",
Secret: true, Secret: true,
}, },
OIDCEmailDomain: codersdk.StringFlag{ OIDCEmailDomain: &codersdk.StringFlag{
Name: "OIDC Email Domain", Name: "OIDC Email Domain",
Flag: "oidc-email-domain", Flag: "oidc-email-domain",
EnvVar: "CODER_OIDC_EMAIL_DOMAIN", EnvVar: "CODER_OIDC_EMAIL_DOMAIN",
Description: "Email domain that clients logging in with OIDC must match.", Description: "Email domain that clients logging in with OIDC must match.",
}, },
OIDCIssuerURL: codersdk.StringFlag{ OIDCIssuerURL: &codersdk.StringFlag{
Name: "OIDC Issuer URL", Name: "OIDC Issuer URL",
Flag: "oidc-issuer-url", Flag: "oidc-issuer-url",
EnvVar: "CODER_OIDC_ISSUER_URL", EnvVar: "CODER_OIDC_ISSUER_URL",
Description: "Issuer URL to use for Login with OIDC.", Description: "Issuer URL to use for Login with OIDC.",
}, },
OIDCScopes: codersdk.StringArrayFlag{ OIDCScopes: &codersdk.StringArrayFlag{
Name: "OIDC Scopes", Name: "OIDC Scopes",
Flag: "oidc-scopes", Flag: "oidc-scopes",
EnvVar: "CODER_OIDC_SCOPES", EnvVar: "CODER_OIDC_SCOPES",
Description: "Scopes to grant when authenticating with OIDC.", Description: "Scopes to grant when authenticating with OIDC.",
Default: []string{oidc.ScopeOpenID, "profile", "email"}, Default: []string{oidc.ScopeOpenID, "profile", "email"},
}, },
TelemetryEnable: codersdk.BoolFlag{ TelemetryEnable: &codersdk.BoolFlag{
Name: "Telemetry Enabled", Name: "Telemetry Enabled",
Flag: "telemetry", Flag: "telemetry",
EnvVar: "CODER_TELEMETRY", EnvVar: "CODER_TELEMETRY",
Description: "Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product.", Description: "Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product.",
Default: flag.Lookup("test.v") == nil, Default: flag.Lookup("test.v") == nil,
}, },
TelemetryTraceEnable: codersdk.BoolFlag{ TelemetryTraceEnable: &codersdk.BoolFlag{
Name: "Trace Telemetry Enabled", Name: "Trace Telemetry Enabled",
Flag: "telemetry-trace", Flag: "telemetry-trace",
EnvVar: "CODER_TELEMETRY_TRACE", EnvVar: "CODER_TELEMETRY_TRACE",
@ -238,20 +244,21 @@ func Flags() codersdk.DeploymentFlags {
Description: "Whether Opentelemetry traces are sent to Coder. Coder collects anonymized application tracing to help improve our product. Disabling telemetry also disables this option.", Description: "Whether Opentelemetry traces are sent to Coder. Coder collects anonymized application tracing to help improve our product. Disabling telemetry also disables this option.",
Default: flag.Lookup("test.v") == nil, Default: flag.Lookup("test.v") == nil,
}, },
TelemetryURL: codersdk.StringFlag{ TelemetryURL: &codersdk.StringFlag{
Name: "Telemetry URL", Name: "Telemetry URL",
Flag: "telemetry-url", Flag: "telemetry-url",
EnvVar: "CODER_TELEMETRY_URL", EnvVar: "CODER_TELEMETRY_URL",
Description: "URL to send telemetry.", Description: "URL to send telemetry.",
Hidden: true,
Default: "https://telemetry.coder.com", Default: "https://telemetry.coder.com",
}, },
TLSEnable: codersdk.BoolFlag{ TLSEnable: &codersdk.BoolFlag{
Name: "TLS Enabled", Name: "TLS Enabled",
Flag: "tls-enable", Flag: "tls-enable",
EnvVar: "CODER_TLS_ENABLE", EnvVar: "CODER_TLS_ENABLE",
Description: "Whether TLS will be enabled.", Description: "Whether TLS will be enabled.",
}, },
TLSCertFiles: codersdk.StringArrayFlag{ TLSCertFiles: &codersdk.StringArrayFlag{
Name: "TLS Cert Files", Name: "TLS Cert Files",
Flag: "tls-cert-file", Flag: "tls-cert-file",
EnvVar: "CODER_TLS_CERT_FILE", EnvVar: "CODER_TLS_CERT_FILE",
@ -260,13 +267,13 @@ func Flags() codersdk.DeploymentFlags {
"and the CA certificate together. The primary certificate should appear first in the combined file.", "and the CA certificate together. The primary certificate should appear first in the combined file.",
Default: []string{}, Default: []string{},
}, },
TLSClientCAFile: codersdk.StringFlag{ TLSClientCAFile: &codersdk.StringFlag{
Name: "TLS Client CA File", Name: "TLS Client CA File",
Flag: "tls-client-ca-file", Flag: "tls-client-ca-file",
EnvVar: "CODER_TLS_CLIENT_CA_FILE", EnvVar: "CODER_TLS_CLIENT_CA_FILE",
Description: "PEM-encoded Certificate Authority file used for checking the authenticity of client", Description: "PEM-encoded Certificate Authority file used for checking the authenticity of client",
}, },
TLSClientAuth: codersdk.StringFlag{ TLSClientAuth: &codersdk.StringFlag{
Name: "TLS Client Auth", Name: "TLS Client Auth",
Flag: "tls-client-auth", Flag: "tls-client-auth",
EnvVar: "CODER_TLS_CLIENT_AUTH", EnvVar: "CODER_TLS_CLIENT_AUTH",
@ -274,33 +281,33 @@ func Flags() codersdk.DeploymentFlags {
`Accepted values are "none", "request", "require-any", "verify-if-given", or "require-and-verify"`, `Accepted values are "none", "request", "require-any", "verify-if-given", or "require-and-verify"`,
Default: "request", Default: "request",
}, },
TLSKeyFiles: codersdk.StringArrayFlag{ TLSKeyFiles: &codersdk.StringArrayFlag{
Name: "TLS Key Files", Name: "TLS Key Files",
Flag: "tls-key-file", Flag: "tls-key-file",
EnvVar: "CODER_TLS_KEY_FILE", EnvVar: "CODER_TLS_KEY_FILE",
Description: "Paths to the private keys for each of the certificates. It requires a PEM-encoded file", Description: "Paths to the private keys for each of the certificates. It requires a PEM-encoded file",
Default: []string{}, Default: []string{},
}, },
TLSMinVersion: codersdk.StringFlag{ TLSMinVersion: &codersdk.StringFlag{
Name: "TLS Min Version", Name: "TLS Min Version",
Flag: "tls-min-version", Flag: "tls-min-version",
EnvVar: "CODER_TLS_MIN_VERSION", EnvVar: "CODER_TLS_MIN_VERSION",
Description: `Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13"`, Description: `Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13"`,
Default: "tls12", Default: "tls12",
}, },
TraceEnable: codersdk.BoolFlag{ TraceEnable: &codersdk.BoolFlag{
Name: "Trace Enabled", Name: "Trace Enabled",
Flag: "trace", Flag: "trace",
EnvVar: "CODER_TRACE", EnvVar: "CODER_TRACE",
Description: "Whether application tracing data is collected.", Description: "Whether application tracing data is collected.",
}, },
SecureAuthCookie: codersdk.BoolFlag{ SecureAuthCookie: &codersdk.BoolFlag{
Name: "Secure Auth Cookie", Name: "Secure Auth Cookie",
Flag: "secure-auth-cookie", Flag: "secure-auth-cookie",
EnvVar: "CODER_SECURE_AUTH_COOKIE", EnvVar: "CODER_SECURE_AUTH_COOKIE",
Description: "Controls if the 'Secure' property is set on browser session cookies", Description: "Controls if the 'Secure' property is set on browser session cookies",
}, },
SSHKeygenAlgorithm: codersdk.StringFlag{ SSHKeygenAlgorithm: &codersdk.StringFlag{
Name: "SSH Keygen Algorithm", Name: "SSH Keygen Algorithm",
Flag: "ssh-keygen-algorithm", Flag: "ssh-keygen-algorithm",
EnvVar: "CODER_SSH_KEYGEN_ALGORITHM", EnvVar: "CODER_SSH_KEYGEN_ALGORITHM",
@ -308,35 +315,38 @@ func Flags() codersdk.DeploymentFlags {
`Accepted values are "ed25519", "ecdsa", or "rsa4096"`, `Accepted values are "ed25519", "ecdsa", or "rsa4096"`,
Default: "ed25519", Default: "ed25519",
}, },
AutoImportTemplates: codersdk.StringArrayFlag{ AutoImportTemplates: &codersdk.StringArrayFlag{
Name: "Auto Import Templates", Name: "Auto Import Templates",
Flag: "auto-import-template", Flag: "auto-import-template",
EnvVar: "CODER_TEMPLATE_AUTOIMPORT", EnvVar: "CODER_TEMPLATE_AUTOIMPORT",
Description: "Templates to auto-import. Available auto-importable templates are: kubernetes", Description: "Templates to auto-import. Available auto-importable templates are: kubernetes",
Hidden: true,
Default: []string{}, Default: []string{},
}, },
MetricsCacheRefreshInterval: codersdk.DurationFlag{ MetricsCacheRefreshInterval: &codersdk.DurationFlag{
Name: "Metrics Cache Refresh Interval", Name: "Metrics Cache Refresh Interval",
Flag: "metrics-cache-refresh-interval", Flag: "metrics-cache-refresh-interval",
EnvVar: "CODER_METRICS_CACHE_REFRESH_INTERVAL", EnvVar: "CODER_METRICS_CACHE_REFRESH_INTERVAL",
Description: "How frequently metrics are refreshed", Description: "How frequently metrics are refreshed",
Hidden: true,
Default: time.Hour, Default: time.Hour,
}, },
AgentStatRefreshInterval: codersdk.DurationFlag{ AgentStatRefreshInterval: &codersdk.DurationFlag{
Name: "Agent Stats Refresh Interval", Name: "Agent Stats Refresh Interval",
Flag: "agent-stats-refresh-interval", Flag: "agent-stats-refresh-interval",
EnvVar: "CODER_AGENT_STATS_REFRESH_INTERVAL", EnvVar: "CODER_AGENT_STATS_REFRESH_INTERVAL",
Description: "How frequently agent stats are recorded", Description: "How frequently agent stats are recorded",
Hidden: true,
Default: 10 * time.Minute, Default: 10 * time.Minute,
}, },
Verbose: codersdk.BoolFlag{ Verbose: &codersdk.BoolFlag{
Name: "Verbose Logging", Name: "Verbose Logging",
Flag: "verbose", Flag: "verbose",
EnvVar: "CODER_VERBOSE", EnvVar: "CODER_VERBOSE",
Shorthand: "v", Shorthand: "v",
Description: "Enables verbose logging.", Description: "Enables verbose logging.",
}, },
AuditLogging: codersdk.BoolFlag{ AuditLogging: &codersdk.BoolFlag{
Name: "Audit Logging", Name: "Audit Logging",
Flag: "audit-logging", Flag: "audit-logging",
EnvVar: "CODER_AUDIT_LOGGING", EnvVar: "CODER_AUDIT_LOGGING",
@ -344,14 +354,14 @@ func Flags() codersdk.DeploymentFlags {
Default: true, Default: true,
Enterprise: true, Enterprise: true,
}, },
BrowserOnly: codersdk.BoolFlag{ BrowserOnly: &codersdk.BoolFlag{
Name: "Browser Only", Name: "Browser Only",
Flag: "browser-only", Flag: "browser-only",
EnvVar: "CODER_BROWSER_ONLY", EnvVar: "CODER_BROWSER_ONLY",
Description: "Whether Coder only allows connections to workspaces via the browser.", Description: "Whether Coder only allows connections to workspaces via the browser.",
Enterprise: true, Enterprise: true,
}, },
SCIMAuthHeader: codersdk.StringFlag{ SCIMAuthHeader: &codersdk.StringFlag{
Name: "SCIM Authentication Header", Name: "SCIM Authentication Header",
Flag: "scim-auth-header", Flag: "scim-auth-header",
EnvVar: "CODER_SCIM_API_KEY", EnvVar: "CODER_SCIM_API_KEY",
@ -359,7 +369,7 @@ func Flags() codersdk.DeploymentFlags {
Secret: true, Secret: true,
Enterprise: true, Enterprise: true,
}, },
UserWorkspaceQuota: codersdk.IntFlag{ UserWorkspaceQuota: &codersdk.IntFlag{
Name: "User Workspace Quota", Name: "User Workspace Quota",
Flag: "user-workspace-quota", Flag: "user-workspace-quota",
EnvVar: "CODER_USER_WORKSPACE_QUOTA", EnvVar: "CODER_USER_WORKSPACE_QUOTA",
@ -375,10 +385,12 @@ func RemoveSensitiveValues(df codersdk.DeploymentFlags) codersdk.DeploymentFlags
t := v.Type() t := v.Type()
for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ {
fv := v.Field(i) fv := v.Field(i)
if v, ok := fv.Interface().(codersdk.StringFlag); ok { if vp, ok := fv.Interface().(*codersdk.StringFlag); ok {
if v.Secret && v.Value != "" { if vp.Secret && vp.Value != "" {
// Make a copy and remove the value.
v := *vp
v.Value = secretValue v.Value = secretValue
fv.Set(reflect.ValueOf(v)) fv.Set(reflect.ValueOf(&v))
} }
} }
} }
@ -386,6 +398,43 @@ func RemoveSensitiveValues(df codersdk.DeploymentFlags) codersdk.DeploymentFlags
return df return df
} }
//nolint:revive
func AttachFlags(flagset *pflag.FlagSet, df *codersdk.DeploymentFlags, enterprise bool) {
v := reflect.ValueOf(df).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
fv := v.Field(i)
fve := fv.Elem()
e := fve.FieldByName("Enterprise").Bool()
if e != enterprise {
continue
}
if e {
d := fve.FieldByName("Description").String()
d += cliui.Styles.Keyword.Render(" This is an Enterprise feature. Contact sales@coder.com for licensing")
fve.FieldByName("Description").SetString(d)
}
switch v := fv.Interface().(type) {
case *codersdk.StringFlag:
StringFlag(flagset, v)
case *codersdk.StringArrayFlag:
StringArrayFlag(flagset, v)
case *codersdk.IntFlag:
IntFlag(flagset, v)
case *codersdk.BoolFlag:
BoolFlag(flagset, v)
case *codersdk.DurationFlag:
DurationFlag(flagset, v)
default:
panic(fmt.Sprintf("unknown flag type: %T", v))
}
if fve.FieldByName("Hidden").Bool() {
_ = flagset.MarkHidden(fve.FieldByName("Flag").String())
}
}
}
func StringFlag(flagset *pflag.FlagSet, fl *codersdk.StringFlag) { func StringFlag(flagset *pflag.FlagSet, fl *codersdk.StringFlag) {
cliflag.StringVarP(flagset, cliflag.StringVarP(flagset,
&fl.Value, &fl.Value,

View File

@ -0,0 +1,32 @@
package deployment_test
import (
"testing"
"github.com/spf13/pflag"
"github.com/stretchr/testify/require"
"github.com/coder/coder/cli/deployment"
)
func TestFlags(t *testing.T) {
t.Parallel()
df := deployment.Flags()
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
deployment.AttachFlags(fs, df, false)
require.NotNil(t, fs.Lookup("access-url"))
require.False(t, fs.Lookup("access-url").Hidden)
require.True(t, fs.Lookup("telemetry-url").Hidden)
require.NotEmpty(t, fs.Lookup("telemetry-url").DefValue)
require.Nil(t, fs.Lookup("audit-logging"))
df = deployment.Flags()
fs = pflag.NewFlagSet("test-enterprise", pflag.ContinueOnError)
deployment.AttachFlags(fs, df, true)
require.Nil(t, fs.Lookup("access-url"))
require.NotNil(t, fs.Lookup("audit-logging"))
require.Contains(t, fs.Lookup("audit-logging").Usage, "This is an Enterprise feature")
}

View File

@ -99,9 +99,7 @@ func Core() []*cobra.Command {
} }
func AGPL() []*cobra.Command { func AGPL() []*cobra.Command {
df := deployment.Flags() all := append(Core(), Server(deployment.Flags(), func(_ context.Context, o *coderd.Options) (*coderd.API, error) {
all := append(Core(), Server(df, func(_ context.Context, o *coderd.Options) (*coderd.API, error) {
o.DeploymentFlags = &df
return coderd.New(o), nil return coderd.New(o), nil
})) }))
return all return all

View File

@ -67,7 +67,7 @@ import (
) )
// nolint:gocyclo // nolint:gocyclo
func Server(dflags codersdk.DeploymentFlags, newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) *cobra.Command { func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) *cobra.Command {
root := &cobra.Command{ root := &cobra.Command{
Use: "server", Use: "server",
Short: "Start a Coder server", Short: "Start a Coder server",
@ -318,7 +318,7 @@ func Server(dflags codersdk.DeploymentFlags, newAPI func(context.Context, *coder
MetricsCacheRefreshInterval: dflags.MetricsCacheRefreshInterval.Value, MetricsCacheRefreshInterval: dflags.MetricsCacheRefreshInterval.Value,
AgentStatsRefreshInterval: dflags.AgentStatRefreshInterval.Value, AgentStatsRefreshInterval: dflags.AgentStatRefreshInterval.Value,
Experimental: ExperimentalEnabled(cmd), Experimental: ExperimentalEnabled(cmd),
DeploymentFlags: &dflags, DeploymentFlags: dflags,
} }
if dflags.OAuth2GithubClientSecret.Value != "" { if dflags.OAuth2GithubClientSecret.Value != "" {
@ -712,58 +712,7 @@ func Server(dflags codersdk.DeploymentFlags, newAPI func(context.Context, *coder
}, },
}) })
deployment.StringFlag(root.Flags(), &dflags.AccessURL) deployment.AttachFlags(root.Flags(), dflags, false)
deployment.StringFlag(root.Flags(), &dflags.WildcardAccessURL)
deployment.StringFlag(root.Flags(), &dflags.Address)
deployment.DurationFlag(root.Flags(), &dflags.AutobuildPollInterval)
_ = root.Flags().MarkHidden(dflags.AutobuildPollInterval.Flag)
deployment.BoolFlag(root.Flags(), &dflags.DerpServerEnable)
deployment.IntFlag(root.Flags(), &dflags.DerpServerRegionID)
deployment.StringFlag(root.Flags(), &dflags.DerpServerRegionCode)
deployment.StringFlag(root.Flags(), &dflags.DerpServerRegionName)
deployment.StringArrayFlag(root.Flags(), &dflags.DerpServerSTUNAddresses)
deployment.StringFlag(root.Flags(), &dflags.DerpConfigURL)
deployment.StringFlag(root.Flags(), &dflags.DerpConfigPath)
deployment.BoolFlag(root.Flags(), &dflags.PromEnabled)
deployment.StringFlag(root.Flags(), &dflags.PromAddress)
deployment.BoolFlag(root.Flags(), &dflags.PprofEnabled)
deployment.StringFlag(root.Flags(), &dflags.CacheDir)
deployment.BoolFlag(root.Flags(), &dflags.InMemoryDatabase)
_ = root.Flags().MarkHidden(dflags.InMemoryDatabase.Flag)
deployment.IntFlag(root.Flags(), &dflags.ProvisionerDaemonCount)
deployment.StringFlag(root.Flags(), &dflags.PostgresURL)
deployment.StringFlag(root.Flags(), &dflags.OAuth2GithubClientID)
deployment.StringFlag(root.Flags(), &dflags.OAuth2GithubClientSecret)
deployment.StringArrayFlag(root.Flags(), &dflags.OAuth2GithubAllowedOrganizations)
deployment.StringArrayFlag(root.Flags(), &dflags.OAuth2GithubAllowedTeams)
deployment.BoolFlag(root.Flags(), &dflags.OAuth2GithubAllowSignups)
deployment.StringFlag(root.Flags(), &dflags.OAuth2GithubEnterpriseBaseURL)
deployment.BoolFlag(root.Flags(), &dflags.OIDCAllowSignups)
deployment.StringFlag(root.Flags(), &dflags.OIDCClientID)
deployment.StringFlag(root.Flags(), &dflags.OIDCClientSecret)
deployment.StringFlag(root.Flags(), &dflags.OIDCEmailDomain)
deployment.StringFlag(root.Flags(), &dflags.OIDCIssuerURL)
deployment.StringArrayFlag(root.Flags(), &dflags.OIDCScopes)
deployment.BoolFlag(root.Flags(), &dflags.TelemetryEnable)
deployment.BoolFlag(root.Flags(), &dflags.TelemetryTraceEnable)
deployment.StringFlag(root.Flags(), &dflags.TelemetryURL)
_ = root.Flags().MarkHidden(dflags.TelemetryURL.Flag)
deployment.BoolFlag(root.Flags(), &dflags.TLSEnable)
deployment.StringArrayFlag(root.Flags(), &dflags.TLSCertFiles)
deployment.StringFlag(root.Flags(), &dflags.TLSClientCAFile)
deployment.StringFlag(root.Flags(), &dflags.TLSClientAuth)
deployment.StringArrayFlag(root.Flags(), &dflags.TLSKeyFiles)
deployment.StringFlag(root.Flags(), &dflags.TLSMinVersion)
deployment.BoolFlag(root.Flags(), &dflags.TraceEnable)
deployment.BoolFlag(root.Flags(), &dflags.SecureAuthCookie)
deployment.StringFlag(root.Flags(), &dflags.SSHKeygenAlgorithm)
deployment.StringArrayFlag(root.Flags(), &dflags.AutoImportTemplates)
_ = root.Flags().MarkHidden(dflags.AutoImportTemplates.Flag)
deployment.DurationFlag(root.Flags(), &dflags.MetricsCacheRefreshInterval)
_ = root.Flags().MarkHidden(dflags.MetricsCacheRefreshInterval.Flag)
deployment.DurationFlag(root.Flags(), &dflags.AgentStatRefreshInterval)
_ = root.Flags().MarkHidden(dflags.AgentStatRefreshInterval.Flag)
deployment.BoolFlag(root.Flags(), &dflags.Verbose)
return root return root
} }

View File

@ -30,7 +30,7 @@ func TestDeploymentFlagSecrets(t *testing.T) {
df.SCIMAuthHeader.Value = hi df.SCIMAuthHeader.Value = hi
client := coderdtest.New(t, &coderdtest.Options{ client := coderdtest.New(t, &coderdtest.Options{
DeploymentFlags: &df, DeploymentFlags: df,
}) })
_ = coderdtest.CreateFirstUser(t, client) _ = coderdtest.CreateFirstUser(t, client)
scrubbed, err := client.DeploymentFlags(ctx) scrubbed, err := client.DeploymentFlags(ctx)

View File

@ -10,57 +10,57 @@ import (
) )
type DeploymentFlags struct { type DeploymentFlags struct {
AccessURL StringFlag `json:"access_url"` AccessURL *StringFlag `json:"access_url" typescript:",notnull"`
WildcardAccessURL StringFlag `json:"wildcard_access_url"` WildcardAccessURL *StringFlag `json:"wildcard_access_url" typescript:",notnull"`
Address StringFlag `json:"address"` Address *StringFlag `json:"address" typescript:",notnull"`
AutobuildPollInterval DurationFlag `json:"autobuild_poll_interval"` AutobuildPollInterval *DurationFlag `json:"autobuild_poll_interval" typescript:",notnull"`
DerpServerEnable BoolFlag `json:"derp_server_enabled"` DerpServerEnable *BoolFlag `json:"derp_server_enabled" typescript:",notnull"`
DerpServerRegionID IntFlag `json:"derp_server_region_id"` DerpServerRegionID *IntFlag `json:"derp_server_region_id" typescript:",notnull"`
DerpServerRegionCode StringFlag `json:"derp_server_region_code"` DerpServerRegionCode *StringFlag `json:"derp_server_region_code" typescript:",notnull"`
DerpServerRegionName StringFlag `json:"derp_server_region_name"` DerpServerRegionName *StringFlag `json:"derp_server_region_name" typescript:",notnull"`
DerpServerSTUNAddresses StringArrayFlag `json:"derp_server_stun_address"` DerpServerSTUNAddresses *StringArrayFlag `json:"derp_server_stun_address" typescript:",notnull"`
DerpConfigURL StringFlag `json:"derp_config_url"` DerpConfigURL *StringFlag `json:"derp_config_url" typescript:",notnull"`
DerpConfigPath StringFlag `json:"derp_config_path"` DerpConfigPath *StringFlag `json:"derp_config_path" typescript:",notnull"`
PromEnabled BoolFlag `json:"prom_enabled"` PromEnabled *BoolFlag `json:"prom_enabled" typescript:",notnull"`
PromAddress StringFlag `json:"prom_address"` PromAddress *StringFlag `json:"prom_address" typescript:",notnull"`
PprofEnabled BoolFlag `json:"pprof_enabled"` PprofEnabled *BoolFlag `json:"pprof_enabled" typescript:",notnull"`
PprofAddress StringFlag `json:"pprof_address"` PprofAddress *StringFlag `json:"pprof_address" typescript:",notnull"`
CacheDir StringFlag `json:"cache_dir"` CacheDir *StringFlag `json:"cache_dir" typescript:",notnull"`
InMemoryDatabase BoolFlag `json:"in_memory_database"` InMemoryDatabase *BoolFlag `json:"in_memory_database" typescript:",notnull"`
ProvisionerDaemonCount IntFlag `json:"provisioner_daemon_count"` ProvisionerDaemonCount *IntFlag `json:"provisioner_daemon_count" typescript:",notnull"`
PostgresURL StringFlag `json:"postgres_url"` PostgresURL *StringFlag `json:"postgres_url" typescript:",notnull"`
OAuth2GithubClientID StringFlag `json:"oauth2_github_client_id"` OAuth2GithubClientID *StringFlag `json:"oauth2_github_client_id" typescript:",notnull"`
OAuth2GithubClientSecret StringFlag `json:"oauth2_github_client_secret"` OAuth2GithubClientSecret *StringFlag `json:"oauth2_github_client_secret" typescript:",notnull"`
OAuth2GithubAllowedOrganizations StringArrayFlag `json:"oauth2_github_allowed_organizations"` OAuth2GithubAllowedOrganizations *StringArrayFlag `json:"oauth2_github_allowed_organizations" typescript:",notnull"`
OAuth2GithubAllowedTeams StringArrayFlag `json:"oauth2_github_allowed_teams"` OAuth2GithubAllowedTeams *StringArrayFlag `json:"oauth2_github_allowed_teams" typescript:",notnull"`
OAuth2GithubAllowSignups BoolFlag `json:"oauth2_github_allow_signups"` OAuth2GithubAllowSignups *BoolFlag `json:"oauth2_github_allow_signups" typescript:",notnull"`
OAuth2GithubEnterpriseBaseURL StringFlag `json:"oauth2_github_enterprise_base_url"` OAuth2GithubEnterpriseBaseURL *StringFlag `json:"oauth2_github_enterprise_base_url" typescript:",notnull"`
OIDCAllowSignups BoolFlag `json:"oidc_allow_signups"` OIDCAllowSignups *BoolFlag `json:"oidc_allow_signups" typescript:",notnull"`
OIDCClientID StringFlag `json:"oidc_client_id"` OIDCClientID *StringFlag `json:"oidc_client_id" typescript:",notnull"`
OIDCClientSecret StringFlag `json:"oidc_cliet_secret"` OIDCClientSecret *StringFlag `json:"oidc_cliet_secret" typescript:",notnull"`
OIDCEmailDomain StringFlag `json:"oidc_email_domain"` OIDCEmailDomain *StringFlag `json:"oidc_email_domain" typescript:",notnull"`
OIDCIssuerURL StringFlag `json:"oidc_issuer_url"` OIDCIssuerURL *StringFlag `json:"oidc_issuer_url" typescript:",notnull"`
OIDCScopes StringArrayFlag `json:"oidc_scopes"` OIDCScopes *StringArrayFlag `json:"oidc_scopes" typescript:",notnull"`
TelemetryEnable BoolFlag `json:"telemetry_enable"` TelemetryEnable *BoolFlag `json:"telemetry_enable" typescript:",notnull"`
TelemetryTraceEnable BoolFlag `json:"telemetry_trace_enable"` TelemetryTraceEnable *BoolFlag `json:"telemetry_trace_enable" typescript:",notnull"`
TelemetryURL StringFlag `json:"telemetry_url"` TelemetryURL *StringFlag `json:"telemetry_url" typescript:",notnull"`
TLSEnable BoolFlag `json:"tls_enable"` TLSEnable *BoolFlag `json:"tls_enable" typescript:",notnull"`
TLSCertFiles StringArrayFlag `json:"tls_cert_files"` TLSCertFiles *StringArrayFlag `json:"tls_cert_files" typescript:",notnull"`
TLSClientCAFile StringFlag `json:"tls_client_ca_file"` TLSClientCAFile *StringFlag `json:"tls_client_ca_file" typescript:",notnull"`
TLSClientAuth StringFlag `json:"tls_client_auth"` TLSClientAuth *StringFlag `json:"tls_client_auth" typescript:",notnull"`
TLSKeyFiles StringArrayFlag `json:"tls_key_tiles"` TLSKeyFiles *StringArrayFlag `json:"tls_key_tiles" typescript:",notnull"`
TLSMinVersion StringFlag `json:"tls_min_version"` TLSMinVersion *StringFlag `json:"tls_min_version" typescript:",notnull"`
TraceEnable BoolFlag `json:"trace_enable"` TraceEnable *BoolFlag `json:"trace_enable" typescript:",notnull"`
SecureAuthCookie BoolFlag `json:"secure_auth_cookie"` SecureAuthCookie *BoolFlag `json:"secure_auth_cookie" typescript:",notnull"`
SSHKeygenAlgorithm StringFlag `json:"ssh_keygen_algorithm"` SSHKeygenAlgorithm *StringFlag `json:"ssh_keygen_algorithm" typescript:",notnull"`
AutoImportTemplates StringArrayFlag `json:"auto_import_templates"` AutoImportTemplates *StringArrayFlag `json:"auto_import_templates" typescript:",notnull"`
MetricsCacheRefreshInterval DurationFlag `json:"metrics_cache_refresh_interval"` MetricsCacheRefreshInterval *DurationFlag `json:"metrics_cache_refresh_interval" typescript:",notnull"`
AgentStatRefreshInterval DurationFlag `json:"agent_stat_refresh_interval"` AgentStatRefreshInterval *DurationFlag `json:"agent_stat_refresh_interval" typescript:",notnull"`
Verbose BoolFlag `json:"verbose"` Verbose *BoolFlag `json:"verbose" typescript:",notnull"`
AuditLogging BoolFlag `json:"audit_logging"` AuditLogging *BoolFlag `json:"audit_logging" typescript:",notnull"`
BrowserOnly BoolFlag `json:"browser_only"` BrowserOnly *BoolFlag `json:"browser_only" typescript:",notnull"`
SCIMAuthHeader StringFlag `json:"scim_auth_header"` SCIMAuthHeader *StringFlag `json:"scim_auth_header" typescript:",notnull"`
UserWorkspaceQuota IntFlag `json:"user_workspace_quota"` UserWorkspaceQuota *IntFlag `json:"user_workspace_quota" typescript:",notnull"`
} }
type StringFlag struct { type StringFlag struct {
@ -71,6 +71,7 @@ type StringFlag struct {
Description string `json:"description"` Description string `json:"description"`
Enterprise bool `json:"enterprise"` Enterprise bool `json:"enterprise"`
Secret bool `json:"secret"` Secret bool `json:"secret"`
Hidden bool `json:"hidden"`
Default string `json:"default"` Default string `json:"default"`
Value string `json:"value"` Value string `json:"value"`
} }
@ -82,6 +83,7 @@ type BoolFlag struct {
Shorthand string `json:"shorthand"` Shorthand string `json:"shorthand"`
Description string `json:"description"` Description string `json:"description"`
Enterprise bool `json:"enterprise"` Enterprise bool `json:"enterprise"`
Hidden bool `json:"hidden"`
Default bool `json:"default"` Default bool `json:"default"`
Value bool `json:"value"` Value bool `json:"value"`
} }
@ -93,6 +95,7 @@ type IntFlag struct {
Shorthand string `json:"shorthand"` Shorthand string `json:"shorthand"`
Description string `json:"description"` Description string `json:"description"`
Enterprise bool `json:"enterprise"` Enterprise bool `json:"enterprise"`
Hidden bool `json:"hidden"`
Default int `json:"default"` Default int `json:"default"`
Value int `json:"value"` Value int `json:"value"`
} }
@ -104,6 +107,7 @@ type DurationFlag struct {
Shorthand string `json:"shorthand"` Shorthand string `json:"shorthand"`
Description string `json:"description"` Description string `json:"description"`
Enterprise bool `json:"enterprise"` Enterprise bool `json:"enterprise"`
Hidden bool `json:"hidden"`
Default time.Duration `json:"default"` Default time.Duration `json:"default"`
Value time.Duration `json:"value"` Value time.Duration `json:"value"`
} }
@ -115,6 +119,7 @@ type StringArrayFlag struct {
Shorthand string `json:"shorthand"` Shorthand string `json:"shorthand"`
Description string `json:"description"` Description string `json:"description"`
Enterprise bool `json:"enterprise"` Enterprise bool `json:"enterprise"`
Hidden bool `json:"hidden"`
Default []string `json:"default"` Default []string `json:"default"`
Value []string `json:"value"` Value []string `json:"value"`
} }

View File

@ -107,8 +107,8 @@ func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID
// CreateTemplateVersionDryRunRequest defines the request parameters for // CreateTemplateVersionDryRunRequest defines the request parameters for
// CreateTemplateVersionDryRun. // CreateTemplateVersionDryRun.
type CreateTemplateVersionDryRunRequest struct { type CreateTemplateVersionDryRunRequest struct {
WorkspaceName string WorkspaceName string `json:"workspace_name"`
ParameterValues []CreateParameterRequest ParameterValues []CreateParameterRequest `json:"parameter_values"`
} }
// CreateTemplateVersionDryRun begins a dry-run provisioner job against the // CreateTemplateVersionDryRun begins a dry-run provisioner job against the

View File

@ -5,7 +5,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/cli/deployment" "github.com/coder/coder/cli/deployment"
"github.com/coder/coder/enterprise/coderd" "github.com/coder/coder/enterprise/coderd"
@ -16,7 +15,6 @@ import (
func server() *cobra.Command { func server() *cobra.Command {
dflags := deployment.Flags() dflags := deployment.Flags()
cmd := agpl.Server(dflags, func(ctx context.Context, options *agplcoderd.Options) (*agplcoderd.API, error) { cmd := agpl.Server(dflags, func(ctx context.Context, options *agplcoderd.Options) (*agplcoderd.API, error) {
options.DeploymentFlags = &dflags
o := &coderd.Options{ o := &coderd.Options{
AuditLogging: dflags.AuditLogging.Value, AuditLogging: dflags.AuditLogging.Value,
BrowserOnly: dflags.BrowserOnly.Value, BrowserOnly: dflags.BrowserOnly.Value,
@ -32,17 +30,7 @@ func server() *cobra.Command {
return api.AGPL, nil return api.AGPL, nil
}) })
// append enterprise description to flags deployment.AttachFlags(cmd.Flags(), dflags, true)
enterpriseOnly := cliui.Styles.Keyword.Render(" This is an Enterprise feature. Contact sales@coder.com for licensing")
dflags.AuditLogging.Description += enterpriseOnly
dflags.BrowserOnly.Description += enterpriseOnly
dflags.SCIMAuthHeader.Description += enterpriseOnly
dflags.UserWorkspaceQuota.Description += enterpriseOnly
deployment.BoolFlag(cmd.Flags(), &dflags.AuditLogging)
deployment.BoolFlag(cmd.Flags(), &dflags.BrowserOnly)
deployment.StringFlag(cmd.Flags(), &dflags.SCIMAuthHeader)
deployment.IntFlag(cmd.Flags(), &dflags.UserWorkspaceQuota)
return cmd return cmd
} }

View File

@ -11,6 +11,7 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/fatih/structtag"
"golang.org/x/tools/go/packages" "golang.org/x/tools/go/packages"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -282,33 +283,51 @@ func (g *Generator) buildStruct(obj types.Object, st *types.Struct) (string, err
} }
field := st.Field(i) field := st.Field(i)
tag := reflect.StructTag(st.Tag(i)) tag := reflect.StructTag(st.Tag(i))
tags, err := structtag.Parse(string(tag))
if err != nil {
panic("invalid struct tags on type " + obj.String())
}
// Use the json name if present // Use the json name if present
jsonName := tag.Get("json") jsonTag, err := tags.Get("json")
arr := strings.Split(jsonName, ",") var (
jsonName = arr[0] jsonName string
jsonOptional bool
)
if err == nil {
jsonName = jsonTag.Name
if len(jsonTag.Options) > 0 && jsonTag.Options[0] == "omitempty" {
jsonOptional = true
}
}
if jsonName == "" { if jsonName == "" {
jsonName = field.Name() jsonName = field.Name()
} }
jsonOptional := false
if len(arr) > 1 && arr[1] == "omitempty" {
jsonOptional = true
}
var tsType TypescriptType // Infer the type.
// If a `typescript:"string"` exists, we take this, and do not try to infer. tsType, err := g.typescriptType(field.Type())
typescriptTag := tag.Get("typescript")
if typescriptTag == "-" {
// Ignore this field
continue
} else if typescriptTag != "" {
tsType.ValueType = typescriptTag
} else {
var err error
tsType, err = g.typescriptType(field.Type())
if err != nil { if err != nil {
return "", xerrors.Errorf("typescript type: %w", err) return "", xerrors.Errorf("typescript type: %w", err)
} }
// If a `typescript:"string"` exists, we take this, and ignore what we
// inferred.
typescriptTag, err := tags.Get("typescript")
if err == nil {
if err == nil && typescriptTag.Name == "-" {
// Completely ignore this field.
continue
} else if typescriptTag.Name != "" {
tsType = TypescriptType{
ValueType: typescriptTag.Name,
}
}
// If you specify `typescript:",notnull"` then mark the type as not
// optional.
if len(typescriptTag.Options) > 0 && typescriptTag.Options[0] == "notnull" {
tsType.Optional = false
}
} }
if tsType.AboveTypeLine != "" { if tsType.AboveTypeLine != "" {

View File

@ -133,6 +133,7 @@ export interface BoolFlag {
readonly shorthand: string readonly shorthand: string
readonly description: string readonly description: string
readonly enterprise: boolean readonly enterprise: boolean
readonly hidden: boolean
readonly default: boolean readonly default: boolean
readonly value: boolean readonly value: boolean
} }
@ -196,8 +197,8 @@ export interface CreateTemplateRequest {
// From codersdk/templateversions.go // From codersdk/templateversions.go
export interface CreateTemplateVersionDryRunRequest { export interface CreateTemplateVersionDryRunRequest {
readonly WorkspaceName: string readonly workspace_name: string
readonly ParameterValues: CreateParameterRequest[] readonly parameter_values: CreateParameterRequest[]
} }
// From codersdk/organizations.go // From codersdk/organizations.go
@ -319,6 +320,7 @@ export interface DurationFlag {
readonly shorthand: string readonly shorthand: string
readonly description: string readonly description: string
readonly enterprise: boolean readonly enterprise: boolean
readonly hidden: boolean
// This is likely an enum in an external package ("time.Duration") // This is likely an enum in an external package ("time.Duration")
readonly default: number readonly default: number
// This is likely an enum in an external package ("time.Duration") // This is likely an enum in an external package ("time.Duration")
@ -383,6 +385,7 @@ export interface IntFlag {
readonly shorthand: string readonly shorthand: string
readonly description: string readonly description: string
readonly enterprise: boolean readonly enterprise: boolean
readonly hidden: boolean
readonly default: number readonly default: number
readonly value: number readonly value: number
} }
@ -546,6 +549,7 @@ export interface StringArrayFlag {
readonly shorthand: string readonly shorthand: string
readonly description: string readonly description: string
readonly enterprise: boolean readonly enterprise: boolean
readonly hidden: boolean
readonly default: string[] readonly default: string[]
readonly value: string[] readonly value: string[]
} }
@ -559,6 +563,7 @@ export interface StringFlag {
readonly description: string readonly description: string
readonly enterprise: boolean readonly enterprise: boolean
readonly secret: boolean readonly secret: boolean
readonly hidden: boolean
readonly default: string readonly default: string
readonly value: string readonly value: string
} }