diff --git a/api-tests/server/auth_test.go b/api-tests/server/auth_test.go index 7529f89538..819c431c0d 100644 --- a/api-tests/server/auth_test.go +++ b/api-tests/server/auth_test.go @@ -35,7 +35,6 @@ import ( pmmapitests "github.com/percona/pmm/api-tests" serverClient "github.com/percona/pmm/api/server/v1/json/client" server "github.com/percona/pmm/api/server/v1/json/client/server_service" - "github.com/percona/pmm/utils/grafana" stringsgen "github.com/percona/pmm/utils/strings" ) @@ -523,7 +522,7 @@ func createServiceAccountWithRole(t *testing.T, role, nodeName string) int { name := fmt.Sprintf("%s-%s", pmmServiceAccountName, nodeName) data, err := json.Marshal(map[string]string{ - "name": grafana.SanitizeSAName(name), + "name": name, "role": role, }) require.NoError(t, err) @@ -585,7 +584,7 @@ func createServiceToken(t *testing.T, serviceAccountID int, nodeName string) (in name := fmt.Sprintf("%s-%s", pmmServiceTokenName, nodeName) data, err := json.Marshal(map[string]string{ - "name": grafana.SanitizeSAName(name), + "name": name, }) require.NoError(t, err) diff --git a/api/swagger/swagger-dev.json b/api/swagger/swagger-dev.json index 209f528470..d12c969387 100644 --- a/api/swagger/swagger-dev.json +++ b/api/swagger/swagger-dev.json @@ -28129,6 +28129,11 @@ "type": "string", "title": "Snoozed PMM version update", "x-order": 3 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-order": 4 } } } @@ -28198,6 +28203,12 @@ "title": "Snooze update alert for a PMM version", "x-nullable": true, "x-order": 2 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-nullable": true, + "x-order": 3 } } } @@ -28229,6 +28240,11 @@ "type": "string", "title": "Snooze update alert for a PMM version", "x-order": 3 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-order": 4 } } } diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 6e35d2a7a3..8693873951 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -27171,6 +27171,11 @@ "type": "string", "title": "Snoozed PMM version update", "x-order": 3 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-order": 4 } } } @@ -27240,6 +27245,12 @@ "title": "Snooze update alert for a PMM version", "x-nullable": true, "x-order": 2 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-nullable": true, + "x-order": 3 } } } @@ -27271,6 +27282,11 @@ "type": "string", "title": "Snooze update alert for a PMM version", "x-order": 3 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-order": 4 } } } diff --git a/api/user/v1/json/client/user_service/get_user_responses.go b/api/user/v1/json/client/user_service/get_user_responses.go index e9ef71e832..1d88eae8dc 100644 --- a/api/user/v1/json/client/user_service/get_user_responses.go +++ b/api/user/v1/json/client/user_service/get_user_responses.go @@ -422,6 +422,9 @@ type GetUserOKBody struct { // Snoozed PMM version update SnoozedPMMVersion string `json:"snoozed_pmm_version,omitempty"` + + // Snoozed warning about API keys migration + SnoozedAPIKeysMigration bool `json:"snoozed_api_keys_migration,omitempty"` } // Validate validates this get user OK body diff --git a/api/user/v1/json/client/user_service/update_user_responses.go b/api/user/v1/json/client/user_service/update_user_responses.go index 93a7ec4357..fa77b7c5a4 100644 --- a/api/user/v1/json/client/user_service/update_user_responses.go +++ b/api/user/v1/json/client/user_service/update_user_responses.go @@ -199,6 +199,9 @@ type UpdateUserBody struct { // Snooze update alert for a PMM version SnoozedPMMVersion *string `json:"snoozed_pmm_version,omitempty"` + + // Snoozed warning about API keys migration + SnoozedAPIKeysMigration *bool `json:"snoozed_api_keys_migration,omitempty"` } // Validate validates this update user body @@ -465,6 +468,9 @@ type UpdateUserOKBody struct { // Snooze update alert for a PMM version SnoozedPMMVersion string `json:"snoozed_pmm_version,omitempty"` + + // Snoozed warning about API keys migration + SnoozedAPIKeysMigration bool `json:"snoozed_api_keys_migration,omitempty"` } // Validate validates this update user OK body diff --git a/api/user/v1/json/v1.json b/api/user/v1/json/v1.json index dd5d27617e..8b0102edee 100644 --- a/api/user/v1/json/v1.json +++ b/api/user/v1/json/v1.json @@ -123,6 +123,11 @@ "type": "string", "title": "Snoozed PMM version update", "x-order": 3 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-order": 4 } } } @@ -192,6 +197,12 @@ "title": "Snooze update alert for a PMM version", "x-nullable": true, "x-order": 2 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-nullable": true, + "x-order": 3 } } } @@ -223,6 +234,11 @@ "type": "string", "title": "Snooze update alert for a PMM version", "x-order": 3 + }, + "snoozed_api_keys_migration": { + "type": "boolean", + "title": "Snoozed warning about API keys migration", + "x-order": 4 } } } diff --git a/api/user/v1/user.pb.go b/api/user/v1/user.pb.go index 703d234e8b..42b9584246 100644 --- a/api/user/v1/user.pb.go +++ b/api/user/v1/user.pb.go @@ -72,6 +72,8 @@ type GetUserResponse struct { AlertingTourCompleted bool `protobuf:"varint,3,opt,name=alerting_tour_completed,json=alertingTourCompleted,proto3" json:"alerting_tour_completed,omitempty"` // Snoozed PMM version update SnoozedPmmVersion string `protobuf:"bytes,4,opt,name=snoozed_pmm_version,json=snoozedPmmVersion,proto3" json:"snoozed_pmm_version,omitempty"` + // Snoozed warning about API keys migration + SnoozedApiKeysMigration bool `protobuf:"varint,5,opt,name=snoozed_api_keys_migration,json=snoozedApiKeysMigration,proto3" json:"snoozed_api_keys_migration,omitempty"` } func (x *GetUserResponse) Reset() { @@ -132,6 +134,13 @@ func (x *GetUserResponse) GetSnoozedPmmVersion() string { return "" } +func (x *GetUserResponse) GetSnoozedApiKeysMigration() bool { + if x != nil { + return x.SnoozedApiKeysMigration + } + return false +} + type UpdateUserRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -143,6 +152,8 @@ type UpdateUserRequest struct { AlertingTourCompleted *bool `protobuf:"varint,3,opt,name=alerting_tour_completed,json=alertingTourCompleted,proto3,oneof" json:"alerting_tour_completed,omitempty"` // Snooze update alert for a PMM version SnoozedPmmVersion *string `protobuf:"bytes,4,opt,name=snoozed_pmm_version,json=snoozedPmmVersion,proto3,oneof" json:"snoozed_pmm_version,omitempty"` + // Snoozed warning about API keys migration + SnoozedApiKeysMigration *bool `protobuf:"varint,5,opt,name=snoozed_api_keys_migration,json=snoozedApiKeysMigration,proto3,oneof" json:"snoozed_api_keys_migration,omitempty"` } func (x *UpdateUserRequest) Reset() { @@ -196,6 +207,13 @@ func (x *UpdateUserRequest) GetSnoozedPmmVersion() string { return "" } +func (x *UpdateUserRequest) GetSnoozedApiKeysMigration() bool { + if x != nil && x.SnoozedApiKeysMigration != nil { + return *x.SnoozedApiKeysMigration + } + return false +} + type UpdateUserResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -209,6 +227,8 @@ type UpdateUserResponse struct { AlertingTourCompleted bool `protobuf:"varint,3,opt,name=alerting_tour_completed,json=alertingTourCompleted,proto3" json:"alerting_tour_completed,omitempty"` // Snooze update alert for a PMM version SnoozedPmmVersion string `protobuf:"bytes,4,opt,name=snoozed_pmm_version,json=snoozedPmmVersion,proto3" json:"snoozed_pmm_version,omitempty"` + // Snoozed warning about API keys migration + SnoozedApiKeysMigration bool `protobuf:"varint,5,opt,name=snoozed_api_keys_migration,json=snoozedApiKeysMigration,proto3" json:"snoozed_api_keys_migration,omitempty"` } func (x *UpdateUserResponse) Reset() { @@ -269,6 +289,13 @@ func (x *UpdateUserResponse) GetSnoozedPmmVersion() string { return "" } +func (x *UpdateUserResponse) GetSnoozedApiKeysMigration() bool { + if x != nil { + return x.SnoozedApiKeysMigration + } + return false +} + type ListUsersRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -414,7 +441,7 @@ var file_user_v1_user_proto_rawDesc = []byte{ 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x10, 0x0a, 0x0e, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xc8, 0x01, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x85, 0x02, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x72, @@ -427,87 +454,100 @@ var file_user_v1_user_proto_rawDesc = []byte{ 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x5f, 0x70, 0x6d, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x50, 0x6d, - 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8f, 0x02, 0x0a, 0x11, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, - 0x0a, 0x16, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, - 0x52, 0x14, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x17, 0x61, 0x6c, 0x65, - 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x15, 0x61, 0x6c, - 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x13, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, + 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x73, 0x6e, 0x6f, 0x6f, + 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x6d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x73, 0x6e, + 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf0, 0x02, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x16, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x14, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x17, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, + 0x6e, 0x67, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x15, 0x61, 0x6c, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x13, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x5f, 0x70, + 0x6d, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x02, 0x52, 0x11, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x50, 0x6d, 0x6d, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x1a, 0x73, 0x6e, 0x6f, 0x6f, + 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x6d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x17, + 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x19, 0x0a, 0x17, 0x5f, 0x70, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, + 0x6e, 0x67, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x5f, 0x70, 0x6d, + 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x1d, 0x0a, 0x1b, 0x5f, 0x73, 0x6e, + 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x88, 0x02, 0x0a, 0x12, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x54, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x36, + 0x0a, 0x17, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x15, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x5f, 0x70, 0x6d, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x11, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x50, 0x6d, - 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x19, 0x0a, 0x17, 0x5f, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x61, 0x6c, 0x65, 0x72, 0x74, - 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x64, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x5f, 0x70, - 0x6d, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcb, 0x01, 0x0a, 0x12, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x72, - 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x6f, 0x75, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x54, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x12, 0x36, 0x0a, 0x17, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x6f, 0x75, - 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x15, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x75, 0x72, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x6e, 0x6f, 0x6f, - 0x7a, 0x65, 0x64, 0x5f, 0x70, 0x6d, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x50, 0x6d, - 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x92, 0x01, 0x0a, - 0x11, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, - 0x40, 0x0a, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x17, 0x0a, - 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, - 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, - 0x73, 0x32, 0xd4, 0x03, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x17, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x50, 0x92, 0x41, 0x39, 0x12, 0x10, 0x47, 0x65, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, - 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x25, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, - 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x66, - 0x72, 0x6f, 0x6d, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, - 0x6d, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, - 0x72, 0x12, 0x1a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x92, 0x41, 0x32, 0x12, - 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x21, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x3a, 0x01, 0x2a, 0x1a, 0x0c, 0x2f, 0x76, 0x31, 0x2f, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x6d, 0x65, 0x12, 0x9d, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x19, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, 0x92, - 0x41, 0x45, 0x12, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x1a, 0x33, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x75, 0x73, 0x65, - 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, - 0x6c, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x50, 0x4d, 0x4d, - 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, - 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x42, 0x8f, 0x01, 0x92, 0x41, 0x0c, 0x12, 0x0a, - 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x20, 0x41, 0x50, 0x49, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x70, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, 0xa2, - 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, - 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x55, 0x73, 0x65, 0x72, - 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x08, 0x55, 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, 0x64, 0x50, 0x6d, 0x6d, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x1a, 0x73, 0x6e, 0x6f, 0x6f, 0x7a, 0x65, + 0x64, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x6d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x73, 0x6e, 0x6f, 0x6f, + 0x7a, 0x65, 0x64, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x92, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, + 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, + 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x40, 0x0a, 0x0a, 0x55, 0x73, + 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0d, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x73, 0x32, 0xd4, 0x03, 0x0a, + 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x0a, + 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x39, + 0x12, 0x10, 0x47, 0x65, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x1a, 0x25, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x75, 0x73, 0x65, + 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x50, + 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, + 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x6d, 0x65, 0x12, 0x93, 0x01, + 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x92, 0x41, 0x32, 0x12, 0x0d, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x20, 0x69, + 0x6e, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x11, 0x3a, 0x01, 0x2a, 0x1a, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, + 0x2f, 0x6d, 0x65, 0x12, 0x9d, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x73, 0x12, 0x19, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, 0x92, 0x41, 0x45, 0x12, 0x0e, 0x4c, + 0x69, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, 0x72, 0x73, 0x1a, 0x33, 0x52, + 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x75, 0x73, 0x65, + 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x50, 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, + 0x65, 0x72, 0x73, 0x42, 0x8f, 0x01, 0x92, 0x41, 0x0c, 0x12, 0x0a, 0x0a, 0x08, 0x55, 0x73, 0x65, + 0x72, 0x20, 0x41, 0x50, 0x49, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x65, 0x72, 0x63, + 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6d, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x73, 0x65, 0x72, + 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, + 0xaa, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07, 0x55, 0x73, 0x65, + 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x08, 0x55, 0x73, 0x65, + 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/user/v1/user.pb.validate.go b/api/user/v1/user.pb.validate.go index a35b0f3413..6998eefd33 100644 --- a/api/user/v1/user.pb.validate.go +++ b/api/user/v1/user.pb.validate.go @@ -165,6 +165,8 @@ func (m *GetUserResponse) validate(all bool) error { // no validation rules for SnoozedPmmVersion + // no validation rules for SnoozedApiKeysMigration + if len(errors) > 0 { return GetUserResponseMultiError(errors) } @@ -277,6 +279,10 @@ func (m *UpdateUserRequest) validate(all bool) error { // no validation rules for SnoozedPmmVersion } + if m.SnoozedApiKeysMigration != nil { + // no validation rules for SnoozedApiKeysMigration + } + if len(errors) > 0 { return UpdateUserRequestMultiError(errors) } @@ -387,6 +393,8 @@ func (m *UpdateUserResponse) validate(all bool) error { // no validation rules for SnoozedPmmVersion + // no validation rules for SnoozedApiKeysMigration + if len(errors) > 0 { return UpdateUserResponseMultiError(errors) } diff --git a/api/user/v1/user.proto b/api/user/v1/user.proto index 0cbfc1509e..c7c41d8760 100644 --- a/api/user/v1/user.proto +++ b/api/user/v1/user.proto @@ -20,6 +20,8 @@ message GetUserResponse { bool alerting_tour_completed = 3; // Snoozed PMM version update string snoozed_pmm_version = 4; + // Snoozed warning about API keys migration + bool snoozed_api_keys_migration = 5; } message UpdateUserRequest { @@ -29,6 +31,8 @@ message UpdateUserRequest { optional bool alerting_tour_completed = 3; // Snooze update alert for a PMM version optional string snoozed_pmm_version = 4; + // Snoozed warning about API keys migration + optional bool snoozed_api_keys_migration = 5; } message UpdateUserResponse { @@ -40,6 +44,8 @@ message UpdateUserResponse { bool alerting_tour_completed = 3; // Snooze update alert for a PMM version string snoozed_pmm_version = 4; + // Snoozed warning about API keys migration + bool snoozed_api_keys_migration = 5; } message ListUsersRequest {} diff --git a/documentation/docs/api/authentication.md b/documentation/docs/api/authentication.md index e8269af6b9..1ddce80a23 100644 --- a/documentation/docs/api/authentication.md +++ b/documentation/docs/api/authentication.md @@ -5,7 +5,7 @@ ### Automatic migration of API keys -When you install PMM v3.x, any existing API keys will be seamlessly converted to service accounts with corresponding service tokens. +When you install PMM v3.x, any existing API keys will be seamlessly converted to service accounts with corresponding service tokens. For more information about the migration, see [Migrate PMM 2 to PMM 3](../pmm-upgrade/migrating_from_pmm_2.md). Service accounts in PMM provide a secure and efficient way to manage access to the PMM Server and its resources. They serve as a replacement for the basic authentication and API keys used in previous versions of PMM (v.2 and earlier). diff --git a/documentation/docs/pmm-upgrade/migrating_from_pmm_2.md b/documentation/docs/pmm-upgrade/migrating_from_pmm_2.md index 1db602c8d8..c34688452e 100644 --- a/documentation/docs/pmm-upgrade/migrating_from_pmm_2.md +++ b/documentation/docs/pmm-upgrade/migrating_from_pmm_2.md @@ -113,9 +113,46 @@ Before upgrading to PMM 3, ensure your PMM 2 Server is running the latest versio Depending on your initial installation method, update PMM Clients using your operating system's package manager or by updating from a tarball. For detailed instructions, see the [Upgrade PMM Client topic](../pmm-upgrade/upgrade_client.md). +## Step 4: Migrate your API keys to service accounts + +PMM 3 replaces API keys with service accounts to enhance security and simplify access management. You can trigger this API key conversion from the UI or from the CLI. + +### From the UI +PMM automatically migrates existing API keys to service accounts when you first log in as an Admin user. The migration results are displayed in a popup dialog box. + +If no popup appears, it likely means there are no API keys to migrate—this is typical for PMM Servers without connected services. + +### From CLI +You can also initiate the conversion using the following command. +Be sure to replace `admin:admin` with your credentials and update the server address (`localhost` or `127.0.0.1`) and port number (`3000`) if they differ from the defaults: + + +```sh +curl -X POST http://localhost:3000/api/serviceaccounts/migrate \ +-u admin:admin \ +-H "Content-Type: application/json +``` + +The response will display the migration details: + +!!! example "Expected output" + + ``` + {"total":3,"migrated":3,"failed":0,"failedApikeyIDs":[],"failedDetails":[]} + ``` + +### Verify the conversion + +To verify the that API keys were successfully migrated, go to **Administration > Users and Access > Service Accounts** where you can check the list of service accounts available and confirm that the **API Keys** menu is no longer displayed. + +If any API keys fail to migrate, you can either: + +- delete the problematic API keys and create new service accounts +- keep using the existing API keys until you're ready to replace them + ### Post-migration steps -After you finish migrating: +After you finish migrating PMM: {.power-number} 1. Verify that all PMM Clients are up to date by checking **PMM Configuration > Updates**. diff --git a/managed/models/database.go b/managed/models/database.go index 3185d42bab..4e423e66d1 100644 --- a/managed/models/database.go +++ b/managed/models/database.go @@ -1144,6 +1144,10 @@ var databaseSchema = [][]string{ ) WHERE settings ? 'encrypted_items';`, }, + 108: { + `ALTER TABLE user_flags + ADD COLUMN snoozed_api_keys_migration BOOLEAN NOT NULL DEFAULT false`, + }, } // ^^^ Avoid default values in schema definition. ^^^ diff --git a/managed/models/user_flags_helpers.go b/managed/models/user_flags_helpers.go index 38cfe3725a..2bdaca6876 100644 --- a/managed/models/user_flags_helpers.go +++ b/managed/models/user_flags_helpers.go @@ -31,10 +31,11 @@ type CreateUserParams struct { // UpdateUserParams has parameters to update existing user. type UpdateUserParams struct { - UserID int - Tour *bool - AlertingTour *bool - SnoozedPMMVersion *string + UserID int + Tour *bool + AlertingTour *bool + SnoozedPMMVersion *string + SnoozedAPIKeysMigration *bool } // GetOrCreateUser returns user and optionally creates it, if not in database yet. @@ -110,6 +111,9 @@ func UpdateUser(q *reform.Querier, params *UpdateUserParams) (*UserDetails, erro if params.SnoozedPMMVersion != nil { row.SnoozedPMMVersion = *params.SnoozedPMMVersion } + if params.SnoozedAPIKeysMigration != nil { + row.SnoozedAPIKeysMigration = *params.SnoozedAPIKeysMigration + } if err = q.Update(row); err != nil { return nil, errors.Wrap(err, "failed to update user") diff --git a/managed/models/user_flags_model.go b/managed/models/user_flags_model.go index e1a8109006..323f49d7d0 100644 --- a/managed/models/user_flags_model.go +++ b/managed/models/user_flags_model.go @@ -27,10 +27,11 @@ import ( // //reform:user_flags type UserDetails struct { - ID int `reform:"id,pk"` - Tour bool `reform:"tour_done"` - AlertingTour bool `reform:"alerting_tour_done"` - SnoozedPMMVersion string `reform:"snoozed_pmm_version"` + ID int `reform:"id,pk"` + Tour bool `reform:"tour_done"` + AlertingTour bool `reform:"alerting_tour_done"` + SnoozedPMMVersion string `reform:"snoozed_pmm_version"` + SnoozedAPIKeysMigration bool `reform:"snoozed_api_keys_migration"` CreatedAt time.Time `reform:"created_at"` UpdatedAt time.Time `reform:"updated_at"` diff --git a/managed/models/user_flags_model_reform.go b/managed/models/user_flags_model_reform.go index 940c242e1d..9354725caa 100644 --- a/managed/models/user_flags_model_reform.go +++ b/managed/models/user_flags_model_reform.go @@ -32,6 +32,7 @@ func (v *userDetailsTableType) Columns() []string { "tour_done", "alerting_tour_done", "snoozed_pmm_version", + "snoozed_api_keys_migration", "created_at", "updated_at", } @@ -62,6 +63,7 @@ var UserDetailsTable = &userDetailsTableType{ {Name: "Tour", Type: "bool", Column: "tour_done"}, {Name: "AlertingTour", Type: "bool", Column: "alerting_tour_done"}, {Name: "SnoozedPMMVersion", Type: "string", Column: "snoozed_pmm_version"}, + {Name: "SnoozedAPIKeysMigration", Type: "bool", Column: "snoozed_api_keys_migration"}, {Name: "CreatedAt", Type: "time.Time", Column: "created_at"}, {Name: "UpdatedAt", Type: "time.Time", Column: "updated_at"}, }, @@ -72,13 +74,14 @@ var UserDetailsTable = &userDetailsTableType{ // String returns a string representation of this struct or record. func (s UserDetails) String() string { - res := make([]string, 6) + res := make([]string, 7) res[0] = "ID: " + reform.Inspect(s.ID, true) res[1] = "Tour: " + reform.Inspect(s.Tour, true) res[2] = "AlertingTour: " + reform.Inspect(s.AlertingTour, true) res[3] = "SnoozedPMMVersion: " + reform.Inspect(s.SnoozedPMMVersion, true) - res[4] = "CreatedAt: " + reform.Inspect(s.CreatedAt, true) - res[5] = "UpdatedAt: " + reform.Inspect(s.UpdatedAt, true) + res[4] = "SnoozedAPIKeysMigration: " + reform.Inspect(s.SnoozedAPIKeysMigration, true) + res[5] = "CreatedAt: " + reform.Inspect(s.CreatedAt, true) + res[6] = "UpdatedAt: " + reform.Inspect(s.UpdatedAt, true) return strings.Join(res, ", ") } @@ -90,6 +93,7 @@ func (s *UserDetails) Values() []interface{} { s.Tour, s.AlertingTour, s.SnoozedPMMVersion, + s.SnoozedAPIKeysMigration, s.CreatedAt, s.UpdatedAt, } @@ -103,6 +107,7 @@ func (s *UserDetails) Pointers() []interface{} { &s.Tour, &s.AlertingTour, &s.SnoozedPMMVersion, + &s.SnoozedAPIKeysMigration, &s.CreatedAt, &s.UpdatedAt, } diff --git a/managed/services/grafana/auth_server.go b/managed/services/grafana/auth_server.go index 71c7167448..863c6cd605 100644 --- a/managed/services/grafana/auth_server.go +++ b/managed/services/grafana/auth_server.go @@ -142,7 +142,7 @@ type cacheItem struct { // clientInterface exist only to make fuzzing simpler. type clientInterface interface { - getAuthUser(ctx context.Context, authHeaders http.Header) (authUser, error) + getAuthUser(ctx context.Context, authHeaders http.Header, l *logrus.Entry) (authUser, error) } // AuthServer authenticates incoming requests via Grafana API. @@ -544,7 +544,7 @@ func (s *AuthServer) authHeaders(req *http.Request) http.Header { } func (s *AuthServer) retrieveRole(ctx context.Context, hash string, authHeaders http.Header, l *logrus.Entry) (*authUser, *authError) { - authUser, err := s.c.getAuthUser(ctx, authHeaders) + authUser, err := s.c.getAuthUser(ctx, authHeaders, l) if err != nil { l.Warnf("%s", err) if cErr, ok := errors.Cause(err).(*clientError); ok { //nolint:errorlint diff --git a/managed/services/grafana/client.go b/managed/services/grafana/client.go index 791c24a7ab..a37a52b71f 100644 --- a/managed/services/grafana/client.go +++ b/managed/services/grafana/client.go @@ -43,8 +43,8 @@ import ( "github.com/percona/pmm/utils/grafana" ) -// ErrFailedToGetToken means it failed to get user's token. Most likely due to the fact user is not logged in using Percona Account. -var ErrFailedToGetToken = errors.New("failed to get token") +// ErrFailedToGetToken means it failed to get the user token. Most likely due to the fact the user is not logged in using Percona Account. +var ErrFailedToGetToken = errors.New("failed to get the user token") const ( pmmServiceTokenName = "pmm-agent-st" //nolint:gosec @@ -111,7 +111,7 @@ func (e *clientError) Error() string { // do makes HTTP request with given parameters, and decodes JSON response with 200 OK status // to respBody. It returns wrapped clientError on any other status, or other fatal errors. // Ctx is used only for cancelation. -func (c *Client) do(ctx context.Context, method, path, rawQuery string, headers http.Header, body []byte, respBody interface{}) error { +func (c *Client) do(ctx context.Context, method, path, rawQuery string, headers http.Header, body []byte, target interface{}) error { u := url.URL{ Scheme: "http", Host: c.addr, @@ -151,8 +151,8 @@ func (c *Client) do(ctx context.Context, method, path, rawQuery string, headers return errors.WithStack(cErr) } - if respBody != nil { - if err = json.Unmarshal(b, respBody); err != nil { + if len(b) > 0 && target != nil { + if err = json.Unmarshal(b, target); err != nil { return errors.WithStack(err) } } @@ -223,26 +223,30 @@ var emptyUser = authUser{ // getAuthUser returns grafanaAdmin if currently authenticated user is a Grafana (super) admin. // Otherwise, it returns a role in the default organization (with ID 1). // Ctx is used only for cancelation. -func (c *Client) getAuthUser(ctx context.Context, authHeaders http.Header) (authUser, error) { +func (c *Client) getAuthUser(ctx context.Context, authHeaders http.Header, l *logrus.Entry) (authUser, error) { // Check if API Key or Service Token is authorized. token := auth.GetTokenFromHeaders(authHeaders) if token != "" { role, err := c.getRoleForServiceToken(ctx, token) - if err != nil { - if strings.Contains(err.Error(), "Auth method is not service account token") { - role, err := c.getRoleForAPIKey(ctx, authHeaders) - return authUser{ - role: role, - userID: 0, - }, err - } + if err == nil { + return authUser{ + role: role, + userID: 0, + }, nil + } - return emptyUser, err + if strings.Contains(err.Error(), "Auth method is not service account token") { + role, err := c.getRoleForAPIKey(ctx, authHeaders) + if err == nil { + l.Warning("you should migrate your API Key to a Service Account") + } + return authUser{ + role: role, + userID: 0, + }, err } - return authUser{ - role: role, - userID: 0, - }, nil + + return emptyUser, err } // https://grafana.com/docs/http_api/user/#actual-user - works only with Basic Auth @@ -679,7 +683,7 @@ func (c *Client) createServiceAccount(ctx context.Context, role role, nodeName s } serviceAccountName := fmt.Sprintf("%s-%s", pmmServiceAccountName, nodeName) - b, err := json.Marshal(serviceAccount{Name: grafana.SanitizeSAName(serviceAccountName), Role: role.String(), Force: reregister}) + b, err := json.Marshal(serviceAccount{Name: serviceAccountName, Role: role.String(), Force: reregister}) if err != nil { return 0, errors.WithStack(err) } @@ -713,7 +717,7 @@ func (c *Client) createServiceToken(ctx context.Context, serviceAccountID int, n } } - b, err := json.Marshal(serviceToken{Name: grafana.SanitizeSAName(serviceTokenName), Role: admin.String()}) + b, err := json.Marshal(serviceToken{Name: serviceTokenName, Role: admin.String()}) if err != nil { return 0, "", errors.WithStack(err) } diff --git a/managed/services/grafana/client_test.go b/managed/services/grafana/client_test.go index 50d28ed1a5..9a9374d35d 100644 --- a/managed/services/grafana/client_test.go +++ b/managed/services/grafana/client_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -31,7 +32,8 @@ import ( ) func TestClient(t *testing.T) { - // logrus.SetLevel(logrus.TraceLevel) + logrus.SetLevel(logrus.TraceLevel) + l := logrus.WithField("test", t.Name()) ctx := context.Background() c := NewClient("127.0.0.1:3000") @@ -43,7 +45,7 @@ func TestClient(t *testing.T) { t.Run("getRole", func(t *testing.T) { t.Run("GrafanaAdmin", func(t *testing.T) { - u, err := c.getAuthUser(ctx, authHeaders) + u, err := c.getAuthUser(ctx, authHeaders, l) role := u.role assert.NoError(t, err) assert.Equal(t, grafanaAdmin, role) @@ -54,7 +56,7 @@ func TestClient(t *testing.T) { // See [auth.anonymous] in grafana.ini. // Even if anonymous access is enabled, returned role is None, not org_role. - u, err := c.getAuthUser(ctx, nil) + u, err := c.getAuthUser(ctx, nil, l) role := u.role clientError, _ := errors.Cause(err).(*clientError) //nolint:errorlint require.NotNil(t, clientError, "got role %s", role) @@ -88,7 +90,7 @@ func TestClient(t *testing.T) { req.SetBasicAuth(login, login) userAuthHeaders := req.Header - u, err := c.getAuthUser(ctx, userAuthHeaders) + u, err := c.getAuthUser(ctx, userAuthHeaders, l) actualRole := u.role assert.NoError(t, err) assert.Equal(t, viewer, actualRole) @@ -115,7 +117,7 @@ func TestClient(t *testing.T) { req.SetBasicAuth(login, login) userAuthHeaders := req.Header - u, err := c.getAuthUser(ctx, userAuthHeaders) + u, err := c.getAuthUser(ctx, userAuthHeaders, l) actualRole := u.role require.NoError(t, err) assert.Equal(t, role, actualRole) @@ -138,7 +140,7 @@ func TestClient(t *testing.T) { apiKeyAuthHeaders := http.Header{} apiKeyAuthHeaders.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey)) - u, err := c.getAuthUser(ctx, apiKeyAuthHeaders) + u, err := c.getAuthUser(ctx, apiKeyAuthHeaders, l) actualRole := u.role require.NoError(t, err) assert.Equal(t, role, actualRole) @@ -167,7 +169,7 @@ func TestClient(t *testing.T) { serviceTokenAuthHeaders := http.Header{} serviceTokenAuthHeaders.Set("Authorization", fmt.Sprintf("Bearer %s", serviceToken)) - u, err := c.getAuthUser(ctx, serviceTokenAuthHeaders) + u, err := c.getAuthUser(ctx, serviceTokenAuthHeaders, l) assert.NoError(t, err) actualRole := u.role assert.Equal(t, role, actualRole) diff --git a/managed/services/user/user.go b/managed/services/user/user.go index eb0443b90a..a4bd0ea1d8 100644 --- a/managed/services/user/user.go +++ b/managed/services/user/user.go @@ -68,10 +68,11 @@ func (s *Service) GetUser(ctx context.Context, _ *userv1.GetUserRequest) (*userv } resp := &userv1.GetUserResponse{ - UserId: uint32(userInfo.ID), - ProductTourCompleted: userInfo.Tour, - AlertingTourCompleted: userInfo.AlertingTour, - SnoozedPmmVersion: userInfo.SnoozedPMMVersion, + UserId: uint32(userInfo.ID), + ProductTourCompleted: userInfo.Tour, + AlertingTourCompleted: userInfo.AlertingTour, + SnoozedPmmVersion: userInfo.SnoozedPMMVersion, + SnoozedApiKeysMigration: userInfo.SnoozedAPIKeysMigration, } return resp, nil } @@ -95,9 +96,10 @@ func (s *Service) UpdateUser(ctx context.Context, req *userv1.UpdateUserRequest) } params := &models.UpdateUserParams{ - UserID: userInfo.ID, - Tour: req.ProductTourCompleted, - AlertingTour: req.AlertingTourCompleted, + UserID: userInfo.ID, + Tour: req.ProductTourCompleted, + AlertingTour: req.AlertingTourCompleted, + SnoozedAPIKeysMigration: req.SnoozedApiKeysMigration, } if req.SnoozedPmmVersion != nil { params.SnoozedPMMVersion = req.SnoozedPmmVersion @@ -115,10 +117,11 @@ func (s *Service) UpdateUser(ctx context.Context, req *userv1.UpdateUserRequest) } resp := &userv1.UpdateUserResponse{ - UserId: uint32(userInfo.ID), - ProductTourCompleted: userInfo.Tour, - AlertingTourCompleted: userInfo.AlertingTour, - SnoozedPmmVersion: userInfo.SnoozedPMMVersion, + UserId: uint32(userInfo.ID), + ProductTourCompleted: userInfo.Tour, + AlertingTourCompleted: userInfo.AlertingTour, + SnoozedPmmVersion: userInfo.SnoozedPMMVersion, + SnoozedApiKeysMigration: userInfo.SnoozedAPIKeysMigration, } return resp, nil }