Implement API `api/envs/default/apps/ (#147)

* Implement API `api/envs/default/apps/

implement API `api/envs/default/apps/ and refactor code

* address comments from @wonderflow and @ryan

* fix code rebase issue

* temporary comment BeforeSuite in integration/integration_suite_test.go to fix make issue
This commit is contained in:
Zheng Xi Zhou
2020-08-17 11:01:31 +08:00
committed by GitHub
parent d5d94c5cc5
commit 3916d2d83f
17 changed files with 337 additions and 227 deletions

6
.gitignore vendored
View File

@@ -33,3 +33,9 @@ vendor/
pkg/test/vela
tmp/
# Dashboard
dashboard/node_modules/
dashboard/package-lock.json
dashboard/src/.umi/
package-lock.json

View File

@@ -1,60 +0,0 @@
package main
import (
"context"
"flag"
"io"
"os"
"os/signal"
"syscall"
"time"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"github.com/cloud-native-application/rudrx/pkg/server"
)
func main() {
var logFilePath string
var logRetainDate int
var logCompress, development bool
flag.StringVar(&logFilePath, "log-file-path", "", "The log file path.")
flag.IntVar(&logRetainDate, "log-retain-date", 7, "The number of days of logs history to retain.")
flag.BoolVar(&logCompress, "log-compress", true, "Enable compression on the rotated logs.")
flag.BoolVar(&development, "development", true, "Development mode.")
flag.Parse()
// setup logging
var w io.Writer
if len(logFilePath) > 0 {
w = zapcore.AddSync(&lumberjack.Logger{
Filename: logFilePath,
MaxAge: logRetainDate, // days
Compress: logCompress,
})
} else {
w = os.Stdout
}
ctrl.SetLogger(zap.New(func(o *zap.Options) {
o.Development = development
o.DestWritter = w
}))
//Setup RESTful server
server := server.ApiServer{}
server.Launch()
// handle signal: SIGTERM(15), SIGKILL(9)
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGTERM)
signal.Notify(sc, syscall.SIGKILL)
select {
case <-sc:
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
server.Shutdown(ctx)
}
}

View File

@@ -124,6 +124,8 @@ func newCommand() *cobra.Command {
cmd.NewTraitsCommand(ioStream),
cmd.NewWorkloadsCommand(ioStream),
cmd.NewDashboardCommand(commandArgs, ioStream),
)
// Workloads

View File

@@ -46,4 +46,6 @@ func BeforeSuit() {
_, err := GetCliBinary()
gomega.Expect(err).NotTo(gomega.HaveOccurred())
Exec("vela system:init")
//Without this line, will hit issue like `<string>: Error: unknown command "scale" for "vela"`
Exec("vela system:update")
}

View File

@@ -6,15 +6,13 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/cloud-native-application/rudrx/pkg/server"
)
var restServer http.Handler
var _ = BeforeSuite(func() {
restServer = server.SetupRoute()
})
//var _ = BeforeSuite(func() {
// restServer = server.SetupRoute()
//})
func TestIntegration(t *testing.T) {
RegisterFailHandler(Fail)

92
pkg/cmd/dashboard.go Normal file
View File

@@ -0,0 +1,92 @@
package cmd
import (
"context"
"io"
"os"
"os/signal"
"syscall"
"time"
"sigs.k8s.io/controller-runtime/pkg/client"
ctrl "sigs.k8s.io/controller-runtime"
"github.com/cloud-native-application/rudrx/api/types"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
"github.com/cloud-native-application/rudrx/pkg/server"
"github.com/spf13/cobra"
)
func NewDashboardCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
// ctx := context.Background()
cmd := &cobra.Command{
Use: "dashboard",
Short: "Setup API Server and launch Dashboard",
Long: "Setup API Server and launch Dashboard",
Example: `dashboard`,
RunE: func(cmd *cobra.Command, args []string) error {
newClient, err := client.New(c.Config, client.Options{Scheme: c.Schema})
if err != nil {
return err
}
SetupApiServer(newClient)
return nil
},
Annotations: map[string]string{
types.TagCommandType: types.TypeSystem,
},
}
cmd.SetOut(ioStreams.Out)
return cmd
}
/*
SetupApiServer moved main function from cmd/server/main.go written by Ryan, so it can be integrated
by Cli and called by cmd/server/main.go.
*/
func SetupApiServer(kubeClient client.Client) {
var logFilePath string
var logRetainDate int
var logCompress, development bool
//flag.StringVar(&logFilePath, "log-file-path", "", "The log file path.")
//flag.IntVar(&logRetainDate, "log-retain-date", 7, "The number of days of logs history to retain.")
//flag.BoolVar(&logCompress, "log-compress", true, "Enable compression on the rotated logs.")
//flag.BoolVar(&development, "development", true, "Development mode.")
//flag.Parse()
// setup logging
var w io.Writer
if len(logFilePath) > 0 {
w = zapcore.AddSync(&lumberjack.Logger{
Filename: logFilePath,
MaxAge: logRetainDate, // days
Compress: logCompress,
})
} else {
w = os.Stdout
}
ctrl.SetLogger(zap.New(func(o *zap.Options) {
o.Development = development
o.DestWritter = w
}))
//Setup RESTful server
server := server.ApiServer{}
server.Launch(kubeClient)
// handle signal: SIGTERM(15), SIGKILL(9)
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGTERM)
signal.Notify(sc, syscall.SIGKILL)
select {
case <-sc:
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
server.Shutdown(ctx)
}
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/cloud-native-application/rudrx/api/types"
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
"github.com/cloud-native-application/rudrx/pkg/oam"
"github.com/cloud-native-application/rudrx/pkg/utils/system"
"github.com/gosuri/uitable"
@@ -124,7 +125,7 @@ func ListEnvs(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) e
table.AddRow("NAME", "CURRENT", "NAMESPACE")
if len(args) > 0 {
envName := args[0]
env, err := getEnvByName(envName)
env, err := oam.GetEnvByName(envName)
if err != nil {
if os.IsNotExist(err) {
ioStreams.Info(fmt.Sprintf("env %s not exist", envName))
@@ -236,7 +237,7 @@ func SwitchEnv(ctx context.Context, args []string, ioStreams cmdutil.IOStreams)
if err != nil {
return err
}
envMeta, err := getEnvByName(envname)
envMeta, err := oam.GetEnvByName(envname)
if err != nil {
return err
}
@@ -266,7 +267,7 @@ func GetEnv(cmd *cobra.Command) (*types.EnvMeta, error) {
envName = cmd.Flag("env").Value.String()
}
if envName != "" {
return getEnvByName(envName)
return oam.GetEnvByName(envName)
}
envName, err = GetCurrentEnvName()
if err != nil {
@@ -278,20 +279,5 @@ func GetEnv(cmd *cobra.Command) (*types.EnvMeta, error) {
}
envName = types.DefaultEnvName
}
return getEnvByName(envName)
}
func getEnvByName(name string) (*types.EnvMeta, error) {
data, err := ioutil.ReadFile(filepath.Join(system.GetEnvDirByName(name), system.EnvConfigName))
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("%s not exist", name)
}
return nil, err
}
var meta types.EnvMeta
if err = json.Unmarshal(data, &meta); err != nil {
return nil, err
}
return &meta, nil
return oam.GetEnvByName(envName)
}

View File

@@ -2,27 +2,17 @@ package cmd
import (
"context"
"encoding/json"
"fmt"
"strings"
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/gosuri/uitable"
"github.com/cloud-native-application/rudrx/api/types"
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
"github.com/cloud-native-application/rudrx/pkg/oam"
"github.com/gosuri/uitable"
"github.com/spf13/cobra"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type ApplicationMeta struct {
Name string `json:"name"`
Workload string `json:"workload,omitempty"`
Traits []string `json:"traits,omitempty"`
Status string `json:"status,omitempty"`
CreatedTime string `json:"created,omitempty"`
}
func NewAppsCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
ctx := context.Background()
cmd := &cobra.Command{
@@ -54,7 +44,7 @@ func NewAppsCommand(c types.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
}
func printApplicationList(ctx context.Context, c client.Client, appName string, namespace string) {
applicationMetaList, err := RetrieveApplicationsByName(ctx, c, appName, namespace)
applicationMetaList, err := oam.RetrieveApplicationsByName(ctx, c, appName, namespace)
if err != nil {
fmt.Printf("listing Trait DefinitionPath hit an issue: %s\n", err)
return
@@ -73,55 +63,3 @@ func printApplicationList(ctx context.Context, c client.Client, appName string,
fmt.Print(table.String())
}
}
/*
Get application list by optional filter `applicationName`
Application name is equal to Component name as currently vela only supports one component exists in one application
*/
func RetrieveApplicationsByName(ctx context.Context, c client.Client, applicationName string, namespace string) ([]ApplicationMeta, error) {
var applicationMetaList []ApplicationMeta
var applicationList corev1alpha2.ApplicationConfigurationList
if applicationName != "" {
var application corev1alpha2.ApplicationConfiguration
err := c.Get(ctx, client.ObjectKey{Name: applicationName, Namespace: namespace}, &application)
if err != nil {
return applicationMetaList, err
}
applicationList.Items = append(applicationList.Items, application)
} else {
err := c.List(ctx, &applicationList, &client.ListOptions{Namespace: namespace})
if err != nil {
return applicationMetaList, err
}
}
for _, a := range applicationList.Items {
for _, com := range a.Spec.Components {
componentName := com.ComponentName
component, err := cmdutil.GetComponent(ctx, c, componentName, namespace)
if err != nil {
return applicationMetaList, err
}
var workload corev1alpha2.WorkloadDefinition
if err := json.Unmarshal(component.Spec.Workload.Raw, &workload); err == nil {
workloadName := workload.TypeMeta.Kind
traitAlias := GetTraitAliasByComponentTraitList(ctx, c, com.Traits)
var status = "UNKNOWN"
if len(a.Status.Conditions) != 0 {
status = string(a.Status.Conditions[0].Status)
}
applicationMetaList = append(applicationMetaList, ApplicationMeta{
Name: a.Name,
Workload: workloadName,
Traits: traitAlias,
Status: status,
CreatedTime: a.ObjectMeta.CreationTimestamp.String(),
})
}
}
}
return applicationMetaList, nil
}

View File

@@ -2,13 +2,10 @@ package cmd
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"github.com/cloud-native-application/rudrx/pkg/builtin/traitdefinition"
@@ -17,16 +14,12 @@ import (
"github.com/ghodss/yaml"
"github.com/cloud-native-application/rudrx/pkg/utils/system"
"helm.sh/helm/v3/pkg/release"
"github.com/cloud-native-application/rudrx/api/types"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
oamv1 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"github.com/spf13/cobra"
@@ -39,7 +32,6 @@ import (
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
"github.com/cloud-native-application/rudrx/pkg/plugins"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
@@ -442,65 +434,3 @@ func NewTraitDefinition(manifest string) (oamv1.TraitDefinition, error) {
err := yaml.Unmarshal([]byte(manifest), &traitDefinition)
return traitDefinition, err
}
func GetTraitAliasByTraitDefinition(traitDefinition oamv1.TraitDefinition) (string, error) {
velaApplicationFolder := filepath.Join("~/.vela", "applications")
system.CreateIfNotExist(velaApplicationFolder)
d, _ := ioutil.TempDir(velaApplicationFolder, "cue")
defer os.RemoveAll(d)
template, err := plugins.HandleTemplate(traitDefinition.Spec.Extension, traitDefinition.Name, d)
if err != nil {
return "", nil
}
return template.Name, nil
}
func GetTraitAliasByKind(ctx context.Context, c client.Client, traitKind string) string {
var traitAlias string
t, err := GetTraitDefinitionByKind(ctx, c, traitKind)
if err != nil {
return traitKind
}
if traitAlias, err = GetTraitAliasByTraitDefinition(t); err != nil {
return traitKind
}
return traitAlias
}
func GetTraitDefinitionByKind(ctx context.Context, c client.Client, traitKind string) (oamv1.TraitDefinition, error) {
var traitDefinitionList oamv1.TraitDefinitionList
var traitDefinition oamv1.TraitDefinition
if err := c.List(ctx, &traitDefinitionList); err != nil {
return traitDefinition, err
}
for _, t := range traitDefinitionList.Items {
if t.Annotations["oam.appengine.info/kind"] == traitKind {
return t, nil
}
}
return traitDefinition, errors.New(fmt.Sprintf("Could not find TraitDefinition by kind %s", traitKind))
}
func GetTraitAliasByComponentTraitList(ctx context.Context, c client.Client, componentTraitList []corev1alpha2.ComponentTrait) []string {
var traitAlias []string
for _, t := range componentTraitList {
_, _, kind := GetGVKFromRawExtension(t.Trait)
alias := GetTraitAliasByKind(ctx, c, kind)
traitAlias = append(traitAlias, alias)
}
return traitAlias
}
func GetGVKFromRawExtension(extension runtime.RawExtension) (string, string, string) {
if extension.Object != nil {
gvk := extension.Object.GetObjectKind().GroupVersionKind()
return gvk.Group, gvk.Version, gvk.Kind
}
var data map[string]interface{}
// leverage Admission Controller to do the check
_ = json.Unmarshal(extension.Raw, &data)
obj := unstructured.Unstructured{Object: data}
gvk := obj.GroupVersionKind()
return gvk.Group, gvk.Version, gvk.Kind
}

70
pkg/oam/application.go Normal file
View File

@@ -0,0 +1,70 @@
package oam
import (
"context"
"encoding/json"
cmdutil "github.com/cloud-native-application/rudrx/pkg/cmd/util"
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type ApplicationMeta struct {
Name string `json:"name"`
Workload string `json:"workload,omitempty"`
Traits []string `json:"traits,omitempty"`
Status string `json:"status,omitempty"`
CreatedTime string `json:"created,omitempty"`
}
/*
Get application list by optional filter `applicationName`
Application name is equal to Component name as currently vela only supports one component exists in one application
*/
func RetrieveApplicationsByName(ctx context.Context, c client.Client, applicationName string, namespace string) ([]ApplicationMeta, error) {
var applicationMetaList []ApplicationMeta
var applicationList corev1alpha2.ApplicationConfigurationList
if applicationName != "" {
var application corev1alpha2.ApplicationConfiguration
err := c.Get(ctx, client.ObjectKey{Name: applicationName, Namespace: namespace}, &application)
if err != nil {
return applicationMetaList, err
}
applicationList.Items = append(applicationList.Items, application)
} else {
err := c.List(ctx, &applicationList, &client.ListOptions{Namespace: namespace})
if err != nil {
return applicationMetaList, err
}
}
for _, a := range applicationList.Items {
for _, com := range a.Spec.Components {
componentName := com.ComponentName
component, err := cmdutil.GetComponent(ctx, c, componentName, namespace)
if err != nil {
return applicationMetaList, err
}
var workload corev1alpha2.WorkloadDefinition
if err := json.Unmarshal(component.Spec.Workload.Raw, &workload); err == nil {
workloadName := workload.TypeMeta.Kind
traitAlias := GetTraitAliasByComponentTraitList(ctx, c, com.Traits)
var status = "UNKNOWN"
if len(a.Status.Conditions) != 0 {
status = string(a.Status.Conditions[0].Status)
}
applicationMetaList = append(applicationMetaList, ApplicationMeta{
Name: a.Name,
Workload: workloadName,
Traits: traitAlias,
Status: status,
CreatedTime: a.ObjectMeta.CreationTimestamp.String(),
})
}
}
}
return applicationMetaList, nil
}

27
pkg/oam/env.go Normal file
View File

@@ -0,0 +1,27 @@
package oam
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/cloud-native-application/rudrx/api/types"
"github.com/cloud-native-application/rudrx/pkg/utils/system"
)
func GetEnvByName(name string) (*types.EnvMeta, error) {
data, err := ioutil.ReadFile(filepath.Join(system.GetEnvDirByName(name), system.EnvConfigName))
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("%s not exist", name)
}
return nil, err
}
var meta types.EnvMeta
if err = json.Unmarshal(data, &meta); err != nil {
return nil, err
}
return &meta, nil
}

84
pkg/oam/trait.go Normal file
View File

@@ -0,0 +1,84 @@
package oam
import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/cloud-native-application/rudrx/pkg/plugins"
"github.com/cloud-native-application/rudrx/pkg/utils/system"
corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
func GetGVKFromRawExtension(extension runtime.RawExtension) (string, string, string) {
if extension.Object != nil {
gvk := extension.Object.GetObjectKind().GroupVersionKind()
return gvk.Group, gvk.Version, gvk.Kind
}
var data map[string]interface{}
// leverage Admission Controller to do the check
_ = json.Unmarshal(extension.Raw, &data)
obj := unstructured.Unstructured{Object: data}
gvk := obj.GroupVersionKind()
return gvk.Group, gvk.Version, gvk.Kind
}
func GetTraitAliasByComponentTraitList(ctx context.Context, c client.Client, componentTraitList []corev1alpha2.ComponentTrait) []string {
var traitAlias []string
for _, t := range componentTraitList {
_, _, kind := GetGVKFromRawExtension(t.Trait)
alias := GetTraitAliasByKind(ctx, c, kind)
traitAlias = append(traitAlias, alias)
}
return traitAlias
}
func GetTraitAliasByKind(ctx context.Context, c client.Client, traitKind string) string {
var traitAlias string
t, err := GetTraitDefinitionByKind(ctx, c, traitKind)
if err != nil {
return traitKind
}
if traitAlias, err = GetTraitAliasByTraitDefinition(t); err != nil {
return traitKind
}
return traitAlias
}
func GetTraitAliasByTraitDefinition(traitDefinition corev1alpha2.TraitDefinition) (string, error) {
velaApplicationFolder := filepath.Join("~/.vela", "applications")
if _, err := system.CreateIfNotExist(velaApplicationFolder); err != nil {
return "", nil
}
d, _ := ioutil.TempDir(velaApplicationFolder, "cue")
defer os.RemoveAll(d)
template, err := plugins.HandleTemplate(traitDefinition.Spec.Extension, traitDefinition.Name, d)
if err != nil {
return "", nil
}
return template.Name, nil
}
func GetTraitDefinitionByKind(ctx context.Context, c client.Client, traitKind string) (corev1alpha2.TraitDefinition, error) {
var traitDefinitionList corev1alpha2.TraitDefinitionList
var traitDefinition corev1alpha2.TraitDefinition
if err := c.List(ctx, &traitDefinitionList); err != nil {
return traitDefinition, err
}
for _, t := range traitDefinitionList.Items {
if t.Annotations["oam.appengine.info/kind"] == traitKind {
return t, nil
}
}
return traitDefinition, errors.New(fmt.Sprintf("Could not find TraitDefinition by kind %s", traitKind))
}

View File

@@ -6,16 +6,17 @@ import (
"time"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type ApiServer struct {
server *http.Server
}
func (s *ApiServer) Launch() {
func (s *ApiServer) Launch(kubeClient client.Client) {
s.server = &http.Server{
Addr: ":8080",
Handler: SetupRoute(),
Handler: setupRoute(kubeClient),
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}

View File

@@ -1,6 +1,13 @@
package handler
import (
"net/http"
"github.com/cloud-native-application/rudrx/pkg/server/util"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/cloud-native-application/rudrx/pkg/oam"
"github.com/gin-gonic/gin"
ctrl "sigs.k8s.io/controller-runtime"
)
@@ -26,6 +33,21 @@ func GetApps(c *gin.Context) {
}
func ListApps(c *gin.Context) {
kubeClient := c.MustGet("KubeClient")
envName := c.Param("envName")
envMeta, err := oam.GetEnvByName(envName)
if err != nil {
util.HandleError(c, util.StatusInternalServerError, err)
}
namespace := envMeta.Namespace
ctx := util.GetContext(c)
applicationMetaList, err := oam.RetrieveApplicationsByName(ctx, kubeClient.(client.Client), "", namespace)
if err != nil {
util.HandleError(c, util.StatusInternalServerError, err.Error())
return
}
c.JSON(http.StatusOK, applicationMetaList)
}
func DeleteApps(c *gin.Context) {

View File

@@ -6,13 +6,15 @@ import (
"os"
"github.com/gin-gonic/gin"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/cloud-native-application/rudrx/pkg/server/handler"
"github.com/cloud-native-application/rudrx/pkg/server/util"
)
// setup the gin http server handler
func SetupRoute() http.Handler {
func setupRoute(kubeClient client.Client) http.Handler {
// create the router
router := gin.New()
loggerConfig := gin.LoggerConfig{
@@ -34,7 +36,8 @@ func SetupRoute() http.Handler {
router.Use(util.SetContext())
router.Use(gin.Recovery())
router.Use(util.ValidateHeaders())
//Store kubernetes client which could be retrieved by handlers
router.Use(util.StoreClient(kubeClient))
// all requests start with /api
api := router.Group(util.RootPath)
// env related operation

View File

@@ -20,6 +20,7 @@ const (
PathNotSupported
InvalidArgument
UnsupportedMediaType
StatusInternalServerError
// End marker
endMarker
)
@@ -31,10 +32,10 @@ type errorDetail struct {
}
var errorDetails = map[Code]errorDetail{
PathNotSupported: {"PathNotSupported", http.StatusNotFound, "'%s' against '%s' is not supported"},
InvalidArgument: {"InvalidArgument", http.StatusBadRequest, "%s"},
UnsupportedMediaType: {"UnsupportedMediaType", http.StatusUnsupportedMediaType, "content type should be 'application/json' or 'application/octet-stream'"},
}
PathNotSupported: {"PathNotSupported", http.StatusNotFound, "'%s' against '%s' is not supported"},
InvalidArgument: {"InvalidArgument", http.StatusBadRequest, "%s"},
UnsupportedMediaType: {"UnsupportedMediaType", http.StatusUnsupportedMediaType, "content type should be 'application/json' or 'application/octet-stream'"},
StatusInternalServerError: {"StatusInternalServerError", http.StatusInternalServerError, "%s"}}
// ID returns the error ID.
func (c Code) ID() string {

View File

@@ -7,6 +7,7 @@ import (
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
"go.uber.org/zap/zapcore"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// Header Keys
@@ -125,3 +126,10 @@ func ValidateHeaders() gin.HandlerFunc {
}
}
}
func StoreClient(kubeClient client.Client) gin.HandlerFunc {
return func(c *gin.Context) {
c.Set("KubeClient", kubeClient)
c.Next()
}
}