Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(*) make sure we enumerate all types in kumactl #1673

Merged
merged 1 commit into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 90 additions & 26 deletions app/kumactl/cmd/delete/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,9 @@ var _ = Describe("kumactl delete ", func() {
// then
Expect(err).To(HaveOccurred())
// and
Expect(err.Error()).To(Equal("unknown TYPE: some-type. Allowed values: mesh, " +
"dataplane, healthcheck, proxytemplate, traffic-log, traffic-permission, " +
"traffic-route, traffic-trace, fault-injection, circuit-breaker, retry, secret, " +
"zone"))
Expect(err.Error()).To(ContainSubstring("unknown TYPE: some-type. Allowed values:"))
// and
Expect(outbuf.String()).To(MatchRegexp("unknown TYPE: some-type. " +
"Allowed values: mesh, dataplane, healthcheck, proxytemplate, traffic-log, " +
"traffic-permission, traffic-route, traffic-trace, fault-injection, " +
"circuit-breaker, retry, secret, zone"))
Expect(outbuf.String()).To(ContainSubstring("unknown TYPE: some-type. Allowed values:"))
// and
Expect(errbuf.Bytes()).To(BeEmpty())
})
Expand Down Expand Up @@ -144,36 +138,66 @@ var _ = Describe("kumactl delete ", func() {
// then
Expect(err).ToNot(HaveOccurred())
},
Entry("circuit-breaker", testCase{
typ: "circuit-breaker",
name: "web",
resource: func() core_model.Resource { return mesh_core.NewCircuitBreakerResource() },
expectedMessage: "deleted CircuitBreaker \"web\"\n",
}),
Entry("dataplanes", testCase{
typ: "dataplane",
name: "web",
resource: func() core_model.Resource { return mesh_core.NewDataplaneResource() },
expectedMessage: "deleted Dataplane \"web\"\n",
}),
Entry("external-services", testCase{
typ: "external-service",
name: "httpbin",
resource: func() core_model.Resource { return mesh_core.NewExternalServiceResource() },
expectedMessage: "deleted ExternalService \"httpbin\"\n",
}),
Entry("fault-injections", testCase{
typ: "fault-injection",
name: "web",
resource: func() core_model.Resource { return mesh_core.NewFaultInjectionResource() },
expectedMessage: "deleted FaultInjection \"web\"\n",
}),
Entry("healthchecks", testCase{
typ: "healthcheck",
name: "web-to-backend",
resource: func() core_model.Resource { return mesh_core.NewHealthCheckResource() },
expectedMessage: "deleted HealthCheck \"web-to-backend\"\n",
}),
Entry("proxytemplate", testCase{
typ: "proxytemplate",
name: "test-pt",
resource: func() core_model.Resource { return mesh_core.NewProxyTemplateResource() },
expectedMessage: "deleted ProxyTemplate \"test-pt\"\n",
}),
Entry("retries", testCase{
typ: "retry",
name: "web-to-backend",
resource: func() core_model.Resource { return mesh_core.NewRetryResource() },
expectedMessage: "deleted Retry \"web-to-backend\"\n",
}),
Entry("traffic-permissions", testCase{
typ: "traffic-permission",
name: "everyone-to-everyone",
resource: func() core_model.Resource { return mesh_core.NewTrafficPermissionResource() },
expectedMessage: "deleted TrafficPermission \"everyone-to-everyone\"\n",
Entry("timeouts", testCase{
typ: "timeout",
name: "web",
resource: func() core_model.Resource { return mesh_core.NewTimeoutResource() },
expectedMessage: "deleted Timeout \"web\"\n",
}),
Entry("traffic-logs", testCase{
typ: "traffic-log",
name: "all-requests",
resource: func() core_model.Resource { return mesh_core.NewTrafficLogResource() },
expectedMessage: "deleted TrafficLog \"all-requests\"\n",
}),
Entry("traffic-permissions", testCase{
typ: "traffic-permission",
name: "everyone-to-everyone",
resource: func() core_model.Resource { return mesh_core.NewTrafficPermissionResource() },
expectedMessage: "deleted TrafficPermission \"everyone-to-everyone\"\n",
}),
Entry("traffic-routes", testCase{
typ: "traffic-route",
name: "web-to-backend",
Expand All @@ -186,26 +210,66 @@ var _ = Describe("kumactl delete ", func() {
resource: func() core_model.Resource { return mesh_core.NewTrafficTraceResource() },
expectedMessage: "deleted TrafficTrace \"web\"\n",
}),
Entry("fault-injections", testCase{
typ: "fault-injection",
name: "web",
resource: func() core_model.Resource { return mesh_core.NewFaultInjectionResource() },
expectedMessage: "deleted FaultInjection \"web\"\n",
}),
Entry("circuit-breaker", testCase{
typ: "circuit-breaker",
name: "web",
resource: func() core_model.Resource { return mesh_core.NewCircuitBreakerResource() },
expectedMessage: "deleted CircuitBreaker \"web\"\n",
}),
Entry("secret", testCase{
Entry("secrets", testCase{
typ: "secret",
name: "web",
resource: func() core_model.Resource { return system.NewSecretResource() },
expectedMessage: "deleted Secret \"web\"\n",
}),
)

DescribeTable("should succeed if resource exists",
func(given testCase) {
key := core_model.ResourceKey{Name: given.name}

By("creating resources necessary for the test")
// setup

// when
err := store.Create(context.Background(), given.resource(), core_store.CreateBy(key))
// then
Expect(err).ToNot(HaveOccurred())

By("running delete command")
// given
rootCmd.SetArgs([]string{
"--config-file", filepath.Join("..", "testdata", "sample-kumactl.config.yaml"),
"delete", given.typ, given.name})

// when
err = rootCmd.Execute()
// then
Expect(err).ToNot(HaveOccurred())
// and
Expect(errbuf.String()).To(BeEmpty())
Expect(outbuf.String()).To(Equal(given.expectedMessage))

By("verifying that resource under test was actually deleted")
// when
err = store.Get(context.Background(), given.resource(), core_store.GetBy(key))
// then
Expect(core_store.IsResourceNotFound(err)).To(BeTrue())
},
Entry("meshes", testCase{
typ: "mesh",
name: "test-mesh",
resource: func() core_model.Resource { return mesh_core.NewMeshResource() },
expectedMessage: "deleted Mesh \"test-mesh\"\n",
}),
Entry("global-secrets", testCase{
typ: "global-secret",
name: "test-secret",
resource: func() core_model.Resource { return system.NewGlobalSecretResource() },
expectedMessage: "deleted GlobalSecret \"test-secret\"\n",
}),
Entry("zones", testCase{
typ: "zone",
name: "eu-north",
resource: func() core_model.Resource { return system.NewZoneResource() },
expectedMessage: "deleted Zone \"eu-north\"\n",
}),
)

DescribeTable("should fail if resource doesn't exist",
func(given testCase) {
By("running delete command")
Expand Down
59 changes: 59 additions & 0 deletions app/kumactl/cmd/get/get_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package get_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/spf13/cobra"

"github.com/kumahq/kuma/app/kumactl/cmd"
kumactl_cmd "github.com/kumahq/kuma/app/kumactl/pkg/cmd"
config_proto "github.com/kumahq/kuma/pkg/config/app/kumactl/v1alpha1"
core_store "github.com/kumahq/kuma/pkg/core/resources/store"
memory_resources "github.com/kumahq/kuma/pkg/plugins/resources/memory"
)

func hasSubCommand(cmd *cobra.Command, sub string) bool {
for _, c := range cmd.Commands() {
if c.Use == sub {
return true
}
}

return false
}

var _ = Describe("kumactl get ", func() {
Describe("Get Command", func() {
var rootCtx *kumactl_cmd.RootContext
var rootCmd, getCmd *cobra.Command
var store core_store.ResourceStore

BeforeEach(func() {
// setup
rootCtx = kumactl_cmd.DefaultRootContext()
rootCtx.Runtime.NewResourceStore = func(*config_proto.ControlPlaneCoordinates_ApiServer) (core_store.ResourceStore, error) {
return store, nil
}
store = core_store.NewPaginationStore(memory_resources.NewStore())

rootCmd = cmd.NewRootCmd(rootCtx)
for _, cmd := range rootCmd.Commands() {
if cmd.Use == "get" {
getCmd = cmd
break
}
}
Expect(getCmd).ToNot(BeNil())
})

It("should have get commands for all defined types", func() {
// when
Expect(len(getCmd.Commands()) > len(rootCtx.TypeArgs)).To(BeTrue())

// then
for sub := range rootCtx.TypeArgs {
Expect(hasSubCommand(getCmd, sub+" NAME")).To(BeTrue(), "failing to find "+sub)
}
})
})
})
22 changes: 12 additions & 10 deletions app/kumactl/pkg/cmd/root_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,21 @@ func DefaultRootContext() *RootContext {
NewAPIServerClient: kumactl_resources.NewAPIServerClient,
},
TypeArgs: map[string]core_model.ResourceType{
"mesh": core_mesh.MeshType,
"circuit-breaker": core_mesh.CircuitBreakerType,
"dataplane": core_mesh.DataplaneType,
"externalservice": core_mesh.ExternalServiceType,
"external-service": core_mesh.ExternalServiceType,
"fault-injection": core_mesh.FaultInjectionType,
"healthcheck": core_mesh.HealthCheckType,
"mesh": core_mesh.MeshType,
"proxytemplate": core_mesh.ProxyTemplateType,
"retry": core_mesh.RetryType,
"timeout": core_mesh.TimeoutType,
"traffic-log": core_mesh.TrafficLogType,
"traffic-permission": core_mesh.TrafficPermissionType,
"traffic-route": core_mesh.TrafficRouteType,
"traffic-trace": core_mesh.TrafficTraceType,
"fault-injection": core_mesh.FaultInjectionType,
"circuit-breaker": core_mesh.CircuitBreakerType,
"retry": core_mesh.RetryType,
"secret": system.SecretType,
"global-secret": system.GlobalSecretType,
"secret": system.SecretType,
"zone": system.ZoneType,
},
InstallCpContext: install_context.DefaultInstallCpContext(),
Expand All @@ -91,10 +92,11 @@ func DefaultRootContext() *RootContext {
func (rc *RootContext) TypeForArg(arg string) (core_model.ResourceType, error) {
typ, ok := rc.TypeArgs[arg]
if !ok {
return "", errors.Errorf("unknown TYPE: %s. Allowed values: mesh, dataplane, "+
"healthcheck, proxytemplate, traffic-log, traffic-permission, traffic-route, "+
"traffic-trace, fault-injection, circuit-breaker, retry, secret, zone",
arg)
allowedValues := ""
for v := range rc.TypeArgs {
allowedValues += v + ", "
}
return "", errors.Errorf("unknown TYPE: %s. Allowed values: %s:", arg, allowedValues)
}
return typ, nil
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/kds/global/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ import (
var (
kdsGlobalLog = core.Log.WithName("kds-global")
ProvidedTypes = []model.ResourceType{
mesh.MeshType,
mesh.CircuitBreakerType,
mesh.DataplaneType,
mesh.ExternalServiceType,
mesh.CircuitBreakerType,
mesh.FaultInjectionType,
mesh.HealthCheckType,
mesh.MeshType,
mesh.ProxyTemplateType,
mesh.RetryType,
mesh.TimeoutType,
mesh.TrafficLogType,
mesh.TrafficPermissionType,
mesh.TrafficRouteType,
mesh.TrafficTraceType,
mesh.ProxyTemplateType,
mesh.RetryType,
mesh.TimeoutType,
system.SecretType,
system.ConfigType,
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/kds/remote/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ var (
mesh.DataplaneInsightType,
}
ConsumedTypes = []model.ResourceType{
mesh.MeshType,
mesh.CircuitBreakerType,
mesh.DataplaneType,
mesh.ExternalServiceType,
mesh.CircuitBreakerType,
mesh.FaultInjectionType,
mesh.HealthCheckType,
mesh.MeshType,
mesh.ProxyTemplateType,
mesh.RetryType,
mesh.TimeoutType,
mesh.TrafficLogType,
mesh.TrafficPermissionType,
mesh.TrafficRouteType,
mesh.TrafficTraceType,
mesh.ProxyTemplateType,
mesh.RetryType,
mesh.TimeoutType,
system.SecretType,
system.ConfigType,
}
Expand Down
39 changes: 24 additions & 15 deletions pkg/kds/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,43 +61,42 @@ var _ = Describe("KDS Server", func() {
It("should support all existing resource types", func() {
ctx := context.Background()

// Just to don't forget to update this test after updating 'kds.SupportedTypes
// Do not forget to update this test after updating 'kds.SupportedTypes
Expect([]proto.Message{
kds_samples.Mesh1,
kds_samples.Ingress,
kds_samples.CircuitBreaker,
kds_samples.Ingress, // mesh.DataplaneType
kds_samples.DataplaneInsight,
kds_samples.ExternalService,
kds_samples.CircuitBreaker,
kds_samples.FaultInjection,
kds_samples.HealthCheck,
kds_samples.Mesh1,
kds_samples.ProxyTemplate,
kds_samples.Retry,
kds_samples.Timeout,
kds_samples.TrafficLog,
kds_samples.TrafficPermission,
kds_samples.TrafficRoute,
kds_samples.TrafficTrace,
kds_samples.ProxyTemplate,
kds_samples.Retry,
kds_samples.Secret,
kds_samples.Config}).
kds_samples.Config,
}).
To(HaveLen(len(kds.SupportedTypes)))

vrf := kds_verifier.New().
Exec(kds_verifier.Create(ctx, &mesh.MeshResource{Spec: kds_samples.Mesh1}, store.CreateByKey("mesh-1", model.NoMesh))).
Exec(kds_verifier.Create(ctx, &mesh.CircuitBreakerResource{Spec: kds_samples.CircuitBreaker}, store.CreateByKey("cb-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.DataplaneResource{Spec: kds_samples.Ingress}, store.CreateByKey("Ingress-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.DataplaneInsightResource{Spec: kds_samples.DataplaneInsight}, store.CreateByKey("insight-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.ExternalServiceResource{Spec: kds_samples.ExternalService}, store.CreateByKey("es-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.CircuitBreakerResource{Spec: kds_samples.CircuitBreaker}, store.CreateByKey("cb-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.FaultInjectionResource{Spec: kds_samples.FaultInjection}, store.CreateByKey("fi-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.HealthCheckResource{Spec: kds_samples.HealthCheck}, store.CreateByKey("hc-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.MeshResource{Spec: kds_samples.Mesh1}, store.CreateByKey("mesh-1", model.NoMesh))).
Exec(kds_verifier.Create(ctx, &mesh.ProxyTemplateResource{Spec: kds_samples.ProxyTemplate}, store.CreateByKey("pt-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.RetryResource{Spec: kds_samples.Retry}, store.CreateByKey("retry-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.TimeoutResource{Spec: kds_samples.Timeout}, store.CreateByKey("timeout-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.TrafficLogResource{Spec: kds_samples.TrafficLog}, store.CreateByKey("tl-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.TrafficPermissionResource{Spec: kds_samples.TrafficPermission}, store.CreateByKey("tp-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.TrafficRouteResource{Spec: kds_samples.TrafficRoute}, store.CreateByKey("tr-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.TrafficTraceResource{Spec: kds_samples.TrafficTrace}, store.CreateByKey("tt-1", "mesh-1"))).
Exec(kds_verifier.Create(ctx, &mesh.ProxyTemplateResource{Spec: kds_samples.ProxyTemplate}, store.CreateByKey("pt-1", "mesh-1"))).
Exec(kds_verifier.Create(
ctx,
&mesh.RetryResource{Spec: kds_samples.Retry},
store.CreateByKey("r-1", "mesh-1"),
)).
Exec(kds_verifier.Create(ctx, &system.SecretResource{Spec: kds_samples.Secret}, store.CreateByKey("s-1", "mesh-1"))).
Exec(kds_verifier.DiscoveryRequest(node, mesh.MeshType)).
Exec(kds_verifier.WaitResponse(defaultTimeout, func(rs []model.Resource) {
Expand Down Expand Up @@ -164,6 +163,16 @@ var _ = Describe("KDS Server", func() {
Expect(rs).To(HaveLen(1))
Expect(rs[0].GetSpec()).To(MatchProto(kds_samples.Secret))
})).
Exec(kds_verifier.DiscoveryRequest(node, mesh.RetryType)).
Exec(kds_verifier.WaitResponse(defaultTimeout, func(rs []model.Resource) {
Expect(rs).To(HaveLen(1))
Expect(rs[0].GetSpec()).To(MatchProto(kds_samples.Retry))
})).
Exec(kds_verifier.DiscoveryRequest(node, mesh.TimeoutType)).
Exec(kds_verifier.WaitResponse(defaultTimeout, func(rs []model.Resource) {
Expect(rs).To(HaveLen(1))
Expect(rs[0].GetSpec()).To(MatchProto(kds_samples.Timeout))
})).
Exec(kds_verifier.CloseStream())

err := vrf.Verify(tc)
Expand Down
Loading