-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: garrettladley <[email protected]>
- Loading branch information
1 parent
67d0b1a
commit d40e2ed
Showing
27 changed files
with
397 additions
and
773 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Configuration | ||
|
||
SAC uses environment variables for configuration. SAC will, by default, pull the envvars from the process in which it was launched, but you can also pass in a .env file (using the --config flag) and use the values defined in there. See .env.template for an example .env file. | ||
|
||
| Name | Group | Description | | ||
|--------------------------------------|------------|---------------------------------------| | ||
| SAC_APPLICATION_PORT | app | port to run the server on. | | ||
| SAC_APPLICATION_HOST | app | host to run the server on. | | ||
| SAC_APPLICATION_BASE_URL | app | base url to run the server on. | | ||
| SAC_DB_USERNAME | db | username for database. | | ||
| SAC_DB_PASSWORD | db | password for database. | | ||
| SAC_DB_PORT | db | port for database. | | ||
| SAC_DB_HOST | db | host for database. | | ||
| SAC_DB_NAME | db | name of database. | | ||
| SAC_DB_REQUIRE_SSL | db | if the db connection requires ssl. | | ||
| SAC_REDIS_ACTIVE_TOKENS_USERNAME | redis | username for active tokens redis. | | ||
| SAC_REDIS_ACTIVE_TOKENS_PASSWORD | redis | password for active tokens redis. | | ||
| SAC_REDIS_ACTIVE_TOKENS_HOST | redis | host for active tokens redis. | | ||
| SAC_REDIS_ACTIVE_TOKENS_PORT | redis | port for active tokens redis. | | ||
| SAC_REDIS_ACTIVE_TOKENS_DB | redis | db for active tokens redis. | | ||
| SAC_REDIS_BLACKLIST_USERNAME | redis | username for blacklist redis. | | ||
| SAC_REDIS_BLACKLIST_PASSWORD | redis | password for blacklist redis. | | ||
| SAC_REDIS_BLACKLIST_HOST | redis | host for blacklist redis. | | ||
| SAC_REDIS_BLACKLIST_PORT | redis | port for blacklist redis. | | ||
| SAC_REDIS_BLACKLIST_DB | redis | db for blacklist redis. | | ||
| SAC_REDIS_LIMITER_USERNAME | redis | username for limiter redis. | | ||
| SAC_REDIS_LIMITER_PASSWORD | redis | password for limiter redis. | | ||
| SAC_REDIS_LIMITER_HOST | redis | host for limiter redis. | | ||
| SAC_REDIS_LIMITER_PORT | redis | port for limiter redis. | | ||
| SAC_REDIS_LIMITER_DB | redis | db for limiter redis. | | ||
| SAC_SUDO_PASSWORD | superuser | password for the superuser. | | ||
| SAC_AUTH_ACCESS_KEY | auth | access key for auth. | | ||
| SAC_AUTH_REFRESH_KEY | auth | refresh key for auth. | | ||
| SAC_AWS_BUCKET_NAME | aws | bucket name for aws s3. | | ||
| SAC_AWS_ID | aws | id for aws s3. | | ||
| SAC_AWS_SECRET | aws | secret for aws s3. | | ||
| SAC_AWS_REGION | aws | region for aws s3. | | ||
| SAC_RESEND_API_KEY | resend | api key for resend. | | ||
| SAC_CALENDAR_MAX_TERMINATION_DATE | calendar | max termination date for calendar integrations. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package config | ||
|
||
type ApplicationSettings struct { | ||
Port uint16 `env:"PORT"` | ||
Host string `env:"HOST"` | ||
BaseUrl string `env:"BASE_URL"` | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,30 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
|
||
m "github.com/garrettladley/mattress" | ||
) | ||
import m "github.com/garrettladley/mattress" | ||
|
||
type AuthSettings struct { | ||
AccessKey *m.Secret[string] | ||
RefreshKey *m.Secret[string] | ||
} | ||
|
||
type intermediateAuthSettings struct { | ||
AccessKey string `yaml:"accesskey"` | ||
RefreshKey string `yaml:"refreshkey"` | ||
AccessKey string `env:"ACCESS_KEY"` | ||
RefreshKey string `env:"REFRESH_KEY"` | ||
} | ||
|
||
func (int *intermediateAuthSettings) into() (*AuthSettings, error) { | ||
accessToken, err := m.NewSecret(int.AccessKey) | ||
func (i *intermediateAuthSettings) into() (*AuthSettings, error) { | ||
accessKey, err := m.NewSecret(i.AccessKey) | ||
if err != nil { | ||
return nil, errors.New("failed to create secret from access key") | ||
return nil, err | ||
} | ||
|
||
refreshToken, err := m.NewSecret(int.RefreshKey) | ||
refreshKey, err := m.NewSecret(i.RefreshKey) | ||
if err != nil { | ||
return nil, errors.New("failed to create secret from refresh key") | ||
return nil, err | ||
} | ||
|
||
return &AuthSettings{ | ||
AccessKey: accessToken, | ||
RefreshKey: refreshToken, | ||
AccessKey: accessKey, | ||
RefreshKey: refreshKey, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,46 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"os" | ||
|
||
m "github.com/garrettladley/mattress" | ||
) | ||
import m "github.com/garrettladley/mattress" | ||
|
||
type AWSSettings struct { | ||
BUCKET_NAME *m.Secret[string] | ||
ID *m.Secret[string] | ||
SECRET *m.Secret[string] | ||
REGION *m.Secret[string] | ||
BucketName *m.Secret[string] | ||
Id *m.Secret[string] | ||
Secret *m.Secret[string] | ||
Region *m.Secret[string] | ||
} | ||
|
||
func readAWSSettings() (*AWSSettings, error) { | ||
bucketName := os.Getenv("SAC_AWS_BUCKET_NAME") | ||
if bucketName == "" { | ||
return nil, errors.New("SAC_AWS_BUCKET_NAME is not set") | ||
} | ||
type intermediateAWSSettings struct { | ||
BucketName string `env:"BUCKET_NAME"` | ||
Id string `env:"ID"` | ||
Secret string `env:"SECRET"` | ||
Region string `env:"REGION"` | ||
} | ||
|
||
secretBucketName, err := m.NewSecret(bucketName) | ||
func (i *intermediateAWSSettings) into() (*AWSSettings, error) { | ||
bucketName, err := m.NewSecret(i.BucketName) | ||
if err != nil { | ||
return nil, errors.New("failed to create secret from bucket name") | ||
} | ||
|
||
id := os.Getenv("SAC_AWS_ID") | ||
if id == "" { | ||
return nil, errors.New("SAC_AWS_ID is not set") | ||
return nil, err | ||
} | ||
|
||
secretID, err := m.NewSecret(id) | ||
id, err := m.NewSecret(i.Id) | ||
if err != nil { | ||
return nil, errors.New("failed to create secret from id") | ||
return nil, err | ||
} | ||
|
||
secret := os.Getenv("SAC_AWS_SECRET") | ||
if secret == "" { | ||
return nil, errors.New("SAC_AWS_SECRET is not set") | ||
} | ||
|
||
secretSecret, err := m.NewSecret(secret) | ||
secret, err := m.NewSecret(i.Secret) | ||
if err != nil { | ||
return nil, errors.New("failed to create secret from secret") | ||
} | ||
|
||
region := os.Getenv("SAC_AWS_REGION") | ||
if region == "" { | ||
return nil, errors.New("SAC_AWS_REGION is not set") | ||
return nil, err | ||
} | ||
|
||
reigonSecret, err := m.NewSecret(region) | ||
region, err := m.NewSecret(i.Region) | ||
if err != nil { | ||
return nil, errors.New("failed to create secret from region") | ||
return nil, err | ||
} | ||
|
||
return &AWSSettings{ | ||
BUCKET_NAME: secretBucketName, | ||
ID: secretID, | ||
SECRET: secretSecret, | ||
REGION: reigonSecret, | ||
BucketName: bucketName, | ||
Id: id, | ||
Secret: secret, | ||
Region: region, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,21 @@ | ||
package config | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/viper" | ||
"github.com/caarlos0/env/v11" | ||
"github.com/joho/godotenv" | ||
) | ||
|
||
type Settings struct { | ||
Application ApplicationSettings | ||
Database DatabaseSettings | ||
Redis []RedisSettings | ||
SuperUser SuperUserSettings | ||
Auth AuthSettings | ||
AWS AWSSettings | ||
Resend ResendSettings | ||
Calendar CalendarSettings | ||
GoogleSettings OAuthSettings | ||
OutlookSettings OAuthSettings | ||
} | ||
|
||
type intermediateSettings struct { | ||
Application ApplicationSettings `yaml:"application"` | ||
Database intermediateDatabaseSettings `yaml:"database"` | ||
Redis []intermediateRedisSettings `yaml:"redis"` | ||
SuperUser intermediateSuperUserSettings `yaml:"superuser"` | ||
Auth intermediateAuthSettings `yaml:"authsecret"` | ||
Calendar intermediateCalendarSettings `yaml:"calendar"` | ||
} | ||
|
||
func (int *intermediateSettings) into() (*Settings, error) { | ||
databaseSettings, err := int.Database.into() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
redisSettings := make([]RedisSettings, len(int.Redis)) | ||
for i, r := range int.Redis { | ||
redisInstance, err := r.into() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
redisSettings[i] = *redisInstance | ||
} | ||
|
||
superUserSettings, err := int.SuperUser.into() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
authSettings, err := int.Auth.into() | ||
func GetConfiguration(path string) (*Settings, error) { | ||
err := godotenv.Load(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
calendarSettings, err := int.Calendar.into() | ||
if err != nil { | ||
var intermediateSettings intermediateSettings | ||
if err := env.Parse(&intermediateSettings); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &Settings{ | ||
Application: int.Application, | ||
Database: *databaseSettings, | ||
Redis: redisSettings, | ||
SuperUser: *superUserSettings, | ||
Auth: *authSettings, | ||
Calendar: *calendarSettings, | ||
}, nil | ||
} | ||
|
||
type Environment string | ||
|
||
const ( | ||
EnvironmentLocal Environment = "local" | ||
EnvironmentProduction Environment = "production" | ||
) | ||
|
||
func GetConfiguration(path string, useDevDotEnv bool) (*Settings, error) { | ||
var environment Environment | ||
if env := os.Getenv("APP_ENVIRONMENT"); env != "" { | ||
environment = Environment(env) | ||
} else { | ||
environment = "local" | ||
} | ||
|
||
v := viper.New() | ||
v.SetConfigType("yaml") | ||
v.AddConfigPath(path) | ||
|
||
switch environment { | ||
case EnvironmentLocal: | ||
return readLocal(v, path, useDevDotEnv) | ||
case EnvironmentProduction: | ||
return readProd(v) | ||
default: | ||
return nil, fmt.Errorf("unknown environment: %s", environment) | ||
} | ||
settings, err := intermediateSettings.into() | ||
return settings, err | ||
} |
Oops, something went wrong.