Skip to content

Commit

Permalink
Add Frontegg and Cloud mocks for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbyiliev committed Nov 22, 2023
1 parent 60282d7 commit 3a461ce
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 1 deletion.
10 changes: 10 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,13 @@ services:
TF_LOG: INFO
command: >
sh -c "tail -F /dev/null"
mock_frontegg:
build: mocks/frontegg
ports:
- "3000:3000"

mock_cloud_api:
build: mocks/cloud
ports:
- "3001:3001"
30 changes: 30 additions & 0 deletions mocks/cloud/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Start from the official Golang base image
FROM golang:1.20 as builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY . .

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o mockserver .

# Start a new stage from scratch
FROM alpine:latest

RUN apk --no-cache add ca-certificates

WORKDIR /root/

# Copy the Pre-built binary file from the previous stage
COPY --from=builder /app/mockserver .

# Command to run the executable
CMD ["./mockserver"]
5 changes: 5 additions & 0 deletions mocks/cloud/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module cloud-mockserver

go 1.20

require github.com/golang-jwt/jwt/v5 v5.1.0 // indirect
2 changes: 2 additions & 0 deletions mocks/cloud/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/golang-jwt/jwt/v5 v5.1.0 h1:UGKbA/IPjtS6zLcdB7i5TyACMgSbOTiR8qzXgw8HWQU=
github.com/golang-jwt/jwt/v5 v5.1.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
90 changes: 90 additions & 0 deletions mocks/cloud/mock_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
)

type Region struct {
ID string `json:"id"`
Name string `json:"name"`
CloudProvider string `json:"cloudProvider"`
URL string `json:"url"`
RegionInfo *RegionInfo `json:"regionInfo,omitempty"`
}

type RegionInfo struct {
SqlAddress string `json:"sqlAddress"`
HttpAddress string `json:"httpAddress"`
Resolvable bool `json:"resolvable"`
EnabledAt string `json:"enabledAt"`
}

type CloudRegion struct {
RegionInfo *RegionInfo `json:"regionInfo"`
}

type CloudProviderResponse struct {
Data []Region `json:"data"`
NextCursor string `json:"nextCursor,omitempty"`
}

// Mock data
var regions = []Region{
{
ID: "aws/us-east-1",
Name: "us-east-1",
CloudProvider: "aws",
URL: "http://localhost:3001",
RegionInfo: &RegionInfo{
SqlAddress: "materialized:6877",
HttpAddress: "materialized:6875",
Resolvable: true,
EnabledAt: "2023-01-01T00:00:00Z",
},
},
// Add more mock regions if needed later
}

func main() {
http.HandleFunc("/api/region", regionHandler)
http.HandleFunc("/api/cloud-regions", cloudRegionsHandler)

fmt.Println("Mock Cloud API server is running at http://localhost:3001")
log.Fatal(http.ListenAndServe(":3001", nil))
}

func regionHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
mockRegion := CloudRegion{
RegionInfo: &RegionInfo{
SqlAddress: "materialized:6877",
HttpAddress: "materialized:6875",
Resolvable: true,
EnabledAt: "2023-01-01T00:00:00Z",
},
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(mockRegion)
case http.MethodPatch:
w.WriteHeader(http.StatusOK)
case http.MethodDelete:
w.WriteHeader(http.StatusAccepted)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}

func cloudRegionsHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
response := CloudProviderResponse{
Data: regions,
}
json.NewEncoder(w).Encode(response)
}
30 changes: 30 additions & 0 deletions mocks/frontegg/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Start from the official Golang base image
FROM golang:1.20 as builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY . .

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o mockserver .

# Start a new stage from scratch
FROM alpine:latest

RUN apk --no-cache add ca-certificates

WORKDIR /root/

# Copy the Pre-built binary file from the previous stage
COPY --from=builder /app/mockserver .

# Command to run the executable
CMD ["./mockserver"]
5 changes: 5 additions & 0 deletions mocks/frontegg/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module frontegg-mockserver

go 1.20

require github.com/golang-jwt/jwt/v5 v5.1.0 // indirect
2 changes: 2 additions & 0 deletions mocks/frontegg/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/golang-jwt/jwt/v5 v5.1.0 h1:UGKbA/IPjtS6zLcdB7i5TyACMgSbOTiR8qzXgw8HWQU=
github.com/golang-jwt/jwt/v5 v5.1.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
60 changes: 60 additions & 0 deletions mocks/frontegg/mock_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"encoding/base64"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
)

// base64UrlEncode encodes the input in base64 URL-safe format.
func base64UrlEncode(input []byte) string {
encoded := base64.StdEncoding.EncodeToString(input)
encoded = strings.ReplaceAll(encoded, "+", "-")
encoded = strings.ReplaceAll(encoded, "/", "_")
encoded = strings.TrimRight(encoded, "=")
return encoded
}

func main() {
http.HandleFunc("/identity/resources/auth/v1/api-token", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}

var payload struct {
ClientId string `json:"clientId"`
Secret string `json:"secret"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer r.Body.Close()

// Mock authentication logic
if payload.ClientId == "1b2a3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d" && payload.Secret == "7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b" {
// Create a mock JWT token with base64 URL-safe encoding
header := base64UrlEncode([]byte(`{"alg":"HS256","typ":"JWT"}`))
payload := base64UrlEncode([]byte(`{"email":"mz_system","exp":1700000000}`))
signature := base64UrlEncode([]byte(`signature`))
mockToken := fmt.Sprintf("%s.%s.%s", header, payload, signature)

// For testing locally set the response email to "mz_system"
response := map[string]string{
"accessToken": mockToken,
"email": "mz_system",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
} else {
http.Error(w, "Invalid credentials", http.StatusUnauthorized)
}
})

fmt.Println("Mock Frontegg server is running at http://localhost:3000")
log.Fatal(http.ListenAndServe(":3000", nil))
}
7 changes: 6 additions & 1 deletion pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData, version stri
continue
}

// Check if regionDetails or RegionInfo is nil before proceeding
if regionDetails == nil || regionDetails.RegionInfo == nil {
continue
}

regionsEnabled[clients.Region(provider.ID)] = regionDetails.RegionInfo != nil && regionDetails.RegionInfo.Resolvable

// Get the database connection details for the region
Expand All @@ -191,7 +196,7 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData, version stri

// Check if at least one region has been initialized successfully
if len(dbClients) == 0 {
return nil, diag.Errorf("No regions were initialized. Please check your configuration.")
return nil, diag.Errorf("No database regions were initialized. Please check your configuration.")
}

// Debug log the dbClients map
Expand Down

0 comments on commit 3a461ce

Please sign in to comment.