cloudfoundry/cf-k8s-controllers

View on GitHub
api/handlers/log_cache.go

Summary

Maintainability
A
0 mins
Test Coverage
package handlers

import (
    "context"
    "net/http"

    "code.cloudfoundry.org/korifi/api/authorization"
    apierrors "code.cloudfoundry.org/korifi/api/errors"
    "code.cloudfoundry.org/korifi/api/payloads"
    "code.cloudfoundry.org/korifi/api/presenter"
    "code.cloudfoundry.org/korifi/api/repositories"
    "code.cloudfoundry.org/korifi/api/routing"

    "github.com/go-logr/logr"
)

const (
    LogCacheInfoPath = "/api/v1/info"
    LogCacheReadPath = "/api/v1/read/{guid}"
    logCacheVersion  = "2.11.4+cf-k8s"
)

//counterfeiter:generate -o fake -fake-name AppLogsReader . AppLogsReader
type AppLogsReader interface {
    Read(ctx context.Context, logger logr.Logger, authInfo authorization.Info, appGUID string, read payloads.LogRead) ([]repositories.LogRecord, error)
}

// LogCache implements the minimal set of log-cache API endpoints/features necessary
// to support the "cf push" workfloh.handlerWrapper.
type LogCache struct {
    appRepo          CFAppRepository
    buildRepo        CFBuildRepository
    appLogsReader    AppLogsReader
    requestValidator RequestValidator
}

func NewLogCache(
    appRepo CFAppRepository,
    buildRepository CFBuildRepository,
    appLogsReader AppLogsReader,
    requestValidator RequestValidator,
) *LogCache {
    return &LogCache{
        appRepo:          appRepo,
        buildRepo:        buildRepository,
        appLogsReader:    appLogsReader,
        requestValidator: requestValidator,
    }
}

func (h *LogCache) info(r *http.Request) (*routing.Response, error) {
    return routing.NewResponse(http.StatusOK).WithBody(map[string]interface{}{
        "version":   logCacheVersion,
        "vm_uptime": "0",
    }), nil
}

func (h *LogCache) read(r *http.Request) (*routing.Response, error) {
    authInfo, _ := authorization.InfoFromContext(r.Context())
    logger := logr.FromContextOrDiscard(r.Context()).WithName("handlers.log-cache.read")

    payload := new(payloads.LogRead)
    if err := h.requestValidator.DecodeAndValidateURLValues(r, payload); err != nil {
        return nil, apierrors.LogAndReturn(logger, err, "failed to decode payload")
    }

    appGUID := routing.URLParam(r, "guid")

    logs, err := h.appLogsReader.Read(r.Context(), logger, authInfo, appGUID, *payload)
    if err != nil {
        return nil, apierrors.LogAndReturn(logger, err, "failed to read app logs", "appGUID", appGUID)
    }

    return routing.NewResponse(http.StatusOK).WithBody(presenter.ForLogs(logs)), nil
}

func (h *LogCache) UnauthenticatedRoutes() []routing.Route {
    return []routing.Route{
        {Method: "GET", Pattern: LogCacheInfoPath, Handler: h.info},
    }
}

func (h *LogCache) AuthenticatedRoutes() []routing.Route {
    return []routing.Route{
        {Method: "GET", Pattern: LogCacheReadPath, Handler: h.read},
    }
}