Repository: clouditor/clouditor
Pull request #553 (2022-03-03 17:16:24)

Make list of discoverers configurable

codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/553?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> Merging [#553](https://codecov.io/gh/clouditor/clouditor/pull/553?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (be86261) into [main](https://codecov.io/gh/clouditor/clouditor/commit/a8b6b50ca0913cba5ab19d09d9c5d05274adfc3a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (a8b6b50) will **increase** coverage by `0.80%`.
> The diff coverage is `89.09%`.

[![Impacted file tree graph](https://codecov.io/gh/clouditor/clouditor/pull/553/graphs/tree.svg?width=650&height=150&src=pr&token=syrXsw5LTX&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)](https://codecov.io/gh/clouditor/clouditor/pull/553?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)

```diff
@@            Coverage Diff             @@
##             main     #553      +/-   ##
==========================================
+ Coverage   80.94%   81.74%   +0.80%     
==========================================
  Files          50       50              
  Lines        4812     4838      +26     
==========================================
+ Hits         3895     3955      +60     
+ Misses        735      701      -34     
  Partials      182      182              
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `81.74% <89.09%> (+0.80%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/clouditor/clouditor/pull/553?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | Coverage Δ | |
|---|---|---|
| [service/discovery/discovery.go](https://codecov.io/gh/clouditor/clouditor/pull/553/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvZGlzY292ZXJ5Lmdv) | `93.90% <87.75%> (+16.06%)` | :arrow_up: |
| [cli/commands/service/discovery/discovery.go](https://codecov.io/gh/clouditor/clouditor/pull/553/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-Y2xpL2NvbW1hbmRzL3NlcnZpY2UvZGlzY292ZXJ5L2Rpc2NvdmVyeS5nbw==) | `83.33% <100.00%> (+1.07%)` | :arrow_up: |
| [cmd/engine/engine.go](https://codecov.io/gh/clouditor/clouditor/pull/553/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-Y21kL2VuZ2luZS9lbmdpbmUuZ28=) | `80.54% <100.00%> (+0.10%)` | :arrow_up: |
| [service/discovery/azure/azure.go](https://codecov.io/gh/clouditor/clouditor/pull/553/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvYXp1cmUuZ28=) | `87.30% <0.00%> (+6.34%)` | :arrow_up: |
| [service/discovery/aws/aws.go](https://codecov.io/gh/clouditor/clouditor/pull/553/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXdzL2F3cy5nbw==) | `88.88% <0.00%> (+11.11%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/clouditor/clouditor/pull/553?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/553?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Last update [a8b6b50...be86261](https://codecov.io/gh/clouditor/clouditor/pull/553?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).


Patch:
diff --git a/api/discovery/discovery.pb.go b/api/discovery/discovery.pb.go
index 346d8a03..908785d7 100644
--- a/api/discovery/discovery.pb.go
+++ b/api/discovery/discovery.pb.go
@@ -52,6 +52,9 @@ type StartDiscoveryRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	// A list of providers to be discovered
+	Providers []string `protobuf:"bytes,1,rep,name=providers,proto3" json:"providers,omitempty"`
 }
 
 func (x *StartDiscoveryRequest) Reset() {
@@ -86,6 +89,13 @@ func (*StartDiscoveryRequest) Descriptor() ([]byte, []int) {
 	return file_api_discovery_discovery_proto_rawDescGZIP(), []int{0}
 }
 
+func (x *StartDiscoveryRequest) GetProviders() []string {
+	if x != nil {
+		return x.Providers
+	}
+	return nil
+}
+
 type StartDiscoveryResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -236,35 +246,37 @@ var file_api_discovery_discovery_proto_rawDesc = []byte{
 	0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
 	0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
 	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x17, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44,
-	0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
-	0x38, 0x0a, 0x16, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72,
-	0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63,
-	0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73,
-	0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22, 0x33, 0x0a, 0x0c, 0x51, 0x75, 0x65,
-	0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x6c,
-	0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x45,
-	0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x65,
-	0x73, 0x75, 0x6c, 0x74, 0x73, 0x32, 0xdb, 0x01, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76,
-	0x65, 0x72, 0x79, 0x12, 0x6f, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x20, 0x2e, 0x63,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44,
+	0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03,
+	0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0x38, 0x0a,
+	0x16, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65,
+	0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, 0x63,
+	0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22, 0x33, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x74, 0x65,
+	0x72, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
+	0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x45, 0x0a, 0x0d,
+	0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a,
+	0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x73, 0x32, 0xdb, 0x01, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72,
+	0x79, 0x12, 0x6f, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x20, 0x2e, 0x63, 0x6c, 0x6f,
+	0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x69, 0x73, 0x63,
+	0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63,
 	0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x69,
-	0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
-	0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74,
-	0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x64,
-	0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x01,
-	0x2a, 0x62, 0x01, 0x2a, 0x12, 0x5d, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x17, 0x2e,
-	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
-	0x6f, 0x72, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69,
-	0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x3a, 0x01, 0x2a,
-	0x62, 0x01, 0x2a, 0x42, 0x0f, 0x5a, 0x0d, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f,
-	0x76, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x73,
+	0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x01, 0x2a, 0x62,
+	0x01, 0x2a, 0x12, 0x5d, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x17, 0x2e, 0x63, 0x6c,
+	0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
+	0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21,
+	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x73, 0x63,
+	0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x3a, 0x01, 0x2a, 0x62, 0x01,
+	0x2a, 0x42, 0x0f, 0x5a, 0x0d, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65,
+	0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/api/discovery/discovery.proto b/api/discovery/discovery.proto
index d7c00e3d..0fafc05b 100644
--- a/api/discovery/discovery.proto
+++ b/api/discovery/discovery.proto
@@ -55,7 +55,10 @@ service Discovery {
   }
 }
 
-message StartDiscoveryRequest {}
+message StartDiscoveryRequest {
+  // A list of providers to be discovered
+  repeated string providers = 1;
+}
 
 message StartDiscoveryResponse { bool successful = 1; }
 
diff --git a/cli/commands/service/discovery/discovery.go b/cli/commands/service/discovery/discovery.go
index 405ea6c7..7bd14b49 100644
--- a/cli/commands/service/discovery/discovery.go
+++ b/cli/commands/service/discovery/discovery.go
@@ -28,14 +28,20 @@ package discovery
 import (
 	"context"
 	"fmt"
+	"github.com/spf13/viper"
 
 	"clouditor.io/clouditor/api/discovery"
 	"clouditor.io/clouditor/cli"
 	"github.com/spf13/cobra"
 )
 
+const (
+	DiscovererFlag = "discoverer"
+)
+
 // NewStartDiscoveryCommand returns a cobra command for the `start` subcommand
 func NewStartDiscoveryCommand() *cobra.Command {
+	var discoverer []string
 	cmd := &cobra.Command{
 		Use:   "start",
 		Short: "Starts the discovery",
@@ -54,12 +60,15 @@ func NewStartDiscoveryCommand() *cobra.Command {
 
 			client = discovery.NewDiscoveryClient(session)
 
-			res, err = client.Start(context.Background(), &discovery.StartDiscoveryRequest{})
+			res, err = client.Start(context.Background(), &discovery.StartDiscoveryRequest{Providers: discoverer})
 
 			return session.HandleResponse(res, err)
 		},
 	}
 
+	cmd.Flags().StringSliceVarP(&discoverer, DiscovererFlag, "d", []string{}, "Providers to discover, separated by comma")
+	_ = viper.BindPFlag(DiscovererFlag, cmd.Flags().Lookup(DiscovererFlag))
+
 	return cmd
 }
 
diff --git a/cmd/engine/engine.go b/cmd/engine/engine.go
index c02cb475..90c496ab 100644
--- a/cmd/engine/engine.go
+++ b/cmd/engine/engine.go
@@ -48,6 +48,7 @@ import (
 	"clouditor.io/clouditor/api/discovery"
 	"clouditor.io/clouditor/api/evidence"
 	"clouditor.io/clouditor/api/orchestrator"
+	cli_discovery "clouditor.io/clouditor/cli/commands/service/discovery"
 	"clouditor.io/clouditor/logging/formatter"
 	"clouditor.io/clouditor/persistence"
 	"clouditor.io/clouditor/persistence/gorm"
@@ -106,6 +107,7 @@ var (
 	assessmentService    assessment.AssessmentServer
 	evidenceStoreService evidence.EvidenceStoreServer
 	db                   persistence.Storage
+	providers            []string
 
 	log *logrus.Entry
 )
@@ -196,6 +198,13 @@ func doCmd(_ *cobra.Command, _ []string) (err error) {
 		return fmt.Errorf("could not create storage: %w", err)
 	}
 
+	// If no CSPs for discovering is given, take all implemented discoverers
+	if viper.GetString(cli_discovery.DiscovererFlag) == "" {
+		providers = []string{service_discovery.ProviderAWS, service_discovery.ProviderAzure, service_discovery.ProviderK8S}
+	} else {
+		providers = []string{viper.GetString(cli_discovery.DiscovererFlag)}
+	}
+
 	authService = service_auth.NewService(
 		service_auth.WithStorage(db),
 		service_auth.WithApiKeyPassword(viper.GetString(APIKeyPasswordFlag)),
@@ -208,6 +217,7 @@ func doCmd(_ *cobra.Command, _ []string) (err error) {
 			viper.GetString(APIDefaultUserFlag),
 			viper.GetString(APIDefaultPasswordFlag),
 		),
+		service_discovery.WithProviders(providers),
 	)
 	orchestratorService = service_orchestrator.NewService(service_orchestrator.WithStorage(db))
 	assessmentService = service_assessment.NewService(
diff --git a/openapi/discovery/openapi.yaml b/openapi/discovery/openapi.yaml
index ac3426bc..1a9b9f0f 100644
--- a/openapi/discovery/openapi.yaml
+++ b/openapi/discovery/openapi.yaml
@@ -70,7 +70,12 @@ components:
                     $ref: '#/components/schemas/ListValue'
         StartDiscoveryRequest:
             type: object
-            properties: {}
+            properties:
+                providers:
+                    type: array
+                    items:
+                        type: string
+                    description: A list of providers to be discovered
         StartDiscoveryResponse:
             type: object
             properties:
diff --git a/service/discovery/discovery.go b/service/discovery/discovery.go
index 331579e9..1f8899a3 100644
--- a/service/discovery/discovery.go
+++ b/service/discovery/discovery.go
@@ -27,6 +27,7 @@ package discovery
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"time"
 
@@ -51,6 +52,12 @@ import (
 	"google.golang.org/protobuf/types/known/structpb"
 )
 
+const (
+	ProviderAWS   = "aws"
+	ProviderK8S   = "k8s"
+	ProviderAzure = "azure"
+)
+
 var log *logrus.Entry
 
 // Service is an implementation of the Clouditor Discovery service.
@@ -68,6 +75,8 @@ type Service struct {
 	scheduler *gocron.Scheduler
 
 	authorizer api.Authorizer
+
+	providers []string
 }
 
 type Configuration struct {
@@ -100,6 +109,13 @@ func WithInternalAuthorizer(address string, username string, password string, op
 	}
 }
 
+// WithProviders is an option to set providers for discovering
+func WithProviders(providersList []string) ServiceOption {
+	return func(s *Service) {
+		s.providers = providersList
+	}
+}
+
 func NewService(opts ...ServiceOption) *Service {
 	s := &Service{
 		assessmentAddress: DefaultAssessmentAddress,
@@ -154,12 +170,21 @@ func (s *Service) initAssessmentStream(additionalOpts ...grpc.DialOption) error
 }
 
 // Start starts discovery
-func (s *Service) Start(_ context.Context, _ *discovery.StartDiscoveryRequest) (resp *discovery.StartDiscoveryResponse, err error) {
+func (s *Service) Start(_ context.Context, req *discovery.StartDiscoveryRequest) (resp *discovery.StartDiscoveryResponse, err error) {
 	resp = &discovery.StartDiscoveryResponse{Successful: true}
 
 	log.Infof("Starting discovery...")
 	s.scheduler.TagsUnique()
 
+	// Set providers
+	if req == nil || req.Providers == nil || len(req.Providers) == 0 {
+		newError := errors.New("no providers for discovering given")
+		log.Errorf("%s", newError)
+		return nil, status.Errorf(codes.InvalidArgument, "%s", newError)
+	} else {
+		s.providers = req.Providers
+	}
+
 	// Establish connection to assessment component
 	if s.assessmentStream == nil {
 		err = s.initAssessmentStream()
@@ -169,36 +194,46 @@ func (s *Service) Start(_ context.Context, _ *discovery.StartDiscoveryRequest) (
 		}
 	}
 
-	authorizer, err := azure.NewAuthorizer()
-	if err != nil {
-		log.Errorf("Could not authenticate to Azure: %v", err)
-		return nil, status.Errorf(codes.FailedPrecondition, "could not authenticate to Azure: %v", err)
-	}
-
-	k8sClient, err := k8s.AuthFromKubeConfig()
-	if err != nil {
-		log.Errorf("Could not authenticate to Kubernetes: %v", err)
-		return nil, status.Errorf(codes.FailedPrecondition, "could not authenticate to Kubernetes: %v", err)
-	}
-
-	awsClient, err := aws.NewClient()
-	if err != nil {
-		log.Errorf("Could not authenticate to AWS: %v", err)
-		return nil, status.Errorf(codes.FailedPrecondition, "could not authenticate to AWS: %v", err)
-	}
-
 	var discoverer []discovery.Discoverer
 
-	discoverer = append(discoverer,
-		azure.NewAzureARMTemplateDiscovery(azure.WithAuthorizer(authorizer)),
-		azure.NewAzureStorageDiscovery(azure.WithAuthorizer(authorizer)),
-		azure.NewAzureComputeDiscovery(azure.WithAuthorizer(authorizer)),
-		azure.NewAzureNetworkDiscovery(azure.WithAuthorizer(authorizer)),
-		k8s.NewKubernetesComputeDiscovery(k8sClient),
-		k8s.NewKubernetesNetworkDiscovery(k8sClient),
-		aws.NewAwsStorageDiscovery(awsClient),
-		aws.NewAwsComputeDiscovery(awsClient),
-	)
+	// Configure discoverers for given providers
+	for _, provider := range s.providers {
+		switch {
+		case provider == ProviderAzure:
+			authorizer, err := azure.NewAuthorizer()
+			if err != nil {
+				log.Errorf("Could not authenticate to Azure: %v", err)
+				return nil, status.Errorf(codes.FailedPrecondition, "could not authenticate to Azure: %v", err)
+			}
+			discoverer = append(discoverer,
+				azure.NewAzureARMTemplateDiscovery(azure.WithAuthorizer(authorizer)),
+				azure.NewAzureStorageDiscovery(azure.WithAuthorizer(authorizer)),
+				azure.NewAzureComputeDiscovery(azure.WithAuthorizer(authorizer)),
+				azure.NewAzureNetworkDiscovery(azure.WithAuthorizer(authorizer)))
+		case provider == ProviderK8S:
+			k8sClient, err := k8s.AuthFromKubeConfig()
+			if err != nil {
+				log.Errorf("Could not authenticate to Kubernetes: %v", err)
+				return nil, status.Errorf(codes.FailedPrecondition, "could not authenticate to Kubernetes: %v", err)
+			}
+			discoverer = append(discoverer,
+				k8s.NewKubernetesComputeDiscovery(k8sClient),
+				k8s.NewKubernetesNetworkDiscovery(k8sClient))
+		case provider == ProviderAWS:
+			awsClient, err := aws.NewClient()
+			if err != nil {
+				log.Errorf("Could not authenticate to AWS: %v", err)
+				return nil, status.Errorf(codes.FailedPrecondition, "could not authenticate to AWS: %v", err)
+			}
+			discoverer = append(discoverer,
+				aws.NewAwsStorageDiscovery(awsClient),
+				aws.NewAwsComputeDiscovery(awsClient))
+		default:
+			newError := fmt.Errorf("provider %s not known", provider)
+			log.Error(newError)
+			return nil, status.Errorf(codes.InvalidArgument, "%s", newError)
+		}
+	}
 
 	for _, v := range discoverer {
 		s.configurations[v] = &Configuration{


Test patch:
diff --git a/service/discovery/discovery_test.go b/service/discovery/discovery_test.go
index 203ffccb..d28a59ba 100644
--- a/service/discovery/discovery_test.go
+++ b/service/discovery/discovery_test.go
@@ -252,7 +252,9 @@ func TestStart(t *testing.T) {
 	tests := []struct {
 		name           string
 		fields         fields
-		wantResp       *discovery.StartDiscoveryResponse
+		req       *discovery.StartDiscoveryRequest
+		providers []string
+		wantResp  *discovery.StartDiscoveryResponse
 		wantErr        bool
 		wantErrMessage string
 	}{
@@ -267,23 +269,20 @@ func TestStart(t *testing.T) {
 						envVariableKey:   "AZURE_AUTH_LOCATION",
 						envVariableValue: "service/discovery/testdata/credentials_test_file",
 					},
-					{
-						hasEnvVariable:   true,
-						envVariableKey:   "HOME",
-						envVariableValue: "",
-					},
 				},
 			},
-			wantResp:       nil,
-			wantErr:        true,
-			wantErrMessage: "could not authenticate to Kubernetes",
+			req:            &discovery.StartDiscoveryRequest{Providers: []string{ProviderAzure}},
+			providers:      []string{ProviderAzure},
+			wantResp:       &discovery.StartDiscoveryResponse{Successful: true},
+			wantErr:        false,
+			wantErrMessage: "",
 		},
 		{
-			name: "No Azure authorizer from file nor CLI",
+			name: "No Azure authorizer",
 			fields: fields{
 				hasRPCConnection: true,
 				envVariables: []envVariable{
-					// We must set AZURE_AUTH_LOCATION and HOME to a wrong pahth so that both Azure authorizer fail
+					// We must set AZURE_AUTH_LOCATION and HOME to a wrong path so that both Azure authorizer fail
 					{
 						hasEnvVariable:   true,
 						envVariableKey:   "AZURE_AUTH_LOCATION",
@@ -296,6 +295,8 @@ func TestStart(t *testing.T) {
 					},
 				},
 			},
+			req:            &discovery.StartDiscoveryRequest{Providers: []string{ProviderAzure}},
+			providers:      []string{ProviderAzure},
 			wantResp:       nil,
 			wantErr:        true,
 			wantErrMessage: "could not authenticate to Azure",
@@ -305,12 +306,7 @@ func TestStart(t *testing.T) {
 			fields: fields{
 				hasRPCConnection: true,
 				envVariables: []envVariable{
-					// We must set AZURE_AUTH_LOCATION to the Azure credentials test file and the set HOME to a wrong path so that the Azure authorizer passes and the K8S authorizer fails
-					{
-						hasEnvVariable:   true,
-						envVariableKey:   "AZURE_AUTH_LOCATION",
-						envVariableValue: "service/discovery/testdata/credentials_test_file",
-					},
+					// We must set HOME to a wrong path so that the K8S authorizer fails
 					{
 						hasEnvVariable:   true,
 						envVariableKey:   "HOME",
@@ -318,6 +314,8 @@ func TestStart(t *testing.T) {
 					},
 				},
 			},
+			req:            &discovery.StartDiscoveryRequest{Providers: []string{ProviderK8S}},
+			providers:      []string{ProviderK8S},
 			wantResp:       nil,
 			wantErr:        true,
 			wantErrMessage: "could not authenticate to Kubernetes",
@@ -327,10 +325,53 @@ func TestStart(t *testing.T) {
 			fields: fields{
 				hasRPCConnection: false,
 			},
+			req:            &discovery.StartDiscoveryRequest{Providers: []string{"aws", "azure", "k8s"}},
+			providers:      []string{"aws", "azure", "k8s"},
 			wantResp:       nil,
 			wantErr:        true,
 			wantErrMessage: "could not initialize stream to Assessment",
 		},
+		{
+			name: "Request with 2 providers",
+			fields: fields{
+				hasRPCConnection: true,
+				envVariables: []envVariable{
+					// We must set HOME to a wrong path so that the AWS and k8s authorizer fails in all systems, regardless if AWS and k8s paths are set or not
+					{
+						hasEnvVariable:   true,
+						envVariableKey:   "HOME",
+						envVariableValue: "",
+					},
+				},
+			},
+			req:            &discovery.StartDiscoveryRequest{Providers: []string{"aws", "k8s"}},
+			providers:      []string{"aws", "k8s"},
+			wantResp:       nil,
+			wantErr:        true,
+			wantErrMessage: "could not authenticate to",
+		},
+		{
+			name: "Empty request",
+			fields: fields{
+				hasRPCConnection: true,
+			},
+			req:            &discovery.StartDiscoveryRequest{Providers: []string{}},
+			providers:      nil,
+			wantResp:       nil,
+			wantErr:        true,
+			wantErrMessage: "no providers for discovering given",
+		},
+		{
+			name: "Request with wrong provider name",
+			fields: fields{
+				hasRPCConnection: true,
+			},
+			req:            &discovery.StartDiscoveryRequest{Providers: []string{"falseProvider"}},
+			providers:      []string{"falseProvider"},
+			wantResp:       nil,
+			wantErr:        true,
+			wantErrMessage: "provider falseProvider not known",
+		},
 	}
 
 	for _, tt := range tests {
@@ -346,7 +387,7 @@ func TestStart(t *testing.T) {
 				}
 			}
 
-			resp, err := s.Start(context.TODO(), nil)
+			resp, err := s.Start(context.TODO(), tt.req)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("Got Start() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -354,6 +395,9 @@ func TestStart(t *testing.T) {
 				assert.Equal(t, tt.wantResp, resp)
 			}
 
+			if tt.req != nil {
+				assert.Equal(t, tt.providers, s.providers)
+			}
 			if err != nil {
 				assert.Contains(t, err.Error(), tt.wantErrMessage)
 			}