Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
replace logrus and gorilla+negorni with zerolog and gin
Browse files Browse the repository at this point in the history
nilsgstrabo committed Mar 13, 2024
1 parent 5b27dca commit 70c5e1b
Showing 17 changed files with 764 additions and 614 deletions.
25 changes: 11 additions & 14 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build docker image
env:
REF: ${{ github. sha }}
@@ -21,25 +21,22 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
- name: Install dependencies
run: go mod download
- name: Install GolangCI Lint
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.55.2

go-version-file: 'go.mod'
- name: golangci-lint
run: golangci-lint run --timeout=30m --max-same-issues=0 --out-format=github-actions
uses: golangci/golangci-lint-action@v4
with:
version: v1.55.2

test:
name: Unit Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version-file: 'go.mod'
- name: Install dependencies
run: go mod download
- name: Run Tests
@@ -50,9 +47,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version-file: 'go.mod'
- name: Install dependencies
run: go mod download
- name: Install Swagger
15 changes: 15 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
run:
timeout: 30m

linters:
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused
- zerologlint

issues:
max-same-issues: 0
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -17,10 +17,10 @@
"RADIXOPERATOR_CLUSTER_TYPE": "development",
"RADIX_DNS_ZONE":"dev.radix.equinor.com",
"RADIX_CONTAINER_REGISTRY":"radixdev.azurecr.io",
"RADIX_ENVIRONMENT":"qa",
"RADIX_ENVIRONMENT":"dev",
"RADIX_APP":"radix-job-demo",
"RADIX_JOB_SCHEDULERS_PER_ENVIRONMENT_HISTORY_LIMIT": "2",
"RADIX_DEPLOYMENT": "qa-qcd3b-cg6u3hnk",
"RADIX_DEPLOYMENT": "dev-f6dbi-w5quewh2",
"RADIX_COMPONENT": "compute",
"RADIX_PORTS": "8081",
"RADIXOPERATOR_APP_ENV_LIMITS_DEFAULT_CPU": "50m",
15 changes: 15 additions & 0 deletions api/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package api

import (
"github.com/gin-gonic/gin"
)

type Route struct {
Path string
Method string
Handler gin.HandlerFunc
}

type Controller interface {
GetRoutes() []Route
}
12 changes: 5 additions & 7 deletions api/controllers/controller_base.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
package controllers

import (
"net/http"

apiErrors "github.com/equinor/radix-job-scheduler/api/errors"
models "github.com/equinor/radix-job-scheduler/models/common"
"github.com/equinor/radix-job-scheduler/utils"
log "github.com/sirupsen/logrus"
"github.com/gin-gonic/gin"
)

type ControllerBase struct {
}

func (controller *ControllerBase) HandleError(w http.ResponseWriter, err error) {
var status *models.Status
func (controller *ControllerBase) HandleError(c *gin.Context, err error) {
_ = c.Error(err)

var status *models.Status
switch t := err.(type) {
case apiErrors.APIStatus:
status = t.Status()
default:
status = apiErrors.NewFromError(err).Status()
}

log.Errorf("failed: %v", err)
utils.StatusResponse(w, status)
utils.StatusResponse(c.Writer, status)
}
5 changes: 3 additions & 2 deletions api/test/test.go
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ import (

radixUtils "github.com/equinor/radix-common/utils"
"github.com/equinor/radix-common/utils/numbers"
"github.com/equinor/radix-job-scheduler/api"
"github.com/equinor/radix-job-scheduler/models"
modelsv1 "github.com/equinor/radix-job-scheduler/models/v1"
"github.com/equinor/radix-job-scheduler/router"
@@ -35,10 +36,10 @@ import (
)

type ControllerTestUtils struct {
controllers []models.Controller
controllers []api.Controller
}

func New(controllers ...models.Controller) ControllerTestUtils {
func New(controllers ...api.Controller) ControllerTestUtils {
return ControllerTestUtils{
controllers: controllers,
}
24 changes: 15 additions & 9 deletions api/v1/batches/batch_handler.go
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import (
"github.com/equinor/radix-job-scheduler/models/common"
modelsv1 "github.com/equinor/radix-job-scheduler/models/v1"
"github.com/equinor/radix-operator/pkg/apis/kube"
log "github.com/sirupsen/logrus"
"github.com/rs/zerolog/log"
corev1 "k8s.io/api/core/v1"
)

@@ -51,15 +51,16 @@ func New(kube *kube.Kube, env *models.Env) BatchHandler {

// GetBatches Get status of all batches
func (handler *batchHandler) GetBatches(ctx context.Context) ([]modelsv1.BatchStatus, error) {
log.Debugf("Get batches for the namespace: %s", handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("Get batches for the namespace: %s", handler.common.Env.RadixDeploymentNamespace)

radixBatches, err := handler.common.HandlerApiV2.GetRadixBatches(ctx)
if err != nil {
return nil, err
}
radixBatchStatuses := make([]modelsv1.BatchStatus, 0, len(radixBatches))
if len(radixBatches) == 0 {
log.Debugf("No batches found for namespace %s", handler.common.Env.RadixDeploymentNamespace)
logger.Debug().Msgf("No batches found for namespace %s", handler.common.Env.RadixDeploymentNamespace)
return radixBatchStatuses, nil
}

@@ -73,7 +74,7 @@ func (handler *batchHandler) GetBatches(ctx context.Context) ([]modelsv1.BatchSt
setBatchJobEventMessages(radixBatchStatus, batchJobPodsMap, eventMessageForPods)
radixBatchStatuses = append(radixBatchStatuses, *radixBatchStatus)
}
log.Debugf("Found %v batches for namespace %s", len(radixBatchStatuses), handler.common.Env.RadixDeploymentNamespace)
logger.Debug().Msgf("Found %v batches for namespace %s", len(radixBatchStatuses), handler.common.Env.RadixDeploymentNamespace)
return radixBatchStatuses, nil
}

@@ -84,7 +85,8 @@ func (handler *batchHandler) GetBatchJob(ctx context.Context, batchName string,

// GetBatch Get status of a batch
func (handler *batchHandler) GetBatch(ctx context.Context, batchName string) (*modelsv1.BatchStatus, error) {
log.Debugf("get batches for namespace: %s", handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("get batches for namespace: %s", handler.common.Env.RadixDeploymentNamespace)
radixBatch, err := handler.common.HandlerApiV2.GetRadixBatch(ctx, batchName)
if err != nil {
return nil, err
@@ -101,7 +103,8 @@ func (handler *batchHandler) GetBatch(ctx context.Context, batchName string) (*m

// CreateBatch Create a batch with parameters
func (handler *batchHandler) CreateBatch(ctx context.Context, batchScheduleDescription *common.BatchScheduleDescription) (*modelsv1.BatchStatus, error) {
log.Debugf("create batch for namespace: %s", handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("create batch for namespace: %s", handler.common.Env.RadixDeploymentNamespace)
radixBatch, err := handler.common.HandlerApiV2.CreateRadixBatch(ctx, batchScheduleDescription)
if err != nil {
return nil, err
@@ -120,7 +123,8 @@ func (handler *batchHandler) CopyBatch(ctx context.Context, batchName string, de

// DeleteBatch Delete a batch
func (handler *batchHandler) DeleteBatch(ctx context.Context, batchName string) error {
log.Debugf("delete batch %s for namespace: %s", batchName, handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("delete batch %s for namespace: %s", batchName, handler.common.Env.RadixDeploymentNamespace)
err := handler.common.HandlerApiV2.DeleteRadixBatch(ctx, batchName)
if err != nil {
return err
@@ -130,13 +134,15 @@ func (handler *batchHandler) DeleteBatch(ctx context.Context, batchName string)

// StopBatch Stop a batch
func (handler *batchHandler) StopBatch(ctx context.Context, batchName string) error {
log.Debugf("delete batch %s for namespace: %s", batchName, handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("delete batch %s for namespace: %s", batchName, handler.common.Env.RadixDeploymentNamespace)
return handler.common.HandlerApiV2.StopRadixBatch(ctx, batchName)
}

// StopBatchJob Stop a batch job
func (handler *batchHandler) StopBatchJob(ctx context.Context, batchName string, jobName string) error {
log.Debugf("delete the job %s in the batch %s for namespace: %s", jobName, batchName, handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("delete the job %s in the batch %s for namespace: %s", jobName, batchName, handler.common.Env.RadixDeploymentNamespace)
return apiv1.StopJob(ctx, handler.common.HandlerApiV2, jobName)
}

463 changes: 241 additions & 222 deletions api/v1/controllers/batches/controller.go

Large diffs are not rendered by default.

322 changes: 169 additions & 153 deletions api/v1/controllers/jobs/controller.go

Large diffs are not rendered by default.

22 changes: 14 additions & 8 deletions api/v1/jobs/job_handler.go
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import (
modelsv1 "github.com/equinor/radix-job-scheduler/models/v1"
modelsv2 "github.com/equinor/radix-job-scheduler/models/v2"
"github.com/equinor/radix-operator/pkg/apis/kube"
log "github.com/sirupsen/logrus"
"github.com/rs/zerolog/log"
"k8s.io/apimachinery/pkg/api/errors"
)

@@ -50,7 +50,8 @@ func New(kube *kube.Kube, env *models.Env) JobHandler {

// GetJobs Get status of all jobs
func (handler *jobHandler) GetJobs(ctx context.Context) ([]modelsv1.JobStatus, error) {
log.Debugf("Get Jobs for namespace: %s", handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("Get Jobs for namespace: %s", handler.common.Env.RadixDeploymentNamespace)

singleJobRadixBatches, err := handler.common.HandlerApiV2.GetRadixBatchSingleJobs(ctx)
if err != nil {
@@ -77,13 +78,14 @@ func (handler *jobHandler) GetJobs(ctx context.Context) ([]modelsv1.JobStatus, e
apiv1.SetBatchJobEventMessageToBatchJobStatus(&jobStatuses[i], batchJobPodsMap, eventMessageForPods)
}

log.Debugf("Found %v jobs for namespace %s", len(jobStatuses), handler.common.Env.RadixDeploymentNamespace)
logger.Debug().Msgf("Found %v jobs for namespace %s", len(jobStatuses), handler.common.Env.RadixDeploymentNamespace)
return jobStatuses, nil
}

// GetJob Get status of a job
func (handler *jobHandler) GetJob(ctx context.Context, jobName string) (*modelsv1.JobStatus, error) {
log.Debugf("get job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("get job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
if batchName, _, ok := apiv1.ParseBatchAndJobNameFromScheduledJobName(jobName); ok {
jobStatus, err := apiv1.GetBatchJob(ctx, handler.common.HandlerApiV2, batchName, jobName)
if err != nil {
@@ -102,7 +104,8 @@ func (handler *jobHandler) GetJob(ctx context.Context, jobName string) (*modelsv

// CreateJob Create a job with parameters
func (handler *jobHandler) CreateJob(ctx context.Context, jobScheduleDescription *common.JobScheduleDescription) (*modelsv1.JobStatus, error) {
log.Debugf("Create job for namespace: %s", handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("Create job for namespace: %s", handler.common.Env.RadixDeploymentNamespace)
radixBatch, err := handler.common.HandlerApiV2.CreateRadixBatchSingleJob(ctx, jobScheduleDescription)
if err != nil {
return nil, err
@@ -112,7 +115,8 @@ func (handler *jobHandler) CreateJob(ctx context.Context, jobScheduleDescription

// CopyJob Copy a job with deployment and optional parameters
func (handler *jobHandler) CopyJob(ctx context.Context, jobName string, deploymentName string) (*modelsv1.JobStatus, error) {
log.Debugf("stop the job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("stop the job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
radixBatch, err := apiv1.CopyJob(ctx, handler.common.HandlerApiV2, jobName, deploymentName)
if err != nil {
return nil, err
@@ -122,7 +126,8 @@ func (handler *jobHandler) CopyJob(ctx context.Context, jobName string, deployme

// DeleteJob Delete a job
func (handler *jobHandler) DeleteJob(ctx context.Context, jobName string) error {
log.Debugf("delete job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("delete job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
batchName, _, ok := apiv1.ParseBatchAndJobNameFromScheduledJobName(jobName)
if !ok {
return apiErrors.NewInvalidWithReason(jobName, "is not a valid job name")
@@ -161,7 +166,8 @@ func jobExistInBatch(radixBatch *modelsv2.RadixBatch, jobName string) bool {

// StopJob Stop a job
func (handler *jobHandler) StopJob(ctx context.Context, jobName string) error {
log.Debugf("stop the job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
logger := log.Ctx(ctx)
logger.Debug().Msgf("stop the job %s for namespace: %s", jobName, handler.common.Env.RadixDeploymentNamespace)
return apiv1.StopJob(ctx, handler.common.HandlerApiV2, jobName)
}

138 changes: 80 additions & 58 deletions api/v2/handler.go

Large diffs are not rendered by default.

49 changes: 33 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
@@ -6,17 +6,15 @@ toolchain go1.21.0

require (
dario.cat/mergo v1.0.0
github.com/equinor/radix-common v1.7.1
github.com/equinor/radix-operator v1.47.2
github.com/equinor/radix-common v1.9.2
github.com/equinor/radix-operator v1.50.2
github.com/gin-gonic/gin v1.9.1
github.com/go-swagger/go-swagger v0.30.5
github.com/golang/mock v1.6.0
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/prometheus-operator/prometheus-operator/pkg/client v0.70.0
github.com/sirupsen/logrus v1.9.3
github.com/rs/zerolog v1.32.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
github.com/urfave/negroni/v3 v3.0.0
github.com/stretchr/testify v1.9.0
k8s.io/api v0.29.0
k8s.io/apimachinery v0.29.0
k8s.io/client-go v0.29.0
@@ -25,36 +23,54 @@ require (

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cert-manager/cert-manager v1.14.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.22.7 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
@@ -63,15 +79,16 @@ require (
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.29.0 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/kube-openapi v0.0.0-20231129212854-f0671cc7e66a // indirect
k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect
k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 // indirect
k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect
sigs.k8s.io/controller-runtime v0.16.3 // indirect
sigs.k8s.io/gateway-api v1.0.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
123 changes: 83 additions & 40 deletions go.sum

Large diffs are not rendered by default.

67 changes: 39 additions & 28 deletions main.go
Original file line number Diff line number Diff line change
@@ -3,11 +3,14 @@ package main
import (
"context"
"fmt"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"github.com/equinor/radix-job-scheduler/api"
batchApi "github.com/equinor/radix-job-scheduler/api/v1/batches"
batchControllers "github.com/equinor/radix-job-scheduler/api/v1/controllers/batches"
jobControllers "github.com/equinor/radix-job-scheduler/api/v1/controllers/jobs"
@@ -20,78 +23,86 @@ import (
"github.com/equinor/radix-operator/pkg/apis/kube"
radixv1 "github.com/equinor/radix-operator/pkg/apis/radix/v1"
"github.com/equinor/radix-operator/pkg/apis/utils"
"github.com/gorilla/handlers"
log "github.com/sirupsen/logrus"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/pflag"
)

func main() {
env := models.NewEnv()
initLogger(env)

kubeUtil := getKubeUtil()

radixDeployJobComponent, err := radix.GetRadixDeployJobComponentByName(context.Background(), kubeUtil.RadixClient(), env.RadixDeploymentNamespace, env.RadixDeploymentName, env.RadixComponentName)
if err != nil {
log.Fatalln(err)
return
log.Fatal().Err(err).Msg("failed to get job specification")
}

radixBatchWatcher, err := getRadixBatchWatcher(kubeUtil, radixDeployJobComponent, env)
if err != nil {
log.Fatalln(err)
return
log.Fatal().Err(err).Msg("failed to inititialize job watcher")
}
defer close(radixBatchWatcher.Stop)

runApiServer(kubeUtil, env)
}

func initLogger(env *models.Env) {
logLevel, err := zerolog.ParseLevel(env.LogLevel)
if err != nil {
logLevel = zerolog.InfoLevel
}
zerolog.SetGlobalLevel(logLevel)
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.TimeOnly})
zerolog.DefaultContextLogger = &log.Logger
}

func runApiServer(kubeUtil *kube.Kube, env *models.Env) {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()

fs := initializeFlagSet()
var (
port = fs.StringP("port", "p", env.RadixPort, "Port where API will be served")
)
log.Debugf("Port: %s\n", *port)
parseFlagsFromArgs(fs)

errsChan := make(chan error)
go func() {
log.Infof("Radix job scheduler API is serving on port %s", *port)
err := http.ListenAndServe(fmt.Sprintf(":%s", *port), handlers.CombinedLoggingHandler(os.Stdout, router.NewServer(env, getControllers(kubeUtil, env)...)))
errsChan <- err
}()
log.Info().Msgf("Radix job API is serving on port %s", *port)
srv := &http.Server{
Addr: fmt.Sprintf(":%s", *port),
Handler: router.NewServer(env, getControllers(kubeUtil, env)...),
BaseContext: func(_ net.Listener) context.Context { return ctx },
}
if err := srv.ListenAndServe(); err != nil {
log.Fatal().Err(err).Msg("Radix job API server stopped")
}

sigTerm := make(chan os.Signal, 1)
signal.Notify(sigTerm, syscall.SIGTERM)
signal.Notify(sigTerm, syscall.SIGINT)
}()

select {
case <-sigTerm:
case err := <-errsChan:
if err != nil {
log.Fatalf("Radix job scheduler API server crashed: %v", err)
}
}
<-ctx.Done()
}

func getRadixBatchWatcher(kubeUtil *kube.Kube, radixDeployJobComponent *radixv1.RadixDeployJobComponent, env *models.Env) (*notifications.Watcher, error) {
notifier := notifications.NewWebhookNotifier(radixDeployJobComponent)
log.Infof("Created notifier: %s", notifier.String())
log.Info().Msgf("Created notifier: %s", notifier.String())
if !notifier.Enabled() {
log.Infoln("Notifiers are not enabled, RadixBatch event and changes watcher is skipped.")
log.Info().Msg("Notifiers are not enabled, RadixBatch event and changes watcher is skipped.")
return notifications.NullRadixBatchWatcher(), nil
}

return notifications.NewRadixBatchWatcher(kubeUtil.RadixClient(), env.RadixDeploymentNamespace, notifier)
}

func getKubeUtil() *kube.Kube {
kubeClient, radixClient, _, secretProviderClient := utils.GetKubernetesClient()
kubeClient, radixClient, _, secretProviderClient, _ := utils.GetKubernetesClient()
kubeUtil, _ := kube.New(kubeClient, radixClient, secretProviderClient)
return kubeUtil
}

func getControllers(kubeUtil *kube.Kube, env *models.Env) []models.Controller {
return []models.Controller{
func getControllers(kubeUtil *kube.Kube, env *models.Env) []api.Controller {
return []api.Controller{
jobControllers.New(jobApi.New(kubeUtil, env)),
batchControllers.New(batchApi.New(kubeUtil, env)),
}
@@ -116,7 +127,7 @@ func parseFlagsFromArgs(fs *pflag.FlagSet) {
case err == pflag.ErrHelp:
os.Exit(0)
case err != nil:
fmt.Fprintf(os.Stderr, "Error: %s\n\n", err.Error())
log.Error().Err(err).Msg("Failed to parse flags")
fs.Usage()
os.Exit(2)
}
16 changes: 4 additions & 12 deletions models/env.go
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@ import (

"github.com/equinor/radix-operator/pkg/apis/defaults"
"github.com/equinor/radix-operator/pkg/apis/utils"
log "github.com/sirupsen/logrus"
)

// Env instance variables
@@ -19,31 +18,28 @@ type Env struct {
RadixDeploymentNamespace string
RadixJobSchedulersPerEnvironmentHistoryLimit int
RadixPort string
LogLevel string
}

// NewEnv Constructor
func NewEnv() *Env {
switch os.Getenv("LOG_LEVEL") {
case "DEBUG":
log.SetLevel(log.DebugLevel)
default:
log.SetLevel(log.InfoLevel)
}
var (
useSwagger = envVarIsTrueOrYes(os.Getenv("USE_SWAGGER"))
useSwagger, _ = strconv.ParseBool(os.Getenv("USE_SWAGGER"))
radixAppName = strings.TrimSpace(os.Getenv(defaults.RadixAppEnvironmentVariable))
radixEnv = strings.TrimSpace(os.Getenv(defaults.EnvironmentnameEnvironmentVariable))
radixComponentName = strings.TrimSpace(os.Getenv(defaults.RadixComponentEnvironmentVariable))
radixDeployment = strings.TrimSpace(os.Getenv(defaults.RadixDeploymentEnvironmentVariable))
radixJobSchedulersPerEnvironmentHistoryLimit = strings.TrimSpace(os.Getenv("RADIX_JOB_SCHEDULERS_PER_ENVIRONMENT_HISTORY_LIMIT"))
radixPorts = strings.TrimSpace(os.Getenv(defaults.RadixPortsEnvironmentVariable))
logLevel = os.Getenv("LOG_LEVEL")
)
env := Env{
RadixComponentName: radixComponentName,
RadixDeploymentName: radixDeployment,
RadixDeploymentNamespace: utils.GetEnvironmentNamespace(radixAppName, radixEnv),
UseSwagger: useSwagger,
RadixJobSchedulersPerEnvironmentHistoryLimit: 10,
LogLevel: logLevel,
}
setPort(radixPorts, &env)
setHistoryLimit(radixJobSchedulersPerEnvironmentHistoryLimit, &env)
@@ -68,7 +64,3 @@ func setPort(radixPorts string, env *Env) {
}
panic(fmt.Errorf("RADIX_PORTS not set"))
}

func envVarIsTrueOrYes(envVar string) bool {
return strings.EqualFold(envVar, "true") || strings.EqualFold(envVar, "yes")
}
31 changes: 16 additions & 15 deletions models/notifications/radix-batch-watcher.go
Original file line number Diff line number Diff line change
@@ -13,8 +13,9 @@ import (
radixv1 "github.com/equinor/radix-operator/pkg/apis/radix/v1"
radixclient "github.com/equinor/radix-operator/pkg/client/clientset/versioned"
radixinformers "github.com/equinor/radix-operator/pkg/client/informers/externalversions"
"github.com/equinor/radix-operator/pkg/client/informers/externalversions/radix/v1"
log "github.com/sirupsen/logrus"
v1 "github.com/equinor/radix-operator/pkg/client/informers/externalversions/radix/v1"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
)
@@ -23,17 +24,17 @@ const (
resyncPeriod = 0
)

var watcherLogger *log.Entry
var watcherLogger zerolog.Logger

func init() {
watcherLogger = log.WithFields(log.Fields{"radixJobScheduler": "radix-batch-watcher"})
watcherLogger = log.Logger.With().Str("radixJobScheduler", "radix-batch-watcher").Logger()
}

type Watcher struct {
radixInformerFactory radixinformers.SharedInformerFactory
batchInformer v1.RadixBatchInformer
Stop chan struct{}
logger *log.Entry
logger *zerolog.Logger
}

// NullRadixBatchWatcher The void watcher
@@ -48,7 +49,7 @@ func NewRadixBatchWatcher(radixClient radixclient.Interface, namespace string, n
watcher := Watcher{
Stop: make(chan struct{}),
radixInformerFactory: radixinformers.NewSharedInformerFactoryWithOptions(radixClient, resyncPeriod, radixinformers.WithNamespace(namespace)),
logger: watcherLogger,
logger: &watcherLogger,
}

existingRadixBatchMap, err := getRadixBatchMap(radixClient, namespace)
@@ -58,16 +59,16 @@ func NewRadixBatchWatcher(radixClient radixclient.Interface, namespace string, n

watcher.batchInformer = watcher.radixInformerFactory.Radix().V1().RadixBatches()

watcher.logger.Info("Setting up event handlers")
watcher.logger.Info().Msg("Setting up event handlers")
errChan := make(chan error)
_, err = watcher.batchInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(cur interface{}) {
newRadixBatch := cur.(*radixv1.RadixBatch)
if _, ok := existingRadixBatchMap[newRadixBatch.GetName()]; ok {
watcher.logger.Debugf("skip existing RadixBatch object %s", newRadixBatch.GetName())
watcher.logger.Debug().Msgf("skip existing RadixBatch object %s", newRadixBatch.GetName())
return
}
watcher.logger.Debugf("RadixBatch object was added %s", newRadixBatch.GetName())
watcher.logger.Debug().Msgf("RadixBatch object was added %s", newRadixBatch.GetName())
jobStatuses := newRadixBatch.Status.JobStatuses
if len(jobStatuses) == 0 {
jobStatuses = make([]radixv1.RadixBatchJobStatus, 0)
@@ -79,20 +80,20 @@ func NewRadixBatchWatcher(radixClient radixclient.Interface, namespace string, n
newRadixBatch := cur.(*radixv1.RadixBatch)
updatedJobStatuses := getUpdatedJobStatuses(oldRadixBatch, newRadixBatch)
if len(updatedJobStatuses) == 0 && equalBatchStatuses(&oldRadixBatch.Status, &newRadixBatch.Status) {
watcher.logger.Debugf("RadixBatch status and job statuses have no changes in the batch %s. Do nothing", newRadixBatch.GetName())
watcher.logger.Debug().Msgf("RadixBatch status and job statuses have no changes in the batch %s. Do nothing", newRadixBatch.GetName())
return
}
watcher.logger.Debugf("RadixBatch object was changed %s", newRadixBatch.GetName())
watcher.logger.Debug().Msgf("RadixBatch object was changed %s", newRadixBatch.GetName())
notifier.Notify(events.Update, newRadixBatch, updatedJobStatuses, errChan)
},
DeleteFunc: func(obj interface{}) {
radixBatch, _ := obj.(*radixv1.RadixBatch)
key, err := cache.MetaNamespaceKeyFunc(radixBatch)
if err != nil {
watcher.logger.Errorf("fail on received event deleted RadixBatch object %s: %v", key, err)
watcher.logger.Error().Err(err).Msgf("fail on received event deleted RadixBatch object %s", key)
return
}
watcher.logger.Debugf("RadixBatch object was deleted %s", radixBatch.GetName())
watcher.logger.Debug().Msgf("RadixBatch object was deleted %s", radixBatch.GetName())
jobStatuses := radixBatch.Status.JobStatuses
if len(jobStatuses) == 0 {
jobStatuses = make([]radixv1.RadixBatchJobStatus, 0)
@@ -102,7 +103,7 @@ func NewRadixBatchWatcher(radixClient radixclient.Interface, namespace string, n
},
})
if err != nil {
watcher.logger.Error(err)
watcher.logger.Error().Err(err).Msg("Failed to setup job informer")
return nil, err
}

@@ -112,7 +113,7 @@ func NewRadixBatchWatcher(radixClient radixclient.Interface, namespace string, n
for {
select {
case err := <-errChan:
watcher.logger.Error(err)
watcher.logger.Error().Err(err).Msg("Notification failed")
case <-watcher.Stop:
return
}
47 changes: 19 additions & 28 deletions router/server.go
Original file line number Diff line number Diff line change
@@ -3,11 +3,11 @@ package router
import (
"net/http"

commongin "github.com/equinor/radix-common/pkg/gin"
"github.com/equinor/radix-job-scheduler/api"
"github.com/equinor/radix-job-scheduler/models"
"github.com/equinor/radix-job-scheduler/swaggerui"
"github.com/equinor/radix-job-scheduler/utils"
"github.com/gorilla/mux"
"github.com/urfave/negroni/v3"
"github.com/gin-gonic/gin"
)

const (
@@ -16,46 +16,37 @@ const (
)

// NewServer creates a new Radix job scheduler REST service
func NewServer(env *models.Env, controllers ...models.Controller) http.Handler {
router := mux.NewRouter().StrictSlash(true)
func NewServer(env *models.Env, controllers ...api.Controller) http.Handler {
gin.SetMode(gin.ReleaseMode)
engine := gin.New()
engine.RemoveExtraSlash = true
engine.Use(commongin.ZerologRequestLogger(), gin.Recovery())

if env.UseSwagger {
initializeSwaggerUI(router)
initializeSwaggerUI(engine)
}

initializeAPIServer(router, controllers)

serveMux := http.NewServeMux()
serveMux.Handle(apiVersionRoute+"/", router)

if env.UseSwagger {
serveMux.Handle(swaggerUIPath+"/", negroni.New(negroni.Wrap(router)))
v1Router := engine.Group(apiVersionRoute)
{
initializeAPIServer(v1Router, controllers)
}

recovery := negroni.NewRecovery()
recovery.PrintStack = false

n := negroni.New(recovery)
n.UseHandler(serveMux)
return n
return engine
}

func initializeSwaggerUI(router *mux.Router) {
swaggerFsHandler := http.FileServer(http.FS(swaggerui.FS()))
swaggerui := http.StripPrefix(swaggerUIPath, swaggerFsHandler)
router.PathPrefix(swaggerUIPath).Handler(swaggerui)
func initializeSwaggerUI(engine *gin.Engine) {
swaggerFsHandler := http.FS(swaggerui.FS())
engine.StaticFS(swaggerUIPath, swaggerFsHandler)
}

func initializeAPIServer(router *mux.Router, controllers []models.Controller) {
func initializeAPIServer(router gin.IRoutes, controllers []api.Controller) {
for _, controller := range controllers {
for _, route := range controller.GetRoutes() {
addHandlerRoute(router, route)
}
}
}

func addHandlerRoute(router *mux.Router, route models.Route) {
path := apiVersionRoute + route.Path
router.HandleFunc(path,
utils.NewRadixMiddleware(path, route.Method, route.HandlerFunc).Handle).Methods(route.Method)
func addHandlerRoute(router gin.IRoutes, route api.Route) {
router.Handle(route.Method, route.Path, route.Handler)
}

0 comments on commit 70c5e1b

Please sign in to comment.