Skip to content

Commit

Permalink
Source of truth (#236)
Browse files Browse the repository at this point in the history
* add mongo docker compose for ease of development

* have env package be source of truth for all env variables in internal packages.

* update internal packages to use env package variables

* get rid of copy pasta tick remnants

* go mod tidy

* test for GetEnv. Thanks Jairo!

* remove processing of GetEnv error from other func calls, redundant when call will fail on initial call to main
  • Loading branch information
D-B-Hawk authored Nov 13, 2023
1 parent b5efac7 commit f72d5e1
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 155 deletions.
16 changes: 14 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
MONGODB_USERNAME=root
MONGODB_PASSWORD=password
MONGODB_HOST_TYPE=local
MONGODB_HOST_TYPE=local # local | atlas
MONGODB_HOST="localhost:27017"
SERVER_PORT=8081
K1_ACCESS_TOKEN=feedkray
IS_CLUSTER_ZERO=
CLUSTER_TYPE="bootstrap"
CLUSTER_ID="abc456"
INSTALL_METHOD="helm"
K1_ACCESS_TOKEN=feedkray
CLOUD_PROVIDER=google
KUBEFIRST_VERSION=
DOMAIN_NAME=
GIT_PROVIDER=
KUBEFIRST_TEAM=
KUBEFIRST_TEAM_INFO=
AWS_REGION=
AWS_PROFILE=
IN_CLUSTER=
ENTERPRISE_API_URL=
79 changes: 43 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Kubefirst API runtime implementation.
- [local environment variables](#local-environment-variables)
- [Provider Support](#provider-support)
- [Creating a Cluster](#creating-a-cluster)
- [Kubernetes Secret](#kubernetes-secret)
- [API Call Parameters](#api-call-parameters)
- [Kubernetes Secret](#kubernetes-secret)
- [API Call Parameters](#api-call-parameters)
- [AWS](#aws)
- [Civo](#civo)
- [Digital Ocean](#digital-ocean)
Expand All @@ -48,7 +48,7 @@ The API is available at `http://localhost:8081/api/v1` while running.
### Build the Binary

The API can be run locally for testing. It can be run by using `make build` and then calling the binary in the `bin/` directory or by using `go run .`.

### Leverage `air` for Live Reloading Locally

**Prerequsite** - Install [air](https://github.com/cosmtrek/air).
Expand All @@ -57,7 +57,7 @@ The API can be run locally for testing. It can be run by using `make build` and
go install github.com/cosmtrek/air@latest
```

Run `air` from the root of the repository. This will watch go files and live rebuild a local running instance of `kubefirst-api`.
Run `air` from the root of the repository. This will watch go files and live rebuild a local running instance of `kubefirst-api`.

## Prerequisites

Expand All @@ -75,19 +75,19 @@ The host:port for MongoDB should be supplied as the environment variable `MONGOD

Some variables are required, others are optional depending on deployment type.

| Variable | Description | Required |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- |
| `MONGODB_HOST_TYPE` | Can be either `atlas` or `local`. | Yes |
| `MONGODB_HOST` | The host to connect to. For Atlas, use only the portion of the string not containing username or password. For all other types, append the port. | Yes |
| `MONGODB_USERNAME` | Required when using Atlas. | If using Atlas |
| `MONGODB_PASSWORD` | Required when using Atlas. | If using Atlas |
| `IN_CLUSTER` | Specify whether or not the API is running inside a Kubernetes cluster. By default, this is assumed `false`. | No |
| `CLUSTER_ID` | The ID of the cluster running API. | Yes |
| `CLUSTER_TYPE` | Cluster type. | Yes |
| `INSTALL_METHOD` | Description of the method through which the API was deployed. Example: `helm` | Yes |
| `K1_ACCESS_TOKEN` | Access token in authorization header to prevent unsolicited in-cluster access | Yes |
| Variable | Description | Required |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ |
| `MONGODB_HOST_TYPE` | Can be either `atlas` or `local`. | Yes |
| `MONGODB_HOST` | The host to connect to. For Atlas, use only the portion of the string not containing username or password. For all other types, append the port. | Yes |
| `MONGODB_USERNAME` | Required when using Atlas/ Docker compose. | If using Atlas/ Docker compose |
| `MONGODB_PASSWORD` | Required when using Atlas/ Docker compose. | If using Atlas/ Docker compose |
| `IN_CLUSTER` | Specify whether or not the API is running inside a Kubernetes cluster. By default, this is assumed `false`. | No |
| `CLUSTER_ID` | The ID of the cluster running API. | Yes |
| `CLUSTER_TYPE` | Cluster type. | Yes |
| `INSTALL_METHOD` | Description of the method through which the API was deployed. Example: `helm` | Yes |
| `K1_ACCESS_TOKEN` | Access token in authorization header to prevent unsolicited in-cluster access | Yes |

### To run locally:
### To run locally:

```bash
# optional local mongodb for kubefirst-api
Expand All @@ -98,7 +98,14 @@ docker run -d --name k1-api-mongodb \
mongo
```

### Using Docker compose:

```bash
docker compose up
```

## local environment variables

see [this .env example](./.env.example) for the necessary values

## Provider Support
Expand Down Expand Up @@ -146,46 +153,46 @@ This would require the following parameters added to the API call depending on w

```json
{
"aws_auth": {
"access_key_id": "foo",
"secret_access_key": "bar",
"session_token": "baz"
}
"aws_auth": {
"access_key_id": "foo",
"secret_access_key": "bar",
"session_token": "baz"
}
}
```

```json
{
"civo_auth": {
"token": "my-civo-token"
}
"civo_auth": {
"token": "my-civo-token"
}
}
```

```json
{
"do_auth": {
"token": "my-do-token",
"spaces_key": "foo",
"spaces_secret": "bar"
}
"do_auth": {
"token": "my-do-token",
"spaces_key": "foo",
"spaces_secret": "bar"
}
}
```

```json
{
"do_auth": {
"key_file": "my-google-credentials-json-keyfile-stringified-no-newline-characters",
"project_id": "google cloud project id"
}
"do_auth": {
"key_file": "my-google-credentials-json-keyfile-stringified-no-newline-characters",
"project_id": "google cloud project id"
}
}
```

```json
{
"vultr_auth": {
"token": "my-vultr-api-key"
}
"vultr_auth": {
"token": "my-vultr-api-key"
}
}
```

Expand Down
11 changes: 11 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: "3.1"

services:
k1-api-mongodb:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGODB_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGODB_PASSWORD}
ports:
- 27017:27017
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.18.19
github.com/aws/aws-sdk-go-v2/service/eks v1.27.10
github.com/aws/aws-sdk-go-v2/service/route53 v1.27.5
github.com/caarlos0/env/v10 v10.0.0
github.com/charmbracelet/bubbles v0.15.0
github.com/charmbracelet/bubbletea v0.23.2
github.com/charmbracelet/lipgloss v0.8.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 h1:5+NghM1Zred9Z078QEZtm28G/kf
github.com/bradleyfalzon/ghinstallation/v2 v2.1.0/go.mod h1:Xg3xPRN5Mcq6GDqeUVhFbjEWMb4JHCyWEeeBGEYQoTU=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA=
github.com/caarlos0/env/v10 v10.0.0/go.mod h1:ZfulV76NvVPw3tm591U4SwL3Xx9ldzBP9aGxzeN7G18=
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
github.com/caarlos0/sshmarshal v0.1.0 h1:zTCZrDORFfWh526Tsb7vCm3+Yg/SfW/Ub8aQDeosk0I=
Expand Down
11 changes: 5 additions & 6 deletions internal/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import (
"errors"
"fmt"
"net"
"os"
"strconv"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/route53"
route53Types "github.com/aws/aws-sdk-go-v2/service/route53/types"
"github.com/kubefirst/kubefirst-api/internal/env"
"github.com/kubefirst/kubefirst-api/internal/utils"
log "github.com/sirupsen/logrus"
)
Expand All @@ -35,13 +35,12 @@ var Conf AWSConfiguration = AWSConfiguration{

// NewAws instantiates a new AWS configuration
func NewAws() aws.Config {
region := os.Getenv("AWS_REGION")
profile := os.Getenv("AWS_PROFILE")

env, _ := env.GetEnv()

awsClient, err := config.LoadDefaultConfig(
context.Background(),
config.WithRegion(region),
config.WithSharedConfigProfile(profile),
config.WithRegion(env.AWSRegion),
config.WithSharedConfigProfile(env.AWSProfile),
)
if err != nil {
log.Errorf("Could not create AWS config: %s", err.Error())
Expand Down
15 changes: 5 additions & 10 deletions internal/controller/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
googleext "github.com/kubefirst/kubefirst-api/extensions/google"
terraformext "github.com/kubefirst/kubefirst-api/extensions/terraform"
vultrext "github.com/kubefirst/kubefirst-api/extensions/vultr"
"github.com/kubefirst/kubefirst-api/internal/env"
gitShim "github.com/kubefirst/kubefirst-api/internal/gitShim"
"github.com/kubefirst/kubefirst-api/pkg/providerConfigs"
pkgtypes "github.com/kubefirst/kubefirst-api/pkg/types"
Expand Down Expand Up @@ -110,11 +111,6 @@ func (clctrl *ClusterController) CreateCluster() error {

// CreateTokens
func (clctrl *ClusterController) CreateTokens(kind string) interface{} {
kubefirstVersion := os.Getenv("KUBEFIRST_VERSION")
if kubefirstVersion == "" {
kubefirstVersion = "development"
}

cl, err := clctrl.MdbCl.GetCluster(clctrl.ClusterName)
if err != nil {
return err
Expand Down Expand Up @@ -162,6 +158,8 @@ func (clctrl *ClusterController) CreateTokens(kind string) interface{} {
return err
}

env, _ := env.GetEnv()

// Default gitopsTemplateTokens
gitopsTemplateTokens := &providerConfigs.GitopsDirectoryValues{
AlertsEmail: clctrl.AlertsEmail,
Expand All @@ -174,7 +172,7 @@ func (clctrl *ClusterController) CreateTokens(kind string) interface{} {
SubdomainName: clctrl.SubdomainName,
KubefirstStateStoreBucket: clctrl.KubefirstStateStoreBucketName,
KubefirstTeam: clctrl.KubefirstTeam,
KubefirstVersion: kubefirstVersion,
KubefirstVersion: env.KubefirstVersion,
Kubeconfig: clctrl.ProviderConfig.Kubeconfig, //AWS
KubeconfigPath: clctrl.ProviderConfig.Kubeconfig, //Not AWS

Expand Down Expand Up @@ -251,7 +249,7 @@ func (clctrl *ClusterController) CreateTokens(kind string) interface{} {
} else {
// moving commented line below to default behavior
// gitopsTemplateTokens.ContainerRegistryURL = fmt.Sprintf("%s/%s", clctrl.ContainerRegistryHost, clctrl.GitAuth.Owner)
log.Info("NOT using ECR but instead %s URL %s", clctrl.GitProvider, gitopsTemplateTokens.ContainerRegistryURL)
log.Infof("NOT using ECR but instead %s URL %s", clctrl.GitProvider, gitopsTemplateTokens.ContainerRegistryURL)
}
}

Expand Down Expand Up @@ -374,9 +372,6 @@ func (clctrl *ClusterController) ContainerRegistryAuth() (string, error) {
kcfg = awsext.CreateEKSKubeconfig(&clctrl.AwsClient.Config, clctrl.ClusterName)

// Container registry authentication creation
if !clctrl.ECR {

}
containerRegistryAuth := gitShim.ContainerRegistryAuth{
GitProvider: clctrl.GitProvider,
GitUser: clctrl.GitAuth.User,
Expand Down
35 changes: 17 additions & 18 deletions internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ import (
"context"
"fmt"
"net/http"
"os"
"time"

"github.com/kubefirst/kubefirst-api/internal/constants"
"github.com/kubefirst/kubefirst-api/internal/db"
"github.com/kubefirst/kubefirst-api/internal/env"
"github.com/kubefirst/kubefirst-api/internal/utils"
google "github.com/kubefirst/kubefirst-api/pkg/google"
"github.com/kubefirst/kubefirst-api/pkg/handlers"
"github.com/kubefirst/kubefirst-api/pkg/providerConfigs"
pkgtypes "github.com/kubefirst/kubefirst-api/pkg/types"
"github.com/kubefirst/metrics-client/pkg/telemetry"
"github.com/kubefirst/runtime/pkg"
runtime "github.com/kubefirst/runtime/pkg"
awsinternal "github.com/kubefirst/runtime/pkg/aws"
"github.com/kubefirst/runtime/pkg/github"
Expand Down Expand Up @@ -143,21 +142,23 @@ func (clctrl *ClusterController) InitController(def *pkgtypes.ClusterDefinition)
clusterID = runtime.GenerateClusterID()
}

env, _ := env.GetEnv()

telemetryEvent := telemetry.TelemetryEvent{
CliVersion: os.Getenv("KUBEFIRST_VERSION"),
CloudProvider: os.Getenv("CLOUD_PROVIDER"),
ClusterID: os.Getenv("CLUSTER_ID"),
ClusterType: os.Getenv("CLUSTER_TYPE"),
DomainName: os.Getenv("DOMAIN_NAME"),
CliVersion: env.KubefirstVersion,
CloudProvider: env.CloudProvider,
ClusterID: env.ClusterId,
ClusterType: env.ClusterType,
DomainName: env.DomainName,
ErrorMessage: "",
GitProvider: os.Getenv("GIT_PROVIDER"),
InstallMethod: os.Getenv("INSTALL_METHOD"),
GitProvider: env.GitProvider,
InstallMethod: env.InstallMethod,
KubefirstClient: "api",
KubefirstTeam: os.Getenv("KUBEFIRST_TEAM"),
KubefirstTeamInfo: os.Getenv("KUBEFIRST_TEAM_INFO"),
MachineID: os.Getenv("CLUSTER_ID"),
KubefirstTeam: env.KubefirstTeam,
KubefirstTeamInfo: env.KubefirstTeamInfo,
MachineID: env.ClusterId,
MetricName: telemetry.ClusterInstallStarted,
UserId: os.Getenv("CLUSTER_ID"),
UserId: env.ClusterId,
}
clctrl.TelemetryEvent = telemetryEvent

Expand Down Expand Up @@ -206,11 +207,9 @@ func (clctrl *ClusterController) InitController(def *pkgtypes.ClusterDefinition)
clctrl.KubefirstStateStoreBucketName = fmt.Sprintf("k1-state-store-%s-%s", clctrl.ClusterName, clusterID)
clctrl.KubefirstArtifactsBucketName = fmt.Sprintf("k1-artifacts-%s-%s", clctrl.ClusterName, clusterID)

clctrl.KubefirstTeam = os.Getenv("KUBEFIRST_TEAM")
if clctrl.KubefirstTeam == "" {
clctrl.KubefirstTeam = "undefined"
}
clctrl.AtlantisWebhookSecret = pkg.Random(20)
clctrl.KubefirstTeam = env.KubefirstTeam

clctrl.AtlantisWebhookSecret = runtime.Random(20)

var fullDomainName string
if clctrl.SubdomainName != "" {
Expand Down
Loading

0 comments on commit f72d5e1

Please sign in to comment.