mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
Libraries for the equivalent of ks show env and kubectl get all -l mylabel=val
This commit is contained in:
parent
af83297c83
commit
3082409330
12 changed files with 99339 additions and 16 deletions
33
Gopkg.lock
generated
33
Gopkg.lock
generated
|
|
@ -579,36 +579,67 @@
|
|||
packages = [
|
||||
"discovery",
|
||||
"discovery/fake",
|
||||
"dynamic",
|
||||
"dynamic/fake",
|
||||
"kubernetes",
|
||||
"kubernetes/fake",
|
||||
"kubernetes/scheme",
|
||||
"kubernetes/typed/admissionregistration/v1alpha1",
|
||||
"kubernetes/typed/admissionregistration/v1alpha1/fake",
|
||||
"kubernetes/typed/admissionregistration/v1beta1",
|
||||
"kubernetes/typed/admissionregistration/v1beta1/fake",
|
||||
"kubernetes/typed/apps/v1",
|
||||
"kubernetes/typed/apps/v1/fake",
|
||||
"kubernetes/typed/apps/v1beta1",
|
||||
"kubernetes/typed/apps/v1beta1/fake",
|
||||
"kubernetes/typed/apps/v1beta2",
|
||||
"kubernetes/typed/apps/v1beta2/fake",
|
||||
"kubernetes/typed/authentication/v1",
|
||||
"kubernetes/typed/authentication/v1/fake",
|
||||
"kubernetes/typed/authentication/v1beta1",
|
||||
"kubernetes/typed/authentication/v1beta1/fake",
|
||||
"kubernetes/typed/authorization/v1",
|
||||
"kubernetes/typed/authorization/v1/fake",
|
||||
"kubernetes/typed/authorization/v1beta1",
|
||||
"kubernetes/typed/authorization/v1beta1/fake",
|
||||
"kubernetes/typed/autoscaling/v1",
|
||||
"kubernetes/typed/autoscaling/v1/fake",
|
||||
"kubernetes/typed/autoscaling/v2beta1",
|
||||
"kubernetes/typed/autoscaling/v2beta1/fake",
|
||||
"kubernetes/typed/batch/v1",
|
||||
"kubernetes/typed/batch/v1/fake",
|
||||
"kubernetes/typed/batch/v1beta1",
|
||||
"kubernetes/typed/batch/v1beta1/fake",
|
||||
"kubernetes/typed/batch/v2alpha1",
|
||||
"kubernetes/typed/batch/v2alpha1/fake",
|
||||
"kubernetes/typed/certificates/v1beta1",
|
||||
"kubernetes/typed/certificates/v1beta1/fake",
|
||||
"kubernetes/typed/core/v1",
|
||||
"kubernetes/typed/core/v1/fake",
|
||||
"kubernetes/typed/events/v1beta1",
|
||||
"kubernetes/typed/events/v1beta1/fake",
|
||||
"kubernetes/typed/extensions/v1beta1",
|
||||
"kubernetes/typed/extensions/v1beta1/fake",
|
||||
"kubernetes/typed/networking/v1",
|
||||
"kubernetes/typed/networking/v1/fake",
|
||||
"kubernetes/typed/policy/v1beta1",
|
||||
"kubernetes/typed/policy/v1beta1/fake",
|
||||
"kubernetes/typed/rbac/v1",
|
||||
"kubernetes/typed/rbac/v1/fake",
|
||||
"kubernetes/typed/rbac/v1alpha1",
|
||||
"kubernetes/typed/rbac/v1alpha1/fake",
|
||||
"kubernetes/typed/rbac/v1beta1",
|
||||
"kubernetes/typed/rbac/v1beta1/fake",
|
||||
"kubernetes/typed/scheduling/v1alpha1",
|
||||
"kubernetes/typed/scheduling/v1alpha1/fake",
|
||||
"kubernetes/typed/settings/v1alpha1",
|
||||
"kubernetes/typed/settings/v1alpha1/fake",
|
||||
"kubernetes/typed/storage/v1",
|
||||
"kubernetes/typed/storage/v1/fake",
|
||||
"kubernetes/typed/storage/v1alpha1",
|
||||
"kubernetes/typed/storage/v1alpha1/fake",
|
||||
"kubernetes/typed/storage/v1beta1",
|
||||
"kubernetes/typed/storage/v1beta1/fake",
|
||||
"pkg/version",
|
||||
"plugin/pkg/client/auth/gcp",
|
||||
"plugin/pkg/client/auth/oidc",
|
||||
|
|
@ -667,6 +698,6 @@
|
|||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "5c03546d71efcb5e0bad0ae002c1e0a6d627fa25f9854c8f118d2201235e6919"
|
||||
inputs-digest = "9f0307c913e8dc2b20bc7d25b9dabee66db88830c6d7d488ab944521c32170fd"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
// LabelKeyAppInstance refers to the application instance resource name
|
||||
LabelKeyAppInstance = MetadataPrefix + "/app-instance"
|
||||
|
||||
// LabelKeySecretType contains the type of argocd secret (currently this is just 'repo')
|
||||
LabelKeySecretType = MetadataPrefix + "/secret-type"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
package ksonnet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/ksonnet/ksonnet/metadata"
|
||||
"github.com/ksonnet/ksonnet/metadata/app"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -15,26 +21,82 @@ var (
|
|||
diffSeparator = regexp.MustCompile("\\n---")
|
||||
)
|
||||
|
||||
// KsonnetApp represents a ksonnet application directory
|
||||
type KsonnetApp struct {
|
||||
// Manager abstracts over a ksonnet application's metadata
|
||||
Manager metadata.Manager
|
||||
// KsonnetApp represents a ksonnet application directory and provides wrapper functionality around
|
||||
// the `ks` command.
|
||||
type KsonnetApp interface {
|
||||
// Root is the root path ksonnet application directory
|
||||
Root() string
|
||||
|
||||
// Spec is the Ksonnet application spec (app.yaml)
|
||||
Spec app.Spec
|
||||
AppSpec() app.Spec
|
||||
|
||||
// Show returns a list of unstructured objects that would be applied to an environment
|
||||
Show(environment string) ([]unstructured.Unstructured, error)
|
||||
}
|
||||
|
||||
func NewKsonnetApp(path string) (*KsonnetApp, error) {
|
||||
ksApp := KsonnetApp{}
|
||||
type ksonnetApp struct {
|
||||
manager metadata.Manager
|
||||
homeDir string
|
||||
spec app.Spec
|
||||
}
|
||||
|
||||
func NewKsonnetApp(path string) (KsonnetApp, error) {
|
||||
ksApp := ksonnetApp{}
|
||||
mgr, err := metadata.Find(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ksApp.Manager = mgr
|
||||
spec, err := ksApp.Manager.AppSpec()
|
||||
ksApp.manager = mgr
|
||||
spec, err := ksApp.manager.AppSpec()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ksApp.Spec = *spec
|
||||
ksApp.spec = *spec
|
||||
return &ksApp, nil
|
||||
}
|
||||
|
||||
func (k *ksonnetApp) ksCmd(args ...string) (string, error) {
|
||||
cmd := exec.Command("ks", args...)
|
||||
cmd.Dir = k.Root()
|
||||
|
||||
cmdStr := strings.Join(cmd.Args, " ")
|
||||
log.Debug(cmdStr)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
exErr := err.(*exec.ExitError)
|
||||
errOutput := string(exErr.Stderr)
|
||||
log.Errorf("`%s` failed: %s", cmdStr, errOutput)
|
||||
return "", fmt.Errorf(strings.TrimSpace(errOutput))
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func (k *ksonnetApp) Root() string {
|
||||
return k.manager.Root()
|
||||
}
|
||||
|
||||
// Spec is the Ksonnet application spec (app.yaml)
|
||||
func (k *ksonnetApp) AppSpec() app.Spec {
|
||||
return k.spec
|
||||
}
|
||||
|
||||
func (k *ksonnetApp) Show(environment string) ([]unstructured.Unstructured, error) {
|
||||
out, err := k.ksCmd("show", environment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parts := diffSeparator.Split(string(out), -1)
|
||||
objs := make([]unstructured.Unstructured, 0)
|
||||
for _, part := range parts {
|
||||
if strings.TrimSpace(part) == "" {
|
||||
continue
|
||||
}
|
||||
var obj unstructured.Unstructured
|
||||
err = yaml.Unmarshal([]byte(part), &obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to unmarshal manifest from `ks show`")
|
||||
}
|
||||
objs = append(objs, obj)
|
||||
}
|
||||
return objs, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package ksonnet
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"path"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
@ -13,7 +15,9 @@ var (
|
|||
)
|
||||
|
||||
const (
|
||||
testAppName = "test-app"
|
||||
testAppName = "test-app"
|
||||
testNamespace = "test-namespace"
|
||||
testEnvName = "test-env"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -24,7 +28,20 @@ func init() {
|
|||
func TestKsonnet(t *testing.T) {
|
||||
ksApp, err := NewKsonnetApp(path.Join(testDataDir, testAppName))
|
||||
assert.Nil(t, err)
|
||||
defaultEnv, ok := ksApp.Spec.Environments["default"]
|
||||
defaultEnv, ok := ksApp.AppSpec().Environments[testEnvName]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 1, len(defaultEnv.Destinations))
|
||||
}
|
||||
|
||||
func TestShow(t *testing.T) {
|
||||
ksApp, err := NewKsonnetApp(path.Join(testDataDir, testAppName))
|
||||
assert.Nil(t, err)
|
||||
objs, err := ksApp.Show(testEnvName)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(objs))
|
||||
for _, obj := range objs {
|
||||
jsonBytes, err := json.Marshal(obj)
|
||||
assert.Nil(t, err)
|
||||
log.Infof("%v", string(jsonBytes))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
6
util/ksonnet/testdata/test-app/app.yaml
vendored
6
util/ksonnet/testdata/test-app/app.yaml
vendored
|
|
@ -1,11 +1,11 @@
|
|||
apiVersion: 0.0.1
|
||||
environments:
|
||||
default:
|
||||
test-env:
|
||||
destinations:
|
||||
- namespace: default
|
||||
- namespace: test-namespace
|
||||
server: https://1.2.3.4
|
||||
k8sVersion: v1.8.0
|
||||
path: default
|
||||
path: test-env
|
||||
kind: ksonnet.io/app
|
||||
name: test-app
|
||||
registries:
|
||||
|
|
|
|||
80
util/ksonnet/testdata/test-app/lib/v1.8.0/k.libsonnet
vendored
Normal file
80
util/ksonnet/testdata/test-app/lib/v1.8.0/k.libsonnet
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
local k8s = import "k8s.libsonnet";
|
||||
|
||||
local apps = k8s.apps;
|
||||
local core = k8s.core;
|
||||
local extensions = k8s.extensions;
|
||||
|
||||
local hidden = {
|
||||
mapContainers(f):: {
|
||||
local podContainers = super.spec.template.spec.containers,
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+: {
|
||||
// IMPORTANT: This overwrites the 'containers' field
|
||||
// for this deployment.
|
||||
containers: std.map(f, podContainers),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
mapContainersWithName(names, f) ::
|
||||
local nameSet =
|
||||
if std.type(names) == "array"
|
||||
then std.set(names)
|
||||
else std.set([names]);
|
||||
local inNameSet(name) = std.length(std.setInter(nameSet, std.set([name]))) > 0;
|
||||
self.mapContainers(
|
||||
function(c)
|
||||
if std.objectHas(c, "name") && inNameSet(c.name)
|
||||
then f(c)
|
||||
else c
|
||||
),
|
||||
};
|
||||
|
||||
k8s + {
|
||||
apps:: apps + {
|
||||
v1beta1:: apps.v1beta1 + {
|
||||
local v1beta1 = apps.v1beta1,
|
||||
|
||||
daemonSet:: v1beta1.daemonSet + {
|
||||
mapContainers(f):: hidden.mapContainers(f),
|
||||
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
|
||||
},
|
||||
|
||||
deployment:: v1beta1.deployment + {
|
||||
mapContainers(f):: hidden.mapContainers(f),
|
||||
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
core:: core + {
|
||||
v1:: core.v1 + {
|
||||
list:: {
|
||||
new(items)::
|
||||
{apiVersion: "v1"} +
|
||||
{kind: "List"} +
|
||||
self.items(items),
|
||||
|
||||
items(items):: if std.type(items) == "array" then {items+: items} else {items+: [items]},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
extensions:: extensions + {
|
||||
v1beta1:: extensions.v1beta1 + {
|
||||
local v1beta1 = extensions.v1beta1,
|
||||
|
||||
daemonSet:: v1beta1.daemonSet + {
|
||||
mapContainers(f):: hidden.mapContainers(f),
|
||||
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
|
||||
},
|
||||
|
||||
deployment:: v1beta1.deployment + {
|
||||
mapContainers(f):: hidden.mapContainers(f),
|
||||
mapContainersWithName(names, f):: hidden.mapContainersWithName(names, f),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
25121
util/ksonnet/testdata/test-app/lib/v1.8.0/k8s.libsonnet
vendored
Normal file
25121
util/ksonnet/testdata/test-app/lib/v1.8.0/k8s.libsonnet
vendored
Normal file
File diff suppressed because it is too large
Load diff
73741
util/ksonnet/testdata/test-app/lib/v1.8.0/swagger.json
vendored
Normal file
73741
util/ksonnet/testdata/test-app/lib/v1.8.0/swagger.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -3,6 +3,15 @@
|
|||
package kube
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
|
@ -14,3 +23,82 @@ func GetClientConfig(kubeconfig string) (*rest.Config, error) {
|
|||
}
|
||||
return rest.InClusterConfig()
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
KubeClientset kubernetes.Interface
|
||||
Disco discovery.DiscoveryInterface
|
||||
RestConfig *rest.Config
|
||||
}
|
||||
|
||||
type listResult struct {
|
||||
Items []*unstructured.Unstructured `json:"items"`
|
||||
}
|
||||
|
||||
// ListAPIResources discovers all API resources supported by the Kube API sererver
|
||||
func ListAPIResources(disco discovery.DiscoveryInterface) ([]metav1.APIResource, error) {
|
||||
apiResources := make([]metav1.APIResource, 0)
|
||||
resList, err := disco.ServerResources()
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
for _, resGroup := range resList {
|
||||
for _, apiRes := range resGroup.APIResources {
|
||||
apiResources = append(apiResources, apiRes)
|
||||
}
|
||||
}
|
||||
return apiResources, nil
|
||||
}
|
||||
|
||||
// ListResources returns a list of resources of a particular API type using the dynamic client
|
||||
func ListResources(dclient dynamic.Interface, apiResource metav1.APIResource, namespace string, listOpts metav1.ListOptions) ([]*unstructured.Unstructured, error) {
|
||||
reIf := dclient.Resource(&apiResource, namespace)
|
||||
liveObjs, err := reIf.List(listOpts)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
liveObjsBytes, err := json.Marshal(liveObjs)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
var objList listResult
|
||||
err = json.Unmarshal(liveObjsBytes, &objList)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
return objList.Items, nil
|
||||
}
|
||||
|
||||
// ListAllResources iterates the list of API resources, and returns all resources with the given filters
|
||||
func ListAllResources(config *rest.Config, apiResources []metav1.APIResource, namespace string, listOpts metav1.ListOptions) ([]*unstructured.Unstructured, error) {
|
||||
// itemMap dedups items when there is duplication of a resource in multiple API types
|
||||
// e.g. extensions/v1beta1/namespaces/default/deployments and apps/v1/namespaces/default/deployments
|
||||
itemMap := make(map[string]*unstructured.Unstructured)
|
||||
|
||||
for _, apiResource := range apiResources {
|
||||
dynConfig := *config
|
||||
dynConfig.GroupVersion = &schema.GroupVersion{
|
||||
Group: apiResource.Group,
|
||||
Version: apiResource.Kind,
|
||||
}
|
||||
dclient, err := dynamic.NewClient(&dynConfig)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
resList, err := ListResources(dclient, apiResource, namespace, listOpts)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
for _, liveObj := range resList {
|
||||
itemMap[string(liveObj.GetUID())] = liveObj
|
||||
}
|
||||
|
||||
}
|
||||
resources := make([]*unstructured.Unstructured, len(itemMap))
|
||||
i := 0
|
||||
for _, obj := range itemMap {
|
||||
resources[i] = obj
|
||||
i++
|
||||
}
|
||||
return resources, nil
|
||||
|
||||
}
|
||||
|
|
|
|||
180
util/kube/kube_test.go
Normal file
180
util/kube/kube_test.go
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
package kube
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||
fakedynamic "k8s.io/client-go/dynamic/fake"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
kubetesting "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testAppName = "test-app"
|
||||
testNamespace = "test-namespace"
|
||||
testEnvName = "test-env"
|
||||
testAppInstanceName = "test-app-instance"
|
||||
)
|
||||
|
||||
func demoService() *apiv1.Service {
|
||||
return &apiv1.Service{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Service",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo",
|
||||
Namespace: testNamespace,
|
||||
Labels: map[string]string{
|
||||
common.LabelKeyAppInstance: testAppInstanceName,
|
||||
},
|
||||
},
|
||||
Spec: apiv1.ServiceSpec{
|
||||
Ports: []apiv1.ServicePort{
|
||||
{
|
||||
Port: 80,
|
||||
TargetPort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"app": "demo",
|
||||
},
|
||||
Type: "ClusterIP",
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func demoDeployment() *appsv1.Deployment {
|
||||
var two int32 = 2
|
||||
return &appsv1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "apps/v1beta1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo",
|
||||
Namespace: testNamespace,
|
||||
Labels: map[string]string{
|
||||
common.LabelKeyAppInstance: testAppInstanceName,
|
||||
},
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: &two,
|
||||
Template: apiv1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"app": "demo",
|
||||
},
|
||||
},
|
||||
Spec: apiv1.PodSpec{
|
||||
Containers: []apiv1.Container{
|
||||
{
|
||||
Name: "demo",
|
||||
Image: "gcr.io/kuar-demo/kuard-amd64:1",
|
||||
Ports: []apiv1.ContainerPort{
|
||||
{
|
||||
ContainerPort: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceList() []*metav1.APIResourceList {
|
||||
return []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: apiv1.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod"},
|
||||
{Name: "services", Namespaced: true, Kind: "Service"},
|
||||
{Name: "replicationcontrollers", Namespaced: true, Kind: "ReplicationController"},
|
||||
{Name: "replicationcontrollers/scale", Namespaced: true, Kind: "Scale", Group: "autoscaling", Version: "v1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
GroupVersion: extv1beta1.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
|
||||
{Name: "replicasets/scale", Namespaced: true, Kind: "Scale"},
|
||||
},
|
||||
},
|
||||
{
|
||||
GroupVersion: appsv1beta2.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "deployments", Namespaced: true, Kind: "Deployment"},
|
||||
{Name: "deployments/scale", Namespaced: true, Kind: "Scale", Group: "apps", Version: "v1beta2"},
|
||||
},
|
||||
},
|
||||
{
|
||||
GroupVersion: appsv1beta1.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "statefulsets", Namespaced: true, Kind: "StatefulSet"},
|
||||
{Name: "statefulsets/scale", Namespaced: true, Kind: "Scale", Group: "apps", Version: "v1beta1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
GroupVersion: argoappv1.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "applications", Namespaced: true, Kind: "Application"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestListAPIResources(t *testing.T) {
|
||||
kubeclientset := fake.NewSimpleClientset(demoService(), demoDeployment())
|
||||
fakeDiscovery, ok := kubeclientset.Discovery().(*fakediscovery.FakeDiscovery)
|
||||
assert.True(t, ok)
|
||||
fakeDiscovery.Fake.Resources = resourceList()
|
||||
apiRes, err := ListAPIResources(fakeDiscovery)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 11, len(apiRes))
|
||||
}
|
||||
|
||||
func TestListResources(t *testing.T) {
|
||||
kubeclientset := fake.NewSimpleClientset(demoService(), demoDeployment())
|
||||
fakeDynClient := fakedynamic.FakeClient{
|
||||
Fake: &kubetesting.Fake{},
|
||||
}
|
||||
fakeDynClient.Fake.AddReactor("list", "services", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
svcList, err := kubeclientset.CoreV1().Services(testNamespace).List(metav1.ListOptions{})
|
||||
assert.Nil(t, err)
|
||||
svcList.Kind = "ServiceList"
|
||||
svcListBytes, err := json.Marshal(svcList)
|
||||
log.Println(string(svcListBytes))
|
||||
assert.Nil(t, err)
|
||||
var uList unstructured.UnstructuredList
|
||||
err = json.Unmarshal(svcListBytes, &uList)
|
||||
assert.Nil(t, err)
|
||||
return true, &uList, nil
|
||||
})
|
||||
|
||||
apiResource := metav1.APIResource{
|
||||
Name: "services",
|
||||
Namespaced: true,
|
||||
Version: "v1",
|
||||
Kind: "Service",
|
||||
}
|
||||
resList, err := ListResources(&fakeDynClient, apiResource, testNamespace, metav1.ListOptions{})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(resList))
|
||||
}
|
||||
Loading…
Reference in a new issue