feat: Support config files with viper (#4696)

This commit is contained in:
Kyle Carberry
2022-10-21 17:08:23 -05:00
committed by GitHub
parent adc5c1a131
commit 7bc5b89f7a
36 changed files with 1099 additions and 1093 deletions
+4 -4
View File
@@ -256,7 +256,7 @@ export const AppRouter: FC = () => {
element={
<AuthAndFrame>
<RequirePermission
isFeatureVisible={Boolean(permissions?.viewDeploymentFlags)}
isFeatureVisible={Boolean(permissions?.viewDeploymentConfig)}
>
<DeploySettingsLayout>
<GeneralSettingsPage />
@@ -270,7 +270,7 @@ export const AppRouter: FC = () => {
element={
<AuthAndFrame>
<RequirePermission
isFeatureVisible={Boolean(permissions?.viewDeploymentFlags)}
isFeatureVisible={Boolean(permissions?.viewDeploymentConfig)}
>
<DeploySettingsLayout>
<SecuritySettingsPage />
@@ -284,7 +284,7 @@ export const AppRouter: FC = () => {
element={
<AuthAndFrame>
<RequirePermission
isFeatureVisible={Boolean(permissions?.viewDeploymentFlags)}
isFeatureVisible={Boolean(permissions?.viewDeploymentConfig)}
>
<DeploySettingsLayout>
<NetworkSettingsPage />
@@ -298,7 +298,7 @@ export const AppRouter: FC = () => {
element={
<AuthAndFrame>
<RequirePermission
isFeatureVisible={Boolean(permissions?.viewDeploymentFlags)}
isFeatureVisible={Boolean(permissions?.viewDeploymentConfig)}
>
<DeploySettingsLayout>
<AuthSettingsPage />
+3 -3
View File
@@ -667,9 +667,9 @@ export const getAgentListeningPorts = async (
return response.data
}
export const getDeploymentFlags =
async (): Promise<TypesGen.DeploymentFlags> => {
const response = await axios.get(`/api/v2/flags/deployment`)
export const getDeploymentConfig =
async (): Promise<TypesGen.DeploymentConfig> => {
const response = await axios.get(`/api/v2/config/deployment`)
return response.data
}
+57 -115
View File
@@ -126,19 +126,6 @@ export interface AzureInstanceIdentityToken {
readonly encoding: string
}
// From codersdk/flags.go
export interface BoolFlag {
readonly name: string
readonly flag: string
readonly env_var: string
readonly shorthand: string
readonly description: string
readonly enterprise: boolean
readonly hidden: boolean
readonly default: boolean
readonly value: boolean
}
// From codersdk/buildinfo.go
export interface BuildInfoResponse {
readonly external_url: string
@@ -264,75 +251,67 @@ export interface DERPRegion {
readonly latency_ms: number
}
// From codersdk/flags.go
export interface DeploymentFlags {
readonly access_url: StringFlag
readonly wildcard_access_url: StringFlag
readonly address: StringFlag
readonly autobuild_poll_interval: DurationFlag
readonly derp_server_enabled: BoolFlag
readonly derp_server_region_id: IntFlag
readonly derp_server_region_code: StringFlag
readonly derp_server_region_name: StringFlag
readonly derp_server_stun_address: StringArrayFlag
readonly derp_server_relay_address: StringFlag
readonly derp_config_url: StringFlag
readonly derp_config_path: StringFlag
readonly prom_enabled: BoolFlag
readonly prom_address: StringFlag
readonly pprof_enabled: BoolFlag
readonly pprof_address: StringFlag
readonly cache_dir: StringFlag
readonly in_memory_database: BoolFlag
readonly provisioner_daemon_count: IntFlag
readonly postgres_url: StringFlag
readonly oauth2_github_client_id: StringFlag
readonly oauth2_github_client_secret: StringFlag
readonly oauth2_github_allowed_organizations: StringArrayFlag
readonly oauth2_github_allowed_teams: StringArrayFlag
readonly oauth2_github_allow_signups: BoolFlag
readonly oauth2_github_enterprise_base_url: StringFlag
readonly oidc_allow_signups: BoolFlag
readonly oidc_client_id: StringFlag
readonly oidc_client_secret: StringFlag
readonly oidc_email_domain: StringFlag
readonly oidc_issuer_url: StringFlag
readonly oidc_scopes: StringArrayFlag
readonly telemetry_enable: BoolFlag
readonly telemetry_trace_enable: BoolFlag
readonly telemetry_url: StringFlag
readonly tls_enable: BoolFlag
readonly tls_cert_files: StringArrayFlag
readonly tls_client_ca_file: StringFlag
readonly tls_client_auth: StringFlag
readonly tls_key_files: StringArrayFlag
readonly tls_min_version: StringFlag
readonly trace_enable: BoolFlag
readonly secure_auth_cookie: BoolFlag
readonly ssh_keygen_algorithm: StringFlag
readonly auto_import_templates: StringArrayFlag
readonly metrics_cache_refresh_interval: DurationFlag
readonly agent_stat_refresh_interval: DurationFlag
readonly verbose: BoolFlag
readonly audit_logging: BoolFlag
readonly browser_only: BoolFlag
readonly scim_auth_header: StringFlag
readonly user_workspace_quota: IntFlag
// From codersdk/deploymentconfig.go
export interface DeploymentConfig {
readonly access_url: DeploymentConfigField<string>
readonly wildcard_access_url: DeploymentConfigField<string>
readonly address: DeploymentConfigField<string>
readonly autobuild_poll_interval: DeploymentConfigField<number>
readonly derp_server_enabled: DeploymentConfigField<boolean>
readonly derp_server_region_id: DeploymentConfigField<number>
readonly derp_server_region_code: DeploymentConfigField<string>
readonly derp_server_region_name: DeploymentConfigField<string>
readonly derp_server_stun_address: DeploymentConfigField<string[]>
readonly derp_server_relay_address: DeploymentConfigField<string>
readonly derp_config_url: DeploymentConfigField<string>
readonly derp_config_path: DeploymentConfigField<string>
readonly prometheus_enabled: DeploymentConfigField<boolean>
readonly prometheus_address: DeploymentConfigField<string>
readonly pprof_enabled: DeploymentConfigField<boolean>
readonly pprof_address: DeploymentConfigField<string>
readonly cache_directory: DeploymentConfigField<string>
readonly in_memory_database: DeploymentConfigField<boolean>
readonly provisioner_daemon_count: DeploymentConfigField<number>
readonly oauth2_github_client_id: DeploymentConfigField<string>
readonly oauth2_github_allowed_orgs: DeploymentConfigField<string[]>
readonly oauth2_github_allowed_teams: DeploymentConfigField<string[]>
readonly oauth2_github_allow_signups: DeploymentConfigField<boolean>
readonly oauth2_github_enterprise_base_url: DeploymentConfigField<string>
readonly oidc_allow_signups: DeploymentConfigField<boolean>
readonly oidc_client_id: DeploymentConfigField<string>
readonly oidc_email_domain: DeploymentConfigField<string>
readonly oidc_issuer_url: DeploymentConfigField<string>
readonly oidc_scopes: DeploymentConfigField<string[]>
readonly telemetry_enable: DeploymentConfigField<boolean>
readonly telemetry_trace_enable: DeploymentConfigField<boolean>
readonly telemetry_url: DeploymentConfigField<string>
readonly tls_enable: DeploymentConfigField<boolean>
readonly tls_cert_files: DeploymentConfigField<string[]>
readonly tls_client_ca_file: DeploymentConfigField<string>
readonly tls_client_auth: DeploymentConfigField<string>
readonly tls_key_files: DeploymentConfigField<string[]>
readonly tls_min_version: DeploymentConfigField<string>
readonly trace_enable: DeploymentConfigField<boolean>
readonly secure_auth_cookie: DeploymentConfigField<boolean>
readonly ssh_keygen_algorithm: DeploymentConfigField<string>
readonly auto_import_templates: DeploymentConfigField<string[]>
readonly metrics_cache_refresh_interval: DeploymentConfigField<number>
readonly agent_stat_refresh_interval: DeploymentConfigField<number>
readonly audit_logging: DeploymentConfigField<boolean>
readonly browser_only: DeploymentConfigField<boolean>
readonly user_workspace_quota: DeploymentConfigField<number>
}
// From codersdk/flags.go
export interface DurationFlag {
// From codersdk/deploymentconfig.go
export interface DeploymentConfigField<T extends Flaggable> {
readonly key: string
readonly name: string
readonly usage: string
readonly flag: string
readonly env_var: string
readonly shorthand: string
readonly description: string
readonly enterprise: boolean
readonly hidden: boolean
// This is likely an enum in an external package ("time.Duration")
readonly default: number
// This is likely an enum in an external package ("time.Duration")
readonly value: number
readonly value: T
}
// From codersdk/features.go
@@ -387,19 +366,6 @@ export interface Healthcheck {
readonly threshold: number
}
// From codersdk/flags.go
export interface IntFlag {
readonly name: string
readonly flag: string
readonly env_var: string
readonly shorthand: string
readonly description: string
readonly enterprise: boolean
readonly hidden: boolean
readonly default: number
readonly value: number
}
// From codersdk/licenses.go
export interface License {
readonly id: number
@@ -564,33 +530,6 @@ export interface ServerSentEvent {
readonly data: any
}
// From codersdk/flags.go
export interface StringArrayFlag {
readonly name: string
readonly flag: string
readonly env_var: string
readonly shorthand: string
readonly description: string
readonly enterprise: boolean
readonly hidden: boolean
readonly default: string[]
readonly value: string[]
}
// From codersdk/flags.go
export interface StringFlag {
readonly name: string
readonly flag: string
readonly env_var: string
readonly shorthand: string
readonly description: string
readonly enterprise: boolean
readonly secret: boolean
readonly hidden: boolean
readonly default: string
readonly value: string
}
// From codersdk/templates.go
export interface Template {
readonly id: string
@@ -999,3 +938,6 @@ export type WorkspaceStatus =
// From codersdk/workspacebuilds.go
export type WorkspaceTransition = "delete" | "start" | "stop"
// From codersdk/deploymentconfig.go
export type Flaggable = string | boolean | number | string[]
@@ -11,9 +11,9 @@ import React, {
import { useActor } from "@xstate/react"
import { XServiceContext } from "xServices/StateContext"
import { Loader } from "components/Loader/Loader"
import { DeploymentFlags } from "api/typesGenerated"
import { DeploymentConfig } from "api/typesGenerated"
type DeploySettingsContextValue = { deploymentFlags: DeploymentFlags }
type DeploySettingsContextValue = { deploymentConfig: DeploymentConfig }
const DeploySettingsContext = createContext<
DeploySettingsContextValue | undefined
@@ -33,9 +33,9 @@ export const DeploySettingsLayout: React.FC<PropsWithChildren> = ({
children,
}) => {
const xServices = useContext(XServiceContext)
const [state, send] = useActor(xServices.deploymentFlagsXService)
const [state, send] = useActor(xServices.deploymentConfigXService)
const styles = useStyles()
const { deploymentFlags } = state.context
const { deploymentConfig } = state.context
useEffect(() => {
if (state.matches("idle")) {
@@ -48,8 +48,10 @@ export const DeploySettingsLayout: React.FC<PropsWithChildren> = ({
<Stack className={styles.wrapper} direction="row" spacing={5}>
<Sidebar />
<main className={styles.content}>
{deploymentFlags ? (
<DeploySettingsContext.Provider value={{ deploymentFlags }}>
{deploymentConfig ? (
<DeploySettingsContext.Provider
value={{ deploymentConfig: deploymentConfig }}
>
{children}
</DeploySettingsContext.Provider>
) : (
@@ -5,7 +5,7 @@ import TableCell from "@material-ui/core/TableCell"
import TableContainer from "@material-ui/core/TableContainer"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import { DeploymentFlags } from "api/typesGenerated"
import { DeploymentConfig } from "api/typesGenerated"
import {
OptionDescription,
OptionName,
@@ -13,7 +13,7 @@ import {
} from "components/DeploySettingsLayout/Option"
import React from "react"
const OptionsTable: React.FC<{ options: Partial<DeploymentFlags> }> = ({
const OptionsTable: React.FC<{ options: Partial<DeploymentConfig> }> = ({
options,
}) => {
const styles = useStyles()
+1 -1
View File
@@ -22,7 +22,7 @@ export const Navbar: React.FC = () => {
featureVisibility[FeatureNames.AuditLog] &&
Boolean(permissions?.viewAuditLog)
const canViewDeployment =
experimental && Boolean(permissions?.viewDeploymentFlags)
experimental && Boolean(permissions?.viewDeploymentConfig)
const onSignOut = () => authSend("SIGN_OUT")
return (
@@ -12,7 +12,7 @@ import { Helmet } from "react-helmet-async"
import { pageTitle } from "util/page"
const AuthSettingsPage: React.FC = () => {
const { deploymentFlags } = useDeploySettings()
const { deploymentConfig: deploymentConfig } = useDeploySettings()
return (
<>
@@ -32,7 +32,7 @@ const AuthSettingsPage: React.FC = () => {
/>
<Badges>
{deploymentFlags.oidc_client_id.value ? (
{deploymentConfig.oidc_client_id.value ? (
<EnabledBadge />
) : (
<DisabledBadge />
@@ -41,12 +41,12 @@ const AuthSettingsPage: React.FC = () => {
<OptionsTable
options={{
oidc_client_id: deploymentFlags.oidc_client_id,
oidc_client_secret: deploymentFlags.oidc_client_secret,
oidc_allow_signups: deploymentFlags.oidc_allow_signups,
oidc_email_domain: deploymentFlags.oidc_email_domain,
oidc_issuer_url: deploymentFlags.oidc_issuer_url,
oidc_scopes: deploymentFlags.oidc_scopes,
oidc_client_id: deploymentConfig.oidc_client_id,
oidc_client_secret: deploymentConfig.oidc_client_secret,
oidc_allow_signups: deploymentConfig.oidc_allow_signups,
oidc_email_domain: deploymentConfig.oidc_email_domain,
oidc_issuer_url: deploymentConfig.oidc_issuer_url,
oidc_scopes: deploymentConfig.oidc_scopes,
}}
/>
</div>
@@ -60,7 +60,7 @@ const AuthSettingsPage: React.FC = () => {
/>
<Badges>
{deploymentFlags.oauth2_github_client_id.value ? (
{deploymentConfig.oauth2_github_client_id.value ? (
<EnabledBadge />
) : (
<DisabledBadge />
@@ -69,17 +69,17 @@ const AuthSettingsPage: React.FC = () => {
<OptionsTable
options={{
oauth2_github_client_id: deploymentFlags.oauth2_github_client_id,
oauth2_github_client_id: deploymentConfig.oauth2_github_client_id,
oauth2_github_client_secret:
deploymentFlags.oauth2_github_client_secret,
deploymentConfig.oauth2_github_client_secret,
oauth2_github_allow_signups:
deploymentFlags.oauth2_github_allow_signups,
oauth2_github_allowed_organizations:
deploymentFlags.oauth2_github_allowed_organizations,
deploymentConfig.oauth2_github_allow_signups,
oauth2_github_allowed_orgs:
deploymentConfig.oauth2_github_allowed_orgs,
oauth2_github_allowed_teams:
deploymentFlags.oauth2_github_allowed_teams,
deploymentConfig.oauth2_github_allowed_teams,
oauth2_github_enterprise_base_url:
deploymentFlags.oauth2_github_enterprise_base_url,
deploymentConfig.oauth2_github_enterprise_base_url,
}}
/>
</div>
@@ -6,7 +6,7 @@ import { Helmet } from "react-helmet-async"
import { pageTitle } from "util/page"
const GeneralSettingsPage: React.FC = () => {
const { deploymentFlags } = useDeploySettings()
const { deploymentConfig: deploymentConfig } = useDeploySettings()
return (
<>
@@ -22,9 +22,9 @@ const GeneralSettingsPage: React.FC = () => {
<OptionsTable
options={{
access_url: deploymentFlags.access_url,
address: deploymentFlags.address,
wildcard_access_url: deploymentFlags.wildcard_access_url,
access_url: deploymentConfig.access_url,
address: deploymentConfig.address,
wildcard_access_url: deploymentConfig.wildcard_access_url,
}}
/>
</>
@@ -6,7 +6,7 @@ import { Helmet } from "react-helmet-async"
import { pageTitle } from "util/page"
const NetworkSettingsPage: React.FC = () => {
const { deploymentFlags } = useDeploySettings()
const { deploymentConfig: deploymentConfig } = useDeploySettings()
return (
<>
@@ -22,10 +22,10 @@ const NetworkSettingsPage: React.FC = () => {
<OptionsTable
options={{
derp_server_enabled: deploymentFlags.derp_server_enabled,
derp_server_region_name: deploymentFlags.derp_server_region_name,
derp_server_stun_address: deploymentFlags.derp_server_stun_address,
derp_config_url: deploymentFlags.derp_config_url,
derp_server_enabled: deploymentConfig.derp_server_enabled,
derp_server_region_name: deploymentConfig.derp_server_region_name,
derp_server_stun_address: deploymentConfig.derp_server_stun_address,
derp_config_url: deploymentConfig.derp_config_url,
}}
/>
</>
@@ -16,7 +16,7 @@ import { pageTitle } from "util/page"
import { XServiceContext } from "xServices/StateContext"
const SecuritySettingsPage: React.FC = () => {
const { deploymentFlags } = useDeploySettings()
const { deploymentConfig: deploymentConfig } = useDeploySettings()
const xServices = useContext(XServiceContext)
const [entitlementsState] = useActor(xServices.entitlementsXService)
@@ -34,8 +34,8 @@ const SecuritySettingsPage: React.FC = () => {
<OptionsTable
options={{
ssh_keygen_algorithm: deploymentFlags.ssh_keygen_algorithm,
secure_auth_cookie: deploymentFlags.secure_auth_cookie,
ssh_keygen_algorithm: deploymentConfig.ssh_keygen_algorithm,
secure_auth_cookie: deploymentConfig.secure_auth_cookie,
}}
/>
</div>
@@ -89,10 +89,10 @@ const SecuritySettingsPage: React.FC = () => {
<OptionsTable
options={{
tls_enable: deploymentFlags.tls_enable,
tls_cert_files: deploymentFlags.tls_cert_files,
tls_key_files: deploymentFlags.tls_key_files,
tls_min_version: deploymentFlags.tls_min_version,
tls_enable: deploymentConfig.tls_enable,
tls_cert_files: deploymentConfig.tls_cert_files,
tls_key_files: deploymentConfig.tls_key_files,
tls_min_version: deploymentConfig.tls_min_version,
}}
/>
</div>
+3 -3
View File
@@ -3,7 +3,7 @@ import { createContext, FC, ReactNode } from "react"
import { ActorRefFrom } from "xstate"
import { authMachine } from "./auth/authXService"
import { buildInfoMachine } from "./buildInfo/buildInfoXService"
import { deploymentFlagsMachine } from "./deploymentFlags/deploymentFlagsMachine"
import { deploymentConfigMachine } from "./deploymentConfig/deploymentConfigMachine"
import { entitlementsMachine } from "./entitlements/entitlementsXService"
import { siteRolesMachine } from "./roles/siteRolesXService"
@@ -13,7 +13,7 @@ interface XServiceContextType {
entitlementsXService: ActorRefFrom<typeof entitlementsMachine>
siteRolesXService: ActorRefFrom<typeof siteRolesMachine>
// Since the info here is used by multiple deployment settings page and we don't want to refetch them every time
deploymentFlagsXService: ActorRefFrom<typeof deploymentFlagsMachine>
deploymentConfigXService: ActorRefFrom<typeof deploymentConfigMachine>
}
/**
@@ -34,7 +34,7 @@ export const XServiceProvider: FC<{ children: ReactNode }> = ({ children }) => {
buildInfoXService: useInterpret(buildInfoMachine),
entitlementsXService: useInterpret(entitlementsMachine),
siteRolesXService: useInterpret(siteRolesMachine),
deploymentFlagsXService: useInterpret(deploymentFlagsMachine),
deploymentConfigXService: useInterpret(deploymentConfigMachine),
}}
>
{children}
+2 -2
View File
@@ -16,7 +16,7 @@ export const checks = {
createTemplates: "createTemplates",
deleteTemplates: "deleteTemplates",
viewAuditLog: "viewAuditLog",
viewDeploymentFlags: "viewDeploymentFlags",
viewDeploymentConfig: "viewDeploymentConfig",
createGroup: "createGroup",
} as const
@@ -57,7 +57,7 @@ export const permissionsToCheck = {
},
action: "read",
},
[checks.viewDeploymentFlags]: {
[checks.viewDeploymentConfig]: {
object: {
resource_type: "deployment_flags",
},
@@ -0,0 +1,62 @@
import { getDeploymentConfig } from "api/api"
import { DeploymentConfig } from "api/typesGenerated"
import { createMachine, assign } from "xstate"
export const deploymentConfigMachine = createMachine(
{
id: "deploymentConfigMachine",
predictableActionArguments: true,
initial: "idle",
schema: {
context: {} as {
deploymentConfig?: DeploymentConfig
getDeploymentConfigError?: unknown
},
events: {} as { type: "LOAD" },
services: {} as {
getDeploymentConfig: {
data: DeploymentConfig
}
},
},
tsTypes: {} as import("./deploymentConfigMachine.typegen").Typegen0,
states: {
idle: {
on: {
LOAD: {
target: "loading",
},
},
},
loading: {
invoke: {
src: "getDeploymentConfig",
onDone: {
target: "loaded",
actions: ["assignDeploymentConfig"],
},
onError: {
target: "idle",
actions: ["assignGetDeploymentConfigError"],
},
},
},
loaded: {
type: "final",
},
},
},
{
services: {
getDeploymentConfig: getDeploymentConfig,
},
actions: {
assignDeploymentConfig: assign({
deploymentConfig: (_, { data }) => data,
}),
assignGetDeploymentConfigError: assign({
getDeploymentConfigError: (_, { data }) => data,
}),
},
},
)
@@ -1,62 +0,0 @@
import { getDeploymentFlags } from "api/api"
import { DeploymentFlags } from "api/typesGenerated"
import { createMachine, assign } from "xstate"
export const deploymentFlagsMachine = createMachine(
{
id: "deploymentFlagsMachine",
predictableActionArguments: true,
initial: "idle",
schema: {
context: {} as {
deploymentFlags?: DeploymentFlags
getDeploymentFlagsError?: unknown
},
events: {} as { type: "LOAD" },
services: {} as {
getDeploymentFlags: {
data: DeploymentFlags
}
},
},
tsTypes: {} as import("./deploymentFlagsMachine.typegen").Typegen0,
states: {
idle: {
on: {
LOAD: {
target: "loading",
},
},
},
loading: {
invoke: {
src: "getDeploymentFlags",
onDone: {
target: "loaded",
actions: ["assignDeploymentFlags"],
},
onError: {
target: "idle",
actions: ["assignGetDeploymentFlagsError"],
},
},
},
loaded: {
type: "final",
},
},
},
{
services: {
getDeploymentFlags,
},
actions: {
assignDeploymentFlags: assign({
deploymentFlags: (_, { data }) => data,
}),
assignGetDeploymentFlagsError: assign({
getDeploymentFlagsError: (_, { data }) => data,
}),
},
},
)