diff --git a/admin/commands/inventory/add_agent_rds_exporter.go b/admin/commands/inventory/add_agent_rds_exporter.go index 42a40d030e9..b200b742b96 100644 --- a/admin/commands/inventory/add_agent_rds_exporter.go +++ b/admin/commands/inventory/add_agent_rds_exporter.go @@ -51,6 +51,7 @@ type AddAgentRDSExporterCommand struct { NodeID string `arg:"" help:"Node identifier"` AWSAccessKey string `help:"AWS Access Key ID"` AWSSecretKey string `help:"AWS Secret Access Key"` + AWSRoleArn string `help:"AWS IAM role ARN to assume"` CustomLabels map[string]string `mapsep:"," help:"Custom user-assigned labels"` SkipConnectionCheck bool `help:"Skip connection check"` DisableBasicMetrics bool `help:"Disable basic metrics"` @@ -70,6 +71,7 @@ func (cmd *AddAgentRDSExporterCommand) RunCmd() (commands.Result, error) { NodeID: cmd.NodeID, AWSAccessKey: cmd.AWSAccessKey, AWSSecretKey: cmd.AWSSecretKey, + AWSRoleArn: cmd.AWSRoleArn, CustomLabels: *customLabels, SkipConnectionCheck: cmd.SkipConnectionCheck, DisableBasicMetrics: cmd.DisableBasicMetrics, diff --git a/admin/commands/inventory/change_agent_rds_exporter.go b/admin/commands/inventory/change_agent_rds_exporter.go index 8972e27074e..81a98bd6b79 100644 --- a/admin/commands/inventory/change_agent_rds_exporter.go +++ b/admin/commands/inventory/change_agent_rds_exporter.go @@ -72,6 +72,7 @@ type ChangeAgentRDSExporterCommand struct { // AWS credentials AWSAccessKey *string `help:"AWS access key"` AWSSecretKey *string `help:"AWS secret key"` + AWSRoleArn *string `help:"AWS IAM role ARN to assume"` // RDS-specific options DisableBasicMetrics *bool `help:"Disable basic metrics"` @@ -95,6 +96,7 @@ func (cmd *ChangeAgentRDSExporterCommand) RunCmd() (commands.Result, error) { Enable: cmd.Enable, AWSAccessKey: cmd.AWSAccessKey, AWSSecretKey: cmd.AWSSecretKey, + AWSRoleArn: cmd.AWSRoleArn, DisableBasicMetrics: cmd.DisableBasicMetrics, DisableEnhancedMetrics: cmd.DisableEnhancedMetrics, EnablePushMetrics: cmd.PushMetrics, @@ -134,6 +136,9 @@ func (cmd *ChangeAgentRDSExporterCommand) RunCmd() (commands.Result, error) { if cmd.AWSSecretKey != nil { changes = append(changes, "updated AWS secret key") } + if cmd.AWSRoleArn != nil { + changes = append(changes, "updated AWS role ARN") + } if cmd.DisableBasicMetrics != nil { if *cmd.DisableBasicMetrics { changes = append(changes, "disabled basic metrics") diff --git a/admin/commands/inventory/change_agent_rds_exporter_test.go b/admin/commands/inventory/change_agent_rds_exporter_test.go index 39ace647fb1..229e7fdb4b3 100644 --- a/admin/commands/inventory/change_agent_rds_exporter_test.go +++ b/admin/commands/inventory/change_agent_rds_exporter_test.go @@ -41,6 +41,7 @@ func TestRDSExporterChangeAgent(t *testing.T) { Enable: new(true), AWSAccessKey: new("AKIAIOSFODNN7EXAMPLE"), AWSSecretKey: new("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"), + AWSRoleArn: new("arn:aws:iam::123456789012:role/PmmRdsReadRole"), DisableBasicMetrics: new(false), DisableEnhancedMetrics: new(true), PushMetrics: new(true), @@ -60,6 +61,7 @@ func TestRDSExporterChangeAgent(t *testing.T) { "enable": true, "aws_access_key": "AKIAIOSFODNN7EXAMPLE", "aws_secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "aws_role_arn": "arn:aws:iam::123456789012:role/PmmRdsReadRole", "disable_basic_metrics": false, "disable_enhanced_metrics": true, "enable_push_metrics": true, @@ -129,6 +131,7 @@ func TestRDSExporterChangeAgent(t *testing.T) { "--enable", "--aws-access-key=AKIATEST123", "--aws-secret-key=secretkey123", + "--aws-role-arn=arn:aws:iam::123456789012:role/PmmRdsReadRole", "--disable-basic-metrics", "--disable-enhanced-metrics", "--push-metrics", @@ -153,6 +156,7 @@ func TestRDSExporterChangeAgent(t *testing.T) { "enable": true, "aws_access_key": "AKIATEST123", "aws_secret_key": "secretkey123", + "aws_role_arn": "arn:aws:iam::123456789012:role/PmmRdsReadRole", "disable_basic_metrics": true, "disable_enhanced_metrics": true, "enable_push_metrics": true, @@ -188,6 +192,7 @@ Configuration changes applied: - enabled agent - updated AWS access key - updated AWS secret key + - updated AWS role ARN - disabled basic metrics - disabled enhanced metrics - enabled push metrics diff --git a/api/inventory/v1/agents.pb.go b/api/inventory/v1/agents.pb.go index 3784fc8b7fc..d750cc9ec03 100644 --- a/api/inventory/v1/agents.pb.go +++ b/api/inventory/v1/agents.pb.go @@ -2801,6 +2801,8 @@ type RDSExporter struct { NodeId string `protobuf:"bytes,4,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` // AWS Access Key. AwsAccessKey string `protobuf:"bytes,5,opt,name=aws_access_key,json=awsAccessKey,proto3" json:"aws_access_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AwsRoleArn string `protobuf:"bytes,27,opt,name=aws_role_arn,json=awsRoleArn,proto3" json:"aws_role_arn,omitempty"` // Custom user-assigned labels. CustomLabels map[string]string `protobuf:"bytes,6,rep,name=custom_labels,json=customLabels,proto3" json:"custom_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Actual Agent status (the same for several configurations). @@ -2890,6 +2892,13 @@ func (x *RDSExporter) GetAwsAccessKey() string { return "" } +func (x *RDSExporter) GetAwsRoleArn() string { + if x != nil { + return x.AwsRoleArn + } + return "" +} + func (x *RDSExporter) GetCustomLabels() map[string]string { if x != nil { return x.CustomLabels @@ -9377,6 +9386,8 @@ type AddRDSExporterParams struct { AwsAccessKey string `protobuf:"bytes,3,opt,name=aws_access_key,json=awsAccessKey,proto3" json:"aws_access_key,omitempty"` // AWS Secret Key. AwsSecretKey string `protobuf:"bytes,4,opt,name=aws_secret_key,json=awsSecretKey,proto3" json:"aws_secret_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AwsRoleArn string `protobuf:"bytes,11,opt,name=aws_role_arn,json=awsRoleArn,proto3" json:"aws_role_arn,omitempty"` // Custom user-assigned labels. CustomLabels map[string]string `protobuf:"bytes,5,rep,name=custom_labels,json=customLabels,proto3" json:"custom_labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Skip connection check. @@ -9451,6 +9462,13 @@ func (x *AddRDSExporterParams) GetAwsSecretKey() string { return "" } +func (x *AddRDSExporterParams) GetAwsRoleArn() string { + if x != nil { + return x.AwsRoleArn + } + return "" +} + func (x *AddRDSExporterParams) GetCustomLabels() map[string]string { if x != nil { return x.CustomLabels @@ -9507,6 +9525,8 @@ type ChangeRDSExporterParams struct { AwsAccessKey *string `protobuf:"bytes,5,opt,name=aws_access_key,json=awsAccessKey,proto3,oneof" json:"aws_access_key,omitempty"` // AWS Secret Key. AwsSecretKey *string `protobuf:"bytes,6,opt,name=aws_secret_key,json=awsSecretKey,proto3,oneof" json:"aws_secret_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AwsRoleArn *string `protobuf:"bytes,10,opt,name=aws_role_arn,json=awsRoleArn,proto3,oneof" json:"aws_role_arn,omitempty"` // Disable basic metrics. DisableBasicMetrics *bool `protobuf:"varint,7,opt,name=disable_basic_metrics,json=disableBasicMetrics,proto3,oneof" json:"disable_basic_metrics,omitempty"` // Disable enhanced metrics. @@ -9589,6 +9609,13 @@ func (x *ChangeRDSExporterParams) GetAwsSecretKey() string { return "" } +func (x *ChangeRDSExporterParams) GetAwsRoleArn() string { + if x != nil && x.AwsRoleArn != nil { + return *x.AwsRoleArn + } + return "" +} + func (x *ChangeRDSExporterParams) GetDisableBasicMetrics() bool { if x != nil && x.DisableBasicMetrics != nil { return *x.DisableBasicMetrics @@ -11279,14 +11306,16 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\tlog_level\x18\x16 \x01(\x0e2\x16.inventory.v1.LogLevelR\blogLevel\x1a?\n" + "\x11CustomLabelsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x96\x06\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xb8\x06\n" + "\vRDSExporter\x12\x19\n" + "\bagent_id\x18\x01 \x01(\tR\aagentId\x12 \n" + "\fpmm_agent_id\x18\x02 \x01(\tR\n" + "pmmAgentId\x12\x1a\n" + "\bdisabled\x18\x03 \x01(\bR\bdisabled\x12\x17\n" + "\anode_id\x18\x04 \x01(\tR\x06nodeId\x12*\n" + - "\x0eaws_access_key\x18\x05 \x01(\tB\x04\x88\xb5\x18\x01R\fawsAccessKey\x12P\n" + + "\x0eaws_access_key\x18\x05 \x01(\tB\x04\x88\xb5\x18\x01R\fawsAccessKey\x12 \n" + + "\faws_role_arn\x18\x1b \x01(\tR\n" + + "awsRoleArn\x12P\n" + "\rcustom_labels\x18\x06 \x03(\v2+.inventory.v1.RDSExporter.CustomLabelsEntryR\fcustomLabels\x121\n" + "\x06status\x18\n" + " \x01(\x0e2\x19.inventory.v1.AgentStatusR\x06status\x12\x1f\n" + @@ -12125,13 +12154,15 @@ const file_inventory_v1_agents_proto_rawDesc = "" + "\n" + "\b_tls_keyB\f\n" + "\n" + - "_log_level\"\xd1\x04\n" + + "_log_level\"\xf3\x04\n" + "\x14AddRDSExporterParams\x12)\n" + "\fpmm_agent_id\x18\x01 \x01(\tB\a\xfaB\x04r\x02\x10\x01R\n" + "pmmAgentId\x12 \n" + "\anode_id\x18\x02 \x01(\tB\a\xfaB\x04r\x02\x10\x01R\x06nodeId\x12*\n" + "\x0eaws_access_key\x18\x03 \x01(\tB\x04\x88\xb5\x18\x01R\fawsAccessKey\x12*\n" + - "\x0eaws_secret_key\x18\x04 \x01(\tB\x04\x88\xb5\x18\x01R\fawsSecretKey\x12Y\n" + + "\x0eaws_secret_key\x18\x04 \x01(\tB\x04\x88\xb5\x18\x01R\fawsSecretKey\x12 \n" + + "\faws_role_arn\x18\v \x01(\tR\n" + + "awsRoleArn\x12Y\n" + "\rcustom_labels\x18\x05 \x03(\v24.inventory.v1.AddRDSExporterParams.CustomLabelsEntryR\fcustomLabels\x122\n" + "\x15skip_connection_check\x18\x06 \x01(\bR\x13skipConnectionCheck\x122\n" + "\x15disable_basic_metrics\x18\a \x01(\bR\x13disableBasicMetrics\x128\n" + @@ -12141,22 +12172,26 @@ const file_inventory_v1_agents_proto_rawDesc = "" + " \x01(\x0e2\x16.inventory.v1.LogLevelR\blogLevel\x1a?\n" + "\x11CustomLabelsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa9\x05\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xe1\x05\n" + "\x17ChangeRDSExporterParams\x12\x1b\n" + "\x06enable\x18\x01 \x01(\bH\x00R\x06enable\x88\x01\x01\x12;\n" + "\rcustom_labels\x18\x02 \x01(\v2\x11.common.StringMapH\x01R\fcustomLabels\x88\x01\x01\x123\n" + "\x13enable_push_metrics\x18\x03 \x01(\bH\x02R\x11enablePushMetrics\x88\x01\x01\x12K\n" + "\x13metrics_resolutions\x18\x04 \x01(\v2\x1a.common.MetricsResolutionsR\x12metricsResolutions\x12/\n" + "\x0eaws_access_key\x18\x05 \x01(\tB\x04\x88\xb5\x18\x01H\x03R\fawsAccessKey\x88\x01\x01\x12/\n" + - "\x0eaws_secret_key\x18\x06 \x01(\tB\x04\x88\xb5\x18\x01H\x04R\fawsSecretKey\x88\x01\x01\x127\n" + - "\x15disable_basic_metrics\x18\a \x01(\bH\x05R\x13disableBasicMetrics\x88\x01\x01\x12=\n" + - "\x18disable_enhanced_metrics\x18\b \x01(\bH\x06R\x16disableEnhancedMetrics\x88\x01\x01\x128\n" + - "\tlog_level\x18\t \x01(\x0e2\x16.inventory.v1.LogLevelH\aR\blogLevel\x88\x01\x01B\t\n" + + "\x0eaws_secret_key\x18\x06 \x01(\tB\x04\x88\xb5\x18\x01H\x04R\fawsSecretKey\x88\x01\x01\x12%\n" + + "\faws_role_arn\x18\n" + + " \x01(\tH\x05R\n" + + "awsRoleArn\x88\x01\x01\x127\n" + + "\x15disable_basic_metrics\x18\a \x01(\bH\x06R\x13disableBasicMetrics\x88\x01\x01\x12=\n" + + "\x18disable_enhanced_metrics\x18\b \x01(\bH\aR\x16disableEnhancedMetrics\x88\x01\x01\x128\n" + + "\tlog_level\x18\t \x01(\x0e2\x16.inventory.v1.LogLevelH\bR\blogLevel\x88\x01\x01B\t\n" + "\a_enableB\x10\n" + "\x0e_custom_labelsB\x16\n" + "\x14_enable_push_metricsB\x11\n" + "\x0f_aws_access_keyB\x11\n" + - "\x0f_aws_secret_keyB\x18\n" + + "\x0f_aws_secret_keyB\x0f\n" + + "\r_aws_role_arnB\x18\n" + "\x16_disable_basic_metricsB\x1b\n" + "\x19_disable_enhanced_metricsB\f\n" + "\n" + diff --git a/api/inventory/v1/agents.pb.validate.go b/api/inventory/v1/agents.pb.validate.go index 0c310df49e6..eef8abe0c84 100644 --- a/api/inventory/v1/agents.pb.validate.go +++ b/api/inventory/v1/agents.pb.validate.go @@ -2581,6 +2581,8 @@ func (m *RDSExporter) validate(all bool) error { // no validation rules for AwsAccessKey + // no validation rules for AwsRoleArn + // no validation rules for CustomLabels // no validation rules for Status @@ -12997,6 +12999,8 @@ func (m *AddRDSExporterParams) validate(all bool) error { // no validation rules for AwsSecretKey + // no validation rules for AwsRoleArn + // no validation rules for CustomLabels // no validation rules for SkipConnectionCheck @@ -13188,6 +13192,10 @@ func (m *ChangeRDSExporterParams) validate(all bool) error { // no validation rules for AwsSecretKey } + if m.AwsRoleArn != nil { + // no validation rules for AwsRoleArn + } + if m.DisableBasicMetrics != nil { // no validation rules for DisableBasicMetrics } diff --git a/api/inventory/v1/agents.proto b/api/inventory/v1/agents.proto index fea2b5df13e..0e3d846e59b 100644 --- a/api/inventory/v1/agents.proto +++ b/api/inventory/v1/agents.proto @@ -658,6 +658,8 @@ message RDSExporter { string node_id = 4; // AWS Access Key. string aws_access_key = 5 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; + // AWS IAM role ARN to assume for RDS metrics collection. + string aws_role_arn = 27; // Custom user-assigned labels. map custom_labels = 6; @@ -1794,6 +1796,8 @@ message AddRDSExporterParams { string aws_access_key = 3 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; // AWS Secret Key. string aws_secret_key = 4 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; + // AWS IAM role ARN to assume for RDS metrics collection. + string aws_role_arn = 11; // Custom user-assigned labels. map custom_labels = 5; // Skip connection check. @@ -1821,6 +1825,8 @@ message ChangeRDSExporterParams { optional string aws_access_key = 5 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; // AWS Secret Key. optional string aws_secret_key = 6 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; + // AWS IAM role ARN to assume for RDS metrics collection. + optional string aws_role_arn = 10; // Disable basic metrics. optional bool disable_basic_metrics = 7; // Disable enhanced metrics. diff --git a/api/inventory/v1/json/client/agents_service/add_agent_responses.go b/api/inventory/v1/json/client/agents_service/add_agent_responses.go index ea0b289313f..54854a5f288 100644 --- a/api/inventory/v1/json/client/agents_service/add_agent_responses.go +++ b/api/inventory/v1/json/client/agents_service/add_agent_responses.go @@ -6078,6 +6078,9 @@ type AddAgentOKBodyRDSExporter struct { // AWS Access Key. AWSAccessKey string `json:"aws_access_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AWSRoleArn string `json:"aws_role_arn,omitempty"` + // Custom user-assigned labels. CustomLabels map[string]string `json:"custom_labels,omitempty"` @@ -8832,6 +8835,9 @@ type AddAgentParamsBodyRDSExporter struct { // AWS Secret Key. AWSSecretKey string `json:"aws_secret_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AWSRoleArn string `json:"aws_role_arn,omitempty"` + // Custom user-assigned labels. CustomLabels map[string]string `json:"custom_labels,omitempty"` diff --git a/api/inventory/v1/json/client/agents_service/change_agent_responses.go b/api/inventory/v1/json/client/agents_service/change_agent_responses.go index 76c5dc89783..bfb4d916ba2 100644 --- a/api/inventory/v1/json/client/agents_service/change_agent_responses.go +++ b/api/inventory/v1/json/client/agents_service/change_agent_responses.go @@ -6159,6 +6159,9 @@ type ChangeAgentOKBodyRDSExporter struct { // AWS Access Key. AWSAccessKey string `json:"aws_access_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AWSRoleArn string `json:"aws_role_arn,omitempty"` + // Custom user-assigned labels. CustomLabels map[string]string `json:"custom_labels,omitempty"` @@ -11421,6 +11424,9 @@ type ChangeAgentParamsBodyRDSExporter struct { // AWS Secret Key. AWSSecretKey *string `json:"aws_secret_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AWSRoleArn *string `json:"aws_role_arn,omitempty"` + // Disable basic metrics. DisableBasicMetrics *bool `json:"disable_basic_metrics,omitempty"` diff --git a/api/inventory/v1/json/client/agents_service/get_agent_responses.go b/api/inventory/v1/json/client/agents_service/get_agent_responses.go index 9f4fc725525..e5cefbaca51 100644 --- a/api/inventory/v1/json/client/agents_service/get_agent_responses.go +++ b/api/inventory/v1/json/client/agents_service/get_agent_responses.go @@ -5294,6 +5294,9 @@ type GetAgentOKBodyRDSExporter struct { // AWS Access Key. AWSAccessKey string `json:"aws_access_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AWSRoleArn string `json:"aws_role_arn,omitempty"` + // Custom user-assigned labels. CustomLabels map[string]string `json:"custom_labels,omitempty"` diff --git a/api/inventory/v1/json/client/agents_service/list_agents_responses.go b/api/inventory/v1/json/client/agents_service/list_agents_responses.go index 0bffc1a715a..5772a2e2b2f 100644 --- a/api/inventory/v1/json/client/agents_service/list_agents_responses.go +++ b/api/inventory/v1/json/client/agents_service/list_agents_responses.go @@ -5465,6 +5465,9 @@ type ListAgentsOKBodyRDSExporterItems0 struct { // AWS Access Key. AWSAccessKey string `json:"aws_access_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AWSRoleArn string `json:"aws_role_arn,omitempty"` + // Custom user-assigned labels. CustomLabels map[string]string `json:"custom_labels,omitempty"` diff --git a/api/inventory/v1/json/v1.json b/api/inventory/v1/json/v1.json index 1b0a2395e83..ee8a54d6cbd 100644 --- a/api/inventory/v1/json/v1.json +++ b/api/inventory/v1/json/v1.json @@ -1717,13 +1717,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -1739,33 +1744,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -1780,13 +1785,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -1808,7 +1813,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } } }, @@ -2884,33 +2889,38 @@ "type": "string", "x-order": 3 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 4 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 4 + "x-order": 5 }, "skip_connection_check": { "description": "Skip connection check.", "type": "boolean", - "x-order": 5 + "x-order": 6 }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", - "x-order": 6 + "x-order": 7 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", - "x-order": 7 + "x-order": 8 }, "push_metrics": { "description": "Enables push metrics mode for exporter.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -2925,7 +2935,7 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 9 + "x-order": 10 } }, "x-order": 7 @@ -4721,13 +4731,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -4743,33 +4758,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -4784,13 +4799,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -4812,7 +4827,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 7 @@ -7440,13 +7455,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -7462,33 +7482,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -7503,13 +7523,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -7531,7 +7551,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 14 @@ -8805,17 +8825,23 @@ "x-nullable": true, "x-order": 5 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-nullable": true, + "x-order": 6 + }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", "x-nullable": true, - "x-order": 6 + "x-order": 7 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", "x-nullable": true, - "x-order": 7 + "x-order": 8 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -8831,7 +8857,7 @@ "LOG_LEVEL_DEBUG" ], "x-nullable": true, - "x-order": 8 + "x-order": 9 } }, "x-order": 6 @@ -10883,13 +10909,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -10905,33 +10936,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -10946,13 +10977,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -10974,7 +11005,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 6 diff --git a/api/management/v1/json/client/management_service/add_service_responses.go b/api/management/v1/json/client/management_service/add_service_responses.go index 357450d0c64..fc9e3092d6b 100644 --- a/api/management/v1/json/client/management_service/add_service_responses.go +++ b/api/management/v1/json/client/management_service/add_service_responses.go @@ -8535,6 +8535,9 @@ type AddServiceOKBodyRDSRDSExporter struct { // AWS Access Key. AWSAccessKey string `json:"aws_access_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics collection. + AWSRoleArn string `json:"aws_role_arn,omitempty"` + // Custom user-assigned labels. CustomLabels map[string]string `json:"custom_labels,omitempty"` @@ -11835,6 +11838,9 @@ type AddServiceParamsBodyRDS struct { // AWS Secret key. AWSSecretKey string `json:"aws_secret_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics discovery and collection. + AWSRoleArn string `json:"aws_role_arn,omitempty"` + // If true, adds rds_exporter. RDSExporter bool `json:"rds_exporter,omitempty"` diff --git a/api/management/v1/json/client/management_service/discover_rds_responses.go b/api/management/v1/json/client/management_service/discover_rds_responses.go index 4f3715bd83c..1bb1cca2653 100644 --- a/api/management/v1/json/client/management_service/discover_rds_responses.go +++ b/api/management/v1/json/client/management_service/discover_rds_responses.go @@ -190,11 +190,14 @@ DiscoverRDSBody discover RDS body swagger:model DiscoverRDSBody */ type DiscoverRDSBody struct { - // AWS Access key. Optional. + // AWS Access key. Optional. Used as source credentials when aws_role_arn is set. AWSAccessKey string `json:"aws_access_key,omitempty"` - // AWS Secret key. Optional. + // AWS Secret key. Optional. Used as source credentials when aws_role_arn is set. AWSSecretKey string `json:"aws_secret_key,omitempty"` + + // AWS IAM role ARN to assume before discovering RDS instances. Optional. + AWSRoleArn string `json:"aws_role_arn,omitempty"` } // Validate validates this discover RDS body diff --git a/api/management/v1/json/v1.json b/api/management/v1/json/v1.json index 98e5b993d75..6468e3a7f4c 100644 --- a/api/management/v1/json/v1.json +++ b/api/management/v1/json/v1.json @@ -3485,15 +3485,20 @@ "type": "string", "x-order": 16 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics discovery and collection.", + "type": "string", + "x-order": 17 + }, "rds_exporter": { "description": "If true, adds rds_exporter.", "type": "boolean", - "x-order": 17 + "x-order": 18 }, "qan_mysql_perfschema": { "description": "If true, adds qan-mysql-perfschema-agent.", "type": "boolean", - "x-order": 18 + "x-order": 19 }, "custom_labels": { "description": "Custom user-assigned labels for Node and Service.", @@ -3501,43 +3506,43 @@ "additionalProperties": { "type": "string" }, - "x-order": 19 + "x-order": 20 }, "skip_connection_check": { "description": "Skip connection check.", "type": "boolean", - "x-order": 20 + "x-order": 21 }, "tls": { "description": "Use TLS for database connections.", "type": "boolean", - "x-order": 21 + "x-order": 22 }, "tls_skip_verify": { "description": "Skip TLS certificate and hostname validation.", "type": "boolean", - "x-order": 22 + "x-order": 23 }, "disable_query_examples": { "description": "Disable query examples.", "type": "boolean", - "x-order": 23 + "x-order": 24 }, "tablestats_group_table_limit": { "description": "Tablestats group collectors will be disabled if there are more than that number of tables.\nIf zero, server's default value is used.\nUse negative value to disable them.", "type": "integer", "format": "int32", - "x-order": 24 + "x-order": 25 }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", - "x-order": 25 + "x-order": 26 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", - "x-order": 26 + "x-order": 27 }, "metrics_mode": { "description": "MetricsMode defines desired metrics mode for agent,\nit can be pull, push or auto mode chosen by server.\n\n - METRICS_MODE_UNSPECIFIED: Auto", @@ -3548,33 +3553,33 @@ "METRICS_MODE_PULL", "METRICS_MODE_PUSH" ], - "x-order": 27 + "x-order": 28 }, "qan_postgresql_pgstatements": { "type": "boolean", "title": "If true, add qan-pgstatements", - "x-order": 28 + "x-order": 29 }, "agent_password": { "description": "Custom password for exporter endpoint /metrics.", "type": "string", - "x-order": 29 + "x-order": 30 }, "database": { "description": "Database name.", "type": "string", - "x-order": 30 + "x-order": 31 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 31 + "x-order": 32 }, "disable_comments_parsing": { "description": "Disable parsing comments from queries and showing them in QAN.", "type": "boolean", - "x-order": 32 + "x-order": 33 }, "max_postgresql_exporter_connections": { "description": "Maximum number of exporter connections to PostgreSQL instance.", @@ -5910,13 +5915,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -5932,33 +5942,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -5973,13 +5983,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -6001,7 +6011,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 1 @@ -7385,14 +7395,19 @@ "type": "object", "properties": { "aws_access_key": { - "description": "AWS Access key. Optional.", + "description": "AWS Access key. Optional. Used as source credentials when aws_role_arn is set.", "type": "string", "x-order": 0 }, "aws_secret_key": { - "description": "AWS Secret key. Optional.", + "description": "AWS Secret key. Optional. Used as source credentials when aws_role_arn is set.", "type": "string", "x-order": 1 + }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume before discovering RDS instances. Optional.", + "type": "string", + "x-order": 2 } } } diff --git a/api/management/v1/rds.pb.go b/api/management/v1/rds.pb.go index d338efd3738..6a729b8f9c8 100644 --- a/api/management/v1/rds.pb.go +++ b/api/management/v1/rds.pb.go @@ -188,10 +188,12 @@ func (x *DiscoverRDSInstance) GetEngineVersion() string { type DiscoverRDSRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // AWS Access key. Optional. + // AWS Access key. Optional. Used as source credentials when aws_role_arn is set. AwsAccessKey string `protobuf:"bytes,1,opt,name=aws_access_key,json=awsAccessKey,proto3" json:"aws_access_key,omitempty"` - // AWS Secret key. Optional. - AwsSecretKey string `protobuf:"bytes,2,opt,name=aws_secret_key,json=awsSecretKey,proto3" json:"aws_secret_key,omitempty"` + // AWS Secret key. Optional. Used as source credentials when aws_role_arn is set. + AwsSecretKey string `protobuf:"bytes,2,opt,name=aws_secret_key,json=awsSecretKey,proto3" json:"aws_secret_key,omitempty"` + // AWS IAM role ARN to assume before discovering RDS instances. Optional. + AwsRoleArn string `protobuf:"bytes,3,opt,name=aws_role_arn,json=awsRoleArn,proto3" json:"aws_role_arn,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -240,6 +242,13 @@ func (x *DiscoverRDSRequest) GetAwsSecretKey() string { return "" } +func (x *DiscoverRDSRequest) GetAwsRoleArn() string { + if x != nil { + return x.AwsRoleArn + } + return "" +} + type DiscoverRDSResponse struct { state protoimpl.MessageState `protogen:"open.v1"` RdsInstances []*DiscoverRDSInstance `protobuf:"bytes,1,rep,name=rds_instances,json=rdsInstances,proto3" json:"rds_instances,omitempty"` @@ -320,6 +329,8 @@ type AddRDSServiceParams struct { AwsAccessKey string `protobuf:"bytes,15,opt,name=aws_access_key,json=awsAccessKey,proto3" json:"aws_access_key,omitempty"` // AWS Secret key. AwsSecretKey string `protobuf:"bytes,16,opt,name=aws_secret_key,json=awsSecretKey,proto3" json:"aws_secret_key,omitempty"` + // AWS IAM role ARN to assume for RDS metrics discovery and collection. + AwsRoleArn string `protobuf:"bytes,36,opt,name=aws_role_arn,json=awsRoleArn,proto3" json:"aws_role_arn,omitempty"` // If true, adds rds_exporter. RdsExporter bool `protobuf:"varint,17,opt,name=rds_exporter,json=rdsExporter,proto3" json:"rds_exporter,omitempty"` // If true, adds qan-mysql-perfschema-agent. @@ -512,6 +523,13 @@ func (x *AddRDSServiceParams) GetAwsSecretKey() string { return "" } +func (x *AddRDSServiceParams) GetAwsRoleArn() string { + if x != nil { + return x.AwsRoleArn + } + return "" +} + func (x *AddRDSServiceParams) GetRdsExporter() bool { if x != nil { return x.RdsExporter @@ -753,12 +771,14 @@ const file_management_v1_rds_proto_rawDesc = "" + "\aaddress\x18\x05 \x01(\tR\aaddress\x12\x12\n" + "\x04port\x18\x06 \x01(\rR\x04port\x128\n" + "\x06engine\x18\a \x01(\x0e2 .management.v1.DiscoverRDSEngineR\x06engine\x12%\n" + - "\x0eengine_version\x18\b \x01(\tR\rengineVersion\"l\n" + + "\x0eengine_version\x18\b \x01(\tR\rengineVersion\"\x8e\x01\n" + "\x12DiscoverRDSRequest\x12*\n" + "\x0eaws_access_key\x18\x01 \x01(\tB\x04\x88\xb5\x18\x01R\fawsAccessKey\x12*\n" + - "\x0eaws_secret_key\x18\x02 \x01(\tB\x04\x88\xb5\x18\x01R\fawsSecretKey\"^\n" + + "\x0eaws_secret_key\x18\x02 \x01(\tB\x04\x88\xb5\x18\x01R\fawsSecretKey\x12 \n" + + "\faws_role_arn\x18\x03 \x01(\tR\n" + + "awsRoleArn\"^\n" + "\x13DiscoverRDSResponse\x12G\n" + - "\rrds_instances\x18\x01 \x03(\v2\".management.v1.DiscoverRDSInstanceR\frdsInstances\"\x8e\r\n" + + "\rrds_instances\x18\x01 \x03(\v2\".management.v1.DiscoverRDSInstanceR\frdsInstances\"\xb0\r\n" + "\x13AddRDSServiceParams\x12\x1f\n" + "\x06region\x18\x01 \x01(\tB\a\xfaB\x04r\x02\x10\x01R\x06region\x12\x0e\n" + "\x02az\x18\x02 \x01(\tR\x02az\x12(\n" + @@ -780,7 +800,9 @@ const file_management_v1_rds_proto_rawDesc = "" + "\busername\x18\r \x01(\tB\v\xfaB\x04r\x02\x10\x01\x88\xb5\x18\x01R\busername\x12 \n" + "\bpassword\x18\x0e \x01(\tB\x04\x88\xb5\x18\x01R\bpassword\x12*\n" + "\x0eaws_access_key\x18\x0f \x01(\tB\x04\x88\xb5\x18\x01R\fawsAccessKey\x12*\n" + - "\x0eaws_secret_key\x18\x10 \x01(\tB\x04\x88\xb5\x18\x01R\fawsSecretKey\x12!\n" + + "\x0eaws_secret_key\x18\x10 \x01(\tB\x04\x88\xb5\x18\x01R\fawsSecretKey\x12 \n" + + "\faws_role_arn\x18$ \x01(\tR\n" + + "awsRoleArn\x12!\n" + "\frds_exporter\x18\x11 \x01(\bR\vrdsExporter\x120\n" + "\x14qan_mysql_perfschema\x18\x12 \x01(\bR\x12qanMysqlPerfschema\x12Y\n" + "\rcustom_labels\x18\x13 \x03(\v24.management.v1.AddRDSServiceParams.CustomLabelsEntryR\fcustomLabels\x122\n" + diff --git a/api/management/v1/rds.pb.validate.go b/api/management/v1/rds.pb.validate.go index 1b4ec4c79b0..970fe3e2a34 100644 --- a/api/management/v1/rds.pb.validate.go +++ b/api/management/v1/rds.pb.validate.go @@ -180,6 +180,8 @@ func (m *DiscoverRDSRequest) validate(all bool) error { // no validation rules for AwsSecretKey + // no validation rules for AwsRoleArn + if len(errors) > 0 { return DiscoverRDSRequestMultiError(errors) } @@ -499,6 +501,8 @@ func (m *AddRDSServiceParams) validate(all bool) error { // no validation rules for AwsSecretKey + // no validation rules for AwsRoleArn + // no validation rules for RdsExporter // no validation rules for QanMysqlPerfschema diff --git a/api/management/v1/rds.proto b/api/management/v1/rds.proto index 043b6156a4e..0b6bbfa501e 100644 --- a/api/management/v1/rds.proto +++ b/api/management/v1/rds.proto @@ -38,10 +38,12 @@ message DiscoverRDSInstance { } message DiscoverRDSRequest { - // AWS Access key. Optional. + // AWS Access key. Optional. Used as source credentials when aws_role_arn is set. string aws_access_key = 1 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; - // AWS Secret key. Optional. + // AWS Secret key. Optional. Used as source credentials when aws_role_arn is set. string aws_secret_key = 2 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; + // AWS IAM role ARN to assume before discovering RDS instances. Optional. + string aws_role_arn = 3; } message DiscoverRDSResponse { @@ -86,6 +88,8 @@ message AddRDSServiceParams { string aws_access_key = 15 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; // AWS Secret key. string aws_secret_key = 16 [(extensions.v1.sensitive) = REDACT_TYPE_FULL]; + // AWS IAM role ARN to assume for RDS metrics discovery and collection. + string aws_role_arn = 36; // If true, adds rds_exporter. bool rds_exporter = 17; // If true, adds qan-mysql-perfschema-agent. diff --git a/api/swagger/swagger-dev.json b/api/swagger/swagger-dev.json index 0bc31d31651..8290585b9a3 100644 --- a/api/swagger/swagger-dev.json +++ b/api/swagger/swagger-dev.json @@ -6990,13 +6990,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -7012,33 +7017,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -7053,13 +7058,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -7081,7 +7086,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } } }, @@ -8157,33 +8162,38 @@ "type": "string", "x-order": 3 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 4 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 4 + "x-order": 5 }, "skip_connection_check": { "description": "Skip connection check.", "type": "boolean", - "x-order": 5 + "x-order": 6 }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", - "x-order": 6 + "x-order": 7 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", - "x-order": 7 + "x-order": 8 }, "push_metrics": { "description": "Enables push metrics mode for exporter.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -8198,7 +8208,7 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 9 + "x-order": 10 } }, "x-order": 7 @@ -9994,13 +10004,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -10016,33 +10031,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -10057,13 +10072,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -10085,7 +10100,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 7 @@ -12713,13 +12728,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -12735,33 +12755,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -12776,13 +12796,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -12804,7 +12824,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 14 @@ -14078,17 +14098,23 @@ "x-nullable": true, "x-order": 5 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-nullable": true, + "x-order": 6 + }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", "x-nullable": true, - "x-order": 6 + "x-order": 7 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", "x-nullable": true, - "x-order": 7 + "x-order": 8 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -14104,7 +14130,7 @@ "LOG_LEVEL_DEBUG" ], "x-nullable": true, - "x-order": 8 + "x-order": 9 } }, "x-order": 6 @@ -16156,13 +16182,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -16178,33 +16209,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -16219,13 +16250,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -16247,7 +16278,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 6 @@ -24856,15 +24887,20 @@ "type": "string", "x-order": 16 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics discovery and collection.", + "type": "string", + "x-order": 17 + }, "rds_exporter": { "description": "If true, adds rds_exporter.", "type": "boolean", - "x-order": 17 + "x-order": 18 }, "qan_mysql_perfschema": { "description": "If true, adds qan-mysql-perfschema-agent.", "type": "boolean", - "x-order": 18 + "x-order": 19 }, "custom_labels": { "description": "Custom user-assigned labels for Node and Service.", @@ -24872,43 +24908,43 @@ "additionalProperties": { "type": "string" }, - "x-order": 19 + "x-order": 20 }, "skip_connection_check": { "description": "Skip connection check.", "type": "boolean", - "x-order": 20 + "x-order": 21 }, "tls": { "description": "Use TLS for database connections.", "type": "boolean", - "x-order": 21 + "x-order": 22 }, "tls_skip_verify": { "description": "Skip TLS certificate and hostname validation.", "type": "boolean", - "x-order": 22 + "x-order": 23 }, "disable_query_examples": { "description": "Disable query examples.", "type": "boolean", - "x-order": 23 + "x-order": 24 }, "tablestats_group_table_limit": { "description": "Tablestats group collectors will be disabled if there are more than that number of tables.\nIf zero, server's default value is used.\nUse negative value to disable them.", "type": "integer", "format": "int32", - "x-order": 24 + "x-order": 25 }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", - "x-order": 25 + "x-order": 26 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", - "x-order": 26 + "x-order": 27 }, "metrics_mode": { "description": "MetricsMode defines desired metrics mode for agent,\nit can be pull, push or auto mode chosen by server.\n\n - METRICS_MODE_UNSPECIFIED: Auto", @@ -24919,44 +24955,44 @@ "METRICS_MODE_PULL", "METRICS_MODE_PUSH" ], - "x-order": 27 + "x-order": 28 }, "qan_postgresql_pgstatements": { "type": "boolean", "title": "If true, add qan-pgstatements", - "x-order": 28 + "x-order": 29 }, "agent_password": { "description": "Custom password for exporter endpoint /metrics.", "type": "string", - "x-order": 29 + "x-order": 30 }, "database": { "description": "Database name.", "type": "string", - "x-order": 30 + "x-order": 31 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 31 + "x-order": 32 }, "disable_comments_parsing": { "description": "Disable parsing comments from queries and showing them in QAN.", "type": "boolean", - "x-order": 32 + "x-order": 33 }, "max_postgresql_exporter_connections": { "description": "Maximum number of exporter connections to PostgreSQL instance.", "type": "integer", "format": "int32", - "x-order": 33 + "x-order": 34 }, "connection_timeout": { "description": "Connection timeout for exporter (if set).", "type": "string", - "x-order": 34 + "x-order": 35 } }, "x-order": 6 @@ -27281,13 +27317,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -27303,33 +27344,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -27344,13 +27385,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -27372,7 +27413,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 1 @@ -28756,14 +28797,19 @@ "type": "object", "properties": { "aws_access_key": { - "description": "AWS Access key. Optional.", + "description": "AWS Access key. Optional. Used as source credentials when aws_role_arn is set.", "type": "string", "x-order": 0 }, "aws_secret_key": { - "description": "AWS Secret key. Optional.", + "description": "AWS Secret key. Optional. Used as source credentials when aws_role_arn is set.", "type": "string", "x-order": 1 + }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume before discovering RDS instances. Optional.", + "type": "string", + "x-order": 2 } } } diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index ae34b9296a5..2fd49bb7da9 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -6032,13 +6032,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -6054,33 +6059,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -6095,13 +6100,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -6123,7 +6128,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } } }, @@ -7199,33 +7204,38 @@ "type": "string", "x-order": 3 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 4 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 4 + "x-order": 5 }, "skip_connection_check": { "description": "Skip connection check.", "type": "boolean", - "x-order": 5 + "x-order": 6 }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", - "x-order": 6 + "x-order": 7 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", - "x-order": 7 + "x-order": 8 }, "push_metrics": { "description": "Enables push metrics mode for exporter.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -7240,7 +7250,7 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 9 + "x-order": 10 } }, "x-order": 7 @@ -9036,13 +9046,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -9058,33 +9073,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -9099,13 +9114,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -9127,7 +9142,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 7 @@ -11755,13 +11770,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -11777,33 +11797,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -11818,13 +11838,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -11846,7 +11866,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 14 @@ -13120,17 +13140,23 @@ "x-nullable": true, "x-order": 5 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-nullable": true, + "x-order": 6 + }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", "x-nullable": true, - "x-order": 6 + "x-order": 7 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", "x-nullable": true, - "x-order": 7 + "x-order": 8 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -13146,7 +13172,7 @@ "LOG_LEVEL_DEBUG" ], "x-nullable": true, - "x-order": 8 + "x-order": 9 } }, "x-order": 6 @@ -15198,13 +15224,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -15220,33 +15251,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -15261,13 +15292,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -15289,7 +15320,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 6 @@ -23898,15 +23929,20 @@ "type": "string", "x-order": 16 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics discovery and collection.", + "type": "string", + "x-order": 17 + }, "rds_exporter": { "description": "If true, adds rds_exporter.", "type": "boolean", - "x-order": 17 + "x-order": 18 }, "qan_mysql_perfschema": { "description": "If true, adds qan-mysql-perfschema-agent.", "type": "boolean", - "x-order": 18 + "x-order": 19 }, "custom_labels": { "description": "Custom user-assigned labels for Node and Service.", @@ -23914,43 +23950,43 @@ "additionalProperties": { "type": "string" }, - "x-order": 19 + "x-order": 20 }, "skip_connection_check": { "description": "Skip connection check.", "type": "boolean", - "x-order": 20 + "x-order": 21 }, "tls": { "description": "Use TLS for database connections.", "type": "boolean", - "x-order": 21 + "x-order": 22 }, "tls_skip_verify": { "description": "Skip TLS certificate and hostname validation.", "type": "boolean", - "x-order": 22 + "x-order": 23 }, "disable_query_examples": { "description": "Disable query examples.", "type": "boolean", - "x-order": 23 + "x-order": 24 }, "tablestats_group_table_limit": { "description": "Tablestats group collectors will be disabled if there are more than that number of tables.\nIf zero, server's default value is used.\nUse negative value to disable them.", "type": "integer", "format": "int32", - "x-order": 24 + "x-order": 25 }, "disable_basic_metrics": { "description": "Disable basic metrics.", "type": "boolean", - "x-order": 25 + "x-order": 26 }, "disable_enhanced_metrics": { "description": "Disable enhanced metrics.", "type": "boolean", - "x-order": 26 + "x-order": 27 }, "metrics_mode": { "description": "MetricsMode defines desired metrics mode for agent,\nit can be pull, push or auto mode chosen by server.\n\n - METRICS_MODE_UNSPECIFIED: Auto", @@ -23961,44 +23997,44 @@ "METRICS_MODE_PULL", "METRICS_MODE_PUSH" ], - "x-order": 27 + "x-order": 28 }, "qan_postgresql_pgstatements": { "type": "boolean", "title": "If true, add qan-pgstatements", - "x-order": 28 + "x-order": 29 }, "agent_password": { "description": "Custom password for exporter endpoint /metrics.", "type": "string", - "x-order": 29 + "x-order": 30 }, "database": { "description": "Database name.", "type": "string", - "x-order": 30 + "x-order": 31 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 31 + "x-order": 32 }, "disable_comments_parsing": { "description": "Disable parsing comments from queries and showing them in QAN.", "type": "boolean", - "x-order": 32 + "x-order": 33 }, "max_postgresql_exporter_connections": { "description": "Maximum number of exporter connections to PostgreSQL instance.", "type": "integer", "format": "int32", - "x-order": 33 + "x-order": 34 }, "connection_timeout": { "description": "Connection timeout for exporter (if set).", "type": "string", - "x-order": 34 + "x-order": 35 } }, "x-order": 6 @@ -26323,13 +26359,18 @@ "type": "string", "x-order": 4 }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume for RDS metrics collection.", + "type": "string", + "x-order": 5 + }, "custom_labels": { "description": "Custom user-assigned labels.", "type": "object", "additionalProperties": { "type": "string" }, - "x-order": 5 + "x-order": 6 }, "status": { "description": "AgentStatus represents actual Agent status.\n\n - AGENT_STATUS_STARTING: Agent is starting.\n - AGENT_STATUS_INITIALIZATION_ERROR: Agent encountered error when starting.\n - AGENT_STATUS_RUNNING: Agent is running.\n - AGENT_STATUS_WAITING: Agent encountered error and will be restarted automatically soon.\n - AGENT_STATUS_STOPPING: Agent is stopping.\n - AGENT_STATUS_DONE: Agent has been stopped or disabled.\n - AGENT_STATUS_UNKNOWN: Agent is not connected, we don't know anything about it's state.", @@ -26345,33 +26386,33 @@ "AGENT_STATUS_DONE", "AGENT_STATUS_UNKNOWN" ], - "x-order": 6 + "x-order": 7 }, "listen_port": { "description": "Listen port for scraping metrics (the same for several configurations).", "type": "integer", "format": "int64", - "x-order": 7 + "x-order": 8 }, "basic_metrics_disabled": { "description": "Basic metrics are disabled.", "type": "boolean", - "x-order": 8 + "x-order": 9 }, "enhanced_metrics_disabled": { "description": "Enhanced metrics are disabled.", "type": "boolean", - "x-order": 9 + "x-order": 10 }, "push_metrics_enabled": { "description": "True if exporter uses push metrics mode.", "type": "boolean", - "x-order": 10 + "x-order": 11 }, "process_exec_path": { "description": "Path to exec process.", "type": "string", - "x-order": 11 + "x-order": 12 }, "log_level": { "description": "- LOG_LEVEL_UNSPECIFIED: Auto", @@ -26386,13 +26427,13 @@ "LOG_LEVEL_INFO", "LOG_LEVEL_DEBUG" ], - "x-order": 12 + "x-order": 13 }, "auto_discovery_limit": { "description": "Limit of databases for auto-discovery.", "type": "integer", "format": "int32", - "x-order": 13 + "x-order": 14 }, "metrics_resolutions": { "description": "MetricsResolutions represents Prometheus exporters metrics resolutions.", @@ -26414,7 +26455,7 @@ "x-order": 2 } }, - "x-order": 14 + "x-order": 15 } }, "x-order": 1 @@ -27798,14 +27839,19 @@ "type": "object", "properties": { "aws_access_key": { - "description": "AWS Access key. Optional.", + "description": "AWS Access key. Optional. Used as source credentials when aws_role_arn is set.", "type": "string", "x-order": 0 }, "aws_secret_key": { - "description": "AWS Secret key. Optional.", + "description": "AWS Secret key. Optional. Used as source credentials when aws_role_arn is set.", "type": "string", "x-order": 1 + }, + "aws_role_arn": { + "description": "AWS IAM role ARN to assume before discovering RDS instances. Optional.", + "type": "string", + "x-order": 2 } } } diff --git a/managed/models/agent_helpers.go b/managed/models/agent_helpers.go index 0f2f88b5e00..dd08a017616 100644 --- a/managed/models/agent_helpers.go +++ b/managed/models/agent_helpers.go @@ -1036,6 +1036,7 @@ type ChangeQANOptions struct { type ChangeAWSOptions struct { AWSAccessKey *string AWSSecretKey *string + AWSRoleARN *string RDSBasicMetricsDisabled *bool RDSEnhancedMetricsDisabled *bool } @@ -1240,6 +1241,9 @@ func ChangeAgent(q *reform.Querier, agentID string, params *ChangeAgentParams) ( if params.AWSOptions.AWSSecretKey != nil { row.AWSOptions.AWSSecretKey = *params.AWSOptions.AWSSecretKey } + if params.AWSOptions.AWSRoleARN != nil { + row.AWSOptions.AWSRoleARN = *params.AWSOptions.AWSRoleARN + } if params.AWSOptions.RDSBasicMetricsDisabled != nil { row.AWSOptions.RDSBasicMetricsDisabled = *params.AWSOptions.RDSBasicMetricsDisabled } diff --git a/managed/models/agent_helpers_test.go b/managed/models/agent_helpers_test.go index 8dafb74129f..11303171e91 100644 --- a/managed/models/agent_helpers_test.go +++ b/managed/models/agent_helpers_test.go @@ -917,6 +917,7 @@ func TestAgentHelpers(t *testing.T) { AWSOptions: models.AWSOptions{ AWSAccessKey: "old-access-key", AWSSecretKey: "old-secret-key", + AWSRoleARN: "old-role-arn", RDSBasicMetricsDisabled: false, RDSEnhancedMetricsDisabled: false, }, @@ -938,6 +939,7 @@ func TestAgentHelpers(t *testing.T) { require.NoError(t, err) assert.Equal(t, "new-access-key", agent.AWSOptions.AWSAccessKey) assert.Equal(t, "new-secret-key", agent.AWSOptions.AWSSecretKey) + assert.Equal(t, "new-role-arn", agent.AWSOptions.AWSRoleARN) assert.True(t, agent.AWSOptions.RDSBasicMetricsDisabled) assert.True(t, agent.AWSOptions.RDSEnhancedMetricsDisabled) @@ -946,6 +948,7 @@ func TestAgentHelpers(t *testing.T) { require.NoError(t, err) assert.Equal(t, "new-access-key", persistedAgent.AWSOptions.AWSAccessKey) assert.Equal(t, "new-secret-key", persistedAgent.AWSOptions.AWSSecretKey) + assert.Equal(t, "new-role-arn", persistedAgent.AWSOptions.AWSRoleARN) assert.True(t, persistedAgent.AWSOptions.RDSBasicMetricsDisabled) assert.True(t, persistedAgent.AWSOptions.RDSEnhancedMetricsDisabled) }) diff --git a/managed/models/agent_model.go b/managed/models/agent_model.go index 69f308efc3c..82fdfb422ca 100644 --- a/managed/models/agent_model.go +++ b/managed/models/agent_model.go @@ -158,6 +158,7 @@ func (c QANOptions) IsEmpty() bool { type AWSOptions struct { AWSAccessKey string `json:"aws_access_key"` AWSSecretKey string `json:"aws_secret_key"` + AWSRoleARN string `json:"aws_role_arn"` RDSBasicMetricsDisabled bool `json:"rds_basic_metrics_disabled"` RDSEnhancedMetricsDisabled bool `json:"rds_enhanced_metrics_disabled"` } @@ -172,6 +173,7 @@ func (c *AWSOptions) Scan(src interface{}) error { return jsonScan(c, src) } func (c AWSOptions) IsEmpty() bool { return c.AWSAccessKey == "" && c.AWSSecretKey == "" && + c.AWSRoleARN == "" && !c.RDSBasicMetricsDisabled && !c.RDSEnhancedMetricsDisabled } diff --git a/managed/services/agents/rds.go b/managed/services/agents/rds.go index a8feaba70a5..38c98868d5c 100644 --- a/managed/services/agents/rds.go +++ b/managed/services/agents/rds.go @@ -35,6 +35,7 @@ type rdsInstance struct { Instance string `yaml:"instance"` AWSAccessKey string `yaml:"aws_access_key,omitempty"` AWSSecretKey string `yaml:"aws_secret_key,omitempty"` + AWSRoleARN string `yaml:"aws_role_arn,omitempty"` DisableBasicMetrics bool `yaml:"disable_basic_metrics"` DisableEnhancedMetrics bool `yaml:"disable_enhanced_metrics"` Labels model.LabelSet `yaml:"labels,omitempty"` @@ -82,6 +83,7 @@ func rdsExporterConfig(pairs map[*models.Node]*models.Agent, redactMode redactMo Instance: node.InstanceID, AWSAccessKey: exporter.AWSOptions.AWSAccessKey, AWSSecretKey: exporter.AWSOptions.AWSSecretKey, + AWSRoleARN: exporter.AWSOptions.AWSRoleARN, Labels: labels, DisableBasicMetrics: exporter.AWSOptions.RDSBasicMetricsDisabled, DisableEnhancedMetrics: exporter.AWSOptions.RDSEnhancedMetricsDisabled, diff --git a/managed/services/agents/rds_test.go b/managed/services/agents/rds_test.go index 72e69f3afea..a9f33b9e44c 100644 --- a/managed/services/agents/rds_test.go +++ b/managed/services/agents/rds_test.go @@ -51,6 +51,7 @@ func TestRDSExporterConfig(t *testing.T) { AWSOptions: models.AWSOptions{ AWSAccessKey: "access_key1", AWSSecretKey: "secret_key1", + AWSRoleARN: "arn:aws:iam::123456789012:role/PmmRdsReadRole", RDSBasicMetricsDisabled: true, }, } @@ -101,6 +102,7 @@ instances: instance: rds-mysql56 aws_access_key: access_key1 aws_secret_key: secret_key1 + aws_role_arn: arn:aws:iam::123456789012:role/PmmRdsReadRole disable_basic_metrics: true disable_enhanced_metrics: false labels: diff --git a/managed/services/converters.go b/managed/services/converters.go index 886493122a0..3a07c15e023 100644 --- a/managed/services/converters.go +++ b/managed/services/converters.go @@ -495,6 +495,7 @@ func ToAPIAgent(q *reform.Querier, agent *models.Agent) (inventoryv1.Agent, erro NodeId: nodeID, Disabled: agent.Disabled, AwsAccessKey: agent.AWSOptions.AWSAccessKey, + AwsRoleArn: agent.AWSOptions.AWSRoleARN, Status: inventoryv1.AgentStatus(inventoryv1.AgentStatus_value[agent.Status]), ListenPort: uint32(pointer.GetUint16(agent.ListenPort)), CustomLabels: labels, diff --git a/managed/services/inventory/agents.go b/managed/services/inventory/agents.go index 37347b1e4f0..bd49f9d61ab 100644 --- a/managed/services/inventory/agents.go +++ b/managed/services/inventory/agents.go @@ -1472,6 +1472,7 @@ func (as *AgentsService) AddRDSExporter(ctx context.Context, p *inventoryv1.AddR AWSOptions: models.AWSOptions{ AWSAccessKey: p.AwsAccessKey, AWSSecretKey: p.AwsSecretKey, + AWSRoleARN: p.AwsRoleArn, RDSBasicMetricsDisabled: p.DisableBasicMetrics, RDSEnhancedMetricsDisabled: p.DisableEnhancedMetrics, }, @@ -1521,6 +1522,7 @@ func (as *AgentsService) ChangeRDSExporter(ctx context.Context, agentID string, params.AWSOptions = &models.ChangeAWSOptions{ AWSAccessKey: p.AwsAccessKey, AWSSecretKey: p.AwsSecretKey, + AWSRoleARN: p.AwsRoleArn, RDSBasicMetricsDisabled: p.DisableBasicMetrics, RDSEnhancedMetricsDisabled: p.DisableEnhancedMetrics, } diff --git a/managed/services/inventory/agents_test.go b/managed/services/inventory/agents_test.go index 9258c3af474..400f3d1fbf8 100644 --- a/managed/services/inventory/agents_test.go +++ b/managed/services/inventory/agents_test.go @@ -454,6 +454,7 @@ func TestAgents(t *testing.T) { NodeId: node.NodeId, AwsAccessKey: "EXAMPLE_ACCESS_KEY", AwsSecretKey: "EXAMPLE_SECRET_KEY", + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", CustomLabels: map[string]string{"baz": "qux"}, }) require.NoError(t, err) @@ -462,6 +463,7 @@ func TestAgents(t *testing.T) { PmmAgentId: "pmm-server", NodeId: "00000000-0000-4000-8000-000000000005", AwsAccessKey: "EXAMPLE_ACCESS_KEY", + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", CustomLabels: map[string]string{"baz": "qux"}, Status: inventoryv1.AgentStatus_AGENT_STATUS_UNKNOWN, } @@ -796,6 +798,7 @@ func TestAgents(t *testing.T) { NodeId: node.NodeId, AwsAccessKey: "EXAMPLE_ACCESS_KEY", AwsSecretKey: "EXAMPLE_SECRET_KEY", + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", CustomLabels: map[string]string{"baz": "qux"}, PushMetrics: true, }) @@ -805,6 +808,7 @@ func TestAgents(t *testing.T) { PmmAgentId: "pmm-server", NodeId: "00000000-0000-4000-8000-000000000005", AwsAccessKey: "EXAMPLE_ACCESS_KEY", + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", CustomLabels: map[string]string{"baz": "qux"}, PushMetricsEnabled: true, Status: inventoryv1.AgentStatus_AGENT_STATUS_UNKNOWN, diff --git a/managed/services/management/rds.go b/managed/services/management/rds.go index 64e6be7bba7..dbd610bc70b 100644 --- a/managed/services/management/rds.go +++ b/managed/services/management/rds.go @@ -24,8 +24,10 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/service/rds" "github.com/aws/aws-sdk-go-v2/service/rds/types" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/aws/smithy-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -45,7 +47,12 @@ import ( const ( // Maximum time for AWS discover APIs calls. awsDiscoverTimeout = 7 * time.Second - rdsEndpointsID = "rds" + + // Maximum time for resolving AWS credentials or assuming the requested IAM role before RDS discovery starts. + awsCredentialsTimeout = 7 * time.Second + rdsEndpointsID = "rds" + + rdsAssumeRoleSessionName = "pmm-rds-discovery" ) // See https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/rds?tab=doc#CreateDBInstanceInput, Engine field. @@ -139,32 +146,72 @@ func listRegions(partitions []string) []string { return slice } -// DiscoverRDS discovers RDS instances. -func (s *ManagementService) DiscoverRDS(ctx context.Context, req *managementv1.DiscoverRDSRequest) (*managementv1.DiscoverRDSResponse, error) { //nolint:gocognit - l := logger.Get(ctx).WithField("component", "discover/rds") +func loadRDSAWSConfig(ctx context.Context, req *managementv1.DiscoverRDSRequest, l *logrus.Entry) (aws.Config, error) { + var opts []func(*config.LoadOptions) error - settings, err := models.GetSettings(s.db.Querier) - if err != nil { - return nil, err - } - - // use given credentials, or default credential chain - var creds aws.CredentialsProvider + // Use supplied credentials as the source credentials, or fall back to the default AWS credential chain. if req.AwsAccessKey != "" && req.AwsSecretKey != "" { - creds = credentials.NewStaticCredentialsProvider(req.AwsAccessKey, req.AwsSecretKey, "") + opts = append(opts, config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(req.AwsAccessKey, req.AwsSecretKey, ""))) } + opts = append(opts, config.WithHTTPClient(&http.Client{})) - opts := []func(*config.LoadOptions) error{ - config.WithCredentialsProvider(creds), - config.WithHTTPClient(&http.Client{}), - } if l.Logger != nil && l.Logger.Level >= logrus.DebugLevel { opts = append(opts, config.WithClientLogMode(aws.LogRetries|aws.LogRequestWithBody|aws.LogResponseWithBody)) } cfg, err := config.LoadDefaultConfig(ctx, opts...) if err != nil { - return nil, errors.WithStack(err) + return aws.Config{}, errors.WithStack(err) + } + + if req.AwsRoleArn != "" { + cfg.Credentials = aws.NewCredentialsCache(stscreds.NewAssumeRoleProvider( + sts.NewFromConfig(cfg), + req.AwsRoleArn, + func(o *stscreds.AssumeRoleOptions) { + o.RoleSessionName = rdsAssumeRoleSessionName + }, + )) + } + + return cfg, nil +} + +func validateRDSAWSCredentials(ctx context.Context, cfg aws.Config, roleARN string) error { + if ctx.Err() != nil { + return nil + } + + ctx, cancel := context.WithTimeout(ctx, awsCredentialsTimeout) + defer cancel() + + _, err := cfg.Credentials.Retrieve(ctx) + if err == nil { + return nil + } + + if roleARN != "" { + return status.Errorf(codes.InvalidArgument, "Failed to assume AWS IAM role %q: %s", roleARN, err) + } + + return status.Errorf(codes.InvalidArgument, "Failed to load AWS credentials: %s", err) +} + +// DiscoverRDS discovers RDS instances. +func (s *ManagementService) DiscoverRDS(ctx context.Context, req *managementv1.DiscoverRDSRequest) (*managementv1.DiscoverRDSResponse, error) { //nolint:gocognit + l := logger.Get(ctx).WithField("component", "discover/rds") + + settings, err := models.GetSettings(s.db.Querier) + if err != nil { + return nil, err + } + + cfg, err := loadRDSAWSConfig(ctx, req, l) + if err != nil { + return nil, err + } + if err := validateRDSAWSCredentials(ctx, cfg, req.AwsRoleArn); err != nil { + return nil, err } // do not break our API if some AWS region is slow or down @@ -318,6 +365,7 @@ func (s *ManagementService) addRDS(ctx context.Context, req *managementv1.AddRDS AWSOptions: models.AWSOptions{ AWSAccessKey: req.AwsAccessKey, AWSSecretKey: req.AwsSecretKey, + AWSRoleARN: req.AwsRoleArn, RDSBasicMetricsDisabled: req.DisableBasicMetrics, RDSEnhancedMetricsDisabled: req.DisableEnhancedMetrics, }, diff --git a/managed/services/management/rds_test.go b/managed/services/management/rds_test.go index ce070c471be..7c188adb71d 100644 --- a/managed/services/management/rds_test.go +++ b/managed/services/management/rds_test.go @@ -43,6 +43,14 @@ import ( "github.com/percona/pmm/utils/logger" ) +type failingCredentialsProvider struct { + err error +} + +func (p failingCredentialsProvider) Retrieve(context.Context) (aws.Credentials, error) { + return aws.Credentials{}, p.err +} + func TestRDSService(t *testing.T) { // logrus.SetLevel(logrus.DebugLevel) @@ -126,6 +134,21 @@ func TestRDSService(t *testing.T) { assert.Equal(t, expected, actual) }) + t.Run("AssumeRoleCredentialsError", func(t *testing.T) { + roleARN := "arn:aws:iam::123456789012:role/PmmRdsReadOnlyRole" + cfg := aws.Config{ + Credentials: failingCredentialsProvider{err: fmt.Errorf("sts assume role denied")}, + } + + err := validateRDSAWSCredentials(t.Context(), cfg, roleARN) + + tests.AssertGRPCError( + t, + status.New(codes.InvalidArgument, "Failed to assume AWS IAM role \"arn:aws:iam::123456789012:role/PmmRdsReadOnlyRole\": sts assume role denied"), + err, + ) + }) + t.Run("InvalidClientTokenId", func(t *testing.T) { ctx := logger.Set(t.Context(), t.Name()) accessKey, secretKey := "EXAMPLE_ACCESS_KEY", "EXAMPLE_SECRET_KEY" @@ -269,6 +292,7 @@ func TestRDSService(t *testing.T) { Password: "password", AwsAccessKey: accessKey, AwsSecretKey: secretKey, + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", RdsExporter: true, QanMysqlPerfschema: true, CustomLabels: map[string]string{ @@ -305,6 +329,7 @@ func TestRDSService(t *testing.T) { PmmAgentId: "pmm-server", NodeId: "00000000-0000-4000-8000-000000000005", AwsAccessKey: "EXAMPLE_ACCESS_KEY", + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", Status: inventoryv1.AgentStatus_AGENT_STATUS_UNKNOWN, }, Mysql: &inventoryv1.MySQLService{ @@ -361,6 +386,7 @@ func TestRDSService(t *testing.T) { Password: "password", AwsAccessKey: accessKey, AwsSecretKey: secretKey, + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", RdsExporter: true, QanPostgresqlPgstatements: true, CustomLabels: map[string]string{ @@ -399,6 +425,7 @@ func TestRDSService(t *testing.T) { PmmAgentId: "pmm-server", NodeId: "00000000-0000-4000-8000-00000000000a", AwsAccessKey: "EXAMPLE_ACCESS_KEY", + AwsRoleArn: "arn:aws:iam::123456789012:role/PmmRdsReadRole", Status: inventoryv1.AgentStatus_AGENT_STATUS_UNKNOWN, }, Postgresql: &inventoryv1.PostgreSQLService{