cloudfoundry/cf-k8s-controllers

View on GitHub
api/middleware/cli_version.go

Summary

Maintainability
A
0 mins
Test Coverage
package middleware

import (
    "fmt"
    "net/http"

    apierrors "code.cloudfoundry.org/korifi/api/errors"
    "code.cloudfoundry.org/korifi/api/routing"
    "github.com/Masterminds/semver"
    "github.com/go-logr/logr"
    "github.com/mileusna/useragent"
)

const minSupportedVersion = ">= 8.5.0-0"

func CFCliVersion(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        logger := logr.FromContextOrDiscard(r.Context()).WithName("cf-cli-version-check")
        userAgents := r.Header["User-Agent"]
        if len(userAgents) == 0 {
            next.ServeHTTP(w, r)
            return
        }

        userAgent := useragent.Parse(userAgents[0])
        if userAgent.Name != "cf" {
            next.ServeHTTP(w, r)
            return
        }

        cfCLIVersion, err := semver.NewVersion(userAgent.Version)
        if err != nil {
            routing.PresentError(logger, w, apierrors.NewInvalidRequestError(
                err,
                fmt.Sprintf("Failed to determine CF CLI version. Korifi requires CF CLI %s", minSupportedVersion),
            ))
            return
        }

        if !versionConstraint(logger).Check(cfCLIVersion) {
            routing.PresentError(logger, w, apierrors.NewInvalidRequestError(
                err,
                fmt.Sprintf("CF CLI version %s is not supported. Korifi requires CF CLI %s", cfCLIVersion, minSupportedVersion),
            ))
            return

        }

        next.ServeHTTP(w, r)
    })
}

func versionConstraint(logger logr.Logger) *semver.Constraints {
    versionConstraint, err := semver.NewConstraint(minSupportedVersion)
    if err != nil {
        logger.Error(err, "failed to convert minSupportedVersion to version constraint", "minSupportedVersion", minSupportedVersion)
        return &semver.Constraints{}
    }
    return versionConstraint
}