Skip to content

Commit

Permalink
Merge pull request #70 from cloud-barista/feature/system-ready-z
Browse files Browse the repository at this point in the history
Feat: Add Read System
  • Loading branch information
heedaeshin authored Oct 2, 2024
2 parents 13cc119 + 96ded79 commit de6a76c
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 3 deletions.
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ ARG GID=0
ARG USER=root
ARG GROUP=root
#-------------------------------------------------------------
RUN apt-get update
RUN apt-get install ca-certificates -y
RUN apt-get update && apt-get install -y ca-certificates curl && rm -rf /var/lib/apt/lists/*
#-------------------------------------------------------------
# User Set
RUN if [ "${USER}" != "root" ]; then \
Expand Down
85 changes: 85 additions & 0 deletions config/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package config
import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
"path/filepath"
Expand Down Expand Up @@ -180,3 +181,87 @@ func (fpm *FileProfileManager) LoadCredentialsByProfile(profileName string, prov
return nil, errors.New("unsupported provider")
}
}

// ValidateProfiles checks that at least one profile exists, each profile has at least one credential,
// and that all provided credentials have non-empty required fields.
func (fpm *FileProfileManager) ValidateProfiles() error {
fpm.mu.Lock()
defer fpm.mu.Unlock()

// Open the profile file
file, err := os.Open(fpm.profileFilePath)
if err != nil {
return fmt.Errorf("unable to open profile file: %v", err)
}
defer file.Close()

// Read the file content
data, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("unable to read profile file: %v", err)
}

// Unmarshal JSON data into profiles
var profiles []struct {
ProfileName string `json:"profileName"`
Credentials models.ProfileCredentials `json:"credentials"`
}

if err := json.Unmarshal(data, &profiles); err != nil {
return fmt.Errorf("unable to parse profile JSON: %v", err)
}

// Check if there are any profiles
if len(profiles) == 0 {
return errors.New("no profiles found")
}

// Validate each profile's credentials
for _, profile := range profiles {
if profile.ProfileName == "" {
return errors.New("a profile has an empty name")
}

creds := profile.Credentials

// Flag to check if at least one credential is present
hasAtLeastOneCredential := false

// Validate AWS credentials if present
if creds.AWS.AccessKey != "" || creds.AWS.SecretKey != "" {
hasAtLeastOneCredential = true
if creds.AWS.AccessKey == "" {
return fmt.Errorf("AWS AccessKey for profile '%s' is missing", profile.ProfileName)
}
if creds.AWS.SecretKey == "" {
return fmt.Errorf("AWS SecretKey for profile '%s' is missing", profile.ProfileName)
}
}

// Validate NCP credentials if present
if creds.NCP.AccessKey != "" || creds.NCP.SecretKey != "" {
hasAtLeastOneCredential = true
if creds.NCP.AccessKey == "" {
return fmt.Errorf("NCP AccessKey for profile '%s' is missing", profile.ProfileName)
}
if creds.NCP.SecretKey == "" {
return fmt.Errorf("NCP SecretKey for profile '%s' is missing", profile.ProfileName)
}
}

// Validate GCP credentials if present
if creds.GCP.PrivateKeyID != "" {
hasAtLeastOneCredential = true
if creds.GCP.PrivateKeyID == "" {
return fmt.Errorf("GCP PrivateKeyID for profile '%s' is missing", profile.ProfileName)
}
}

// Ensure that at least one credential is present
if !hasAtLeastOneCredential {
return fmt.Errorf("profile '%s' must have at least one set of credentials (AWS, NCP, or GCP)", profile.ProfileName)
}
}

return nil
}
8 changes: 8 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ services:
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
# Health check configuration
# OK [ 2xx ,3xx}, ERR [4xx,5xx,...etc]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3300/readyZ"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s

##################
## OPTIONAL ##
Expand Down
55 changes: 55 additions & 0 deletions websrc/controllers/healthCheckHandlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright 2023 The Cloud-Barista Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers

import (
"net/http"
"time"

"github.com/cloud-barista/mc-data-manager/config"
"github.com/cloud-barista/mc-data-manager/models"
"github.com/labstack/echo/v4"
)

// GetSystemReadyHandler godoc
//
// @ID GetSystemReadyHandler
// @Summary Get System Ready Handler
// @Description Get System Ready
// @Tags [Ready]
// @Produce json
// @Success 200 {object} models.BasicResponse "System is Ready"
// @Failure 404 {object} models.BasicResponse "Profile Load , Failed: err"
// @Router /readyZ [Get]
func GetSystemReadyHandler(ctx echo.Context) error {
start := time.Now()
logger, logstrings := pageLogInit(ctx, "healthcheck-task", "Ready?", start)
credentailManger := config.NewProfileManager()
err := credentailManger.ValidateProfiles()
if err != nil {
errStr := "Profile Load , Failed : " + err.Error()
logger.Error().Msg(errStr)
return ctx.JSON(http.StatusNotFound, models.BasicResponse{
Result: logstrings.String(),
Error: &errStr,
})
}
jobEnd(logger, "System is Ready", start)
return ctx.JSON(http.StatusOK, models.BasicResponse{
Result: logstrings.String(),
Error: nil,
})
}
2 changes: 1 addition & 1 deletion websrc/controllers/publicfunc.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func pageLogInit(c echo.Context, pageName, pageInfo string, startTime time.Time)
logger := parentLogger.Output(multiWriter)

// Log page access information
logger.Info().Msgf("%s post page accessed", pageName)
logger.Info().Msgf("%s page accessed", pageName)
logger.Info().Msg(pageInfo)
logger.Info().Str("start time", startTime.Format(time.RFC3339))

Expand Down
1 change: 1 addition & 0 deletions websrc/serve/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func InitServer(port string, addIP ...string) *echo.Echo {
e.GET("/swagger/*", echoSwagger.WrapHandler)

e.GET("/", controllers.MainGetHandler)
e.GET("/readyZ", controllers.GetSystemReadyHandler)

migrationGroup := e.Group("/migrate")
routes.MigrationRoutes(migrationGroup)
Expand Down

0 comments on commit de6a76c

Please sign in to comment.