Skip to content

Commit 3cb9f9f

Browse files
JiriCtvrtkaademidoffBupycHuk
authored
PMM-12251 PMM-12686 Service accounts. (#2516) (#2852)
* PMM-12251 Service accounts. * PMM-12251Create service account and token. * PMM-12251 Another changes. * PMM-12251 Fix for http client status code, creating of service token. * PMM-12251 Set orgId to 1 to avoid problem with default (-1). * PMM-12251 Mock regen. * PMM-12251 Setup, tokens. * PMM-12251 Basic/Bearer auth. * PMM-12251 Set transport, check token/basic. * PMM-12251 Tidy. * PMM-12251 Lint, small changes. * PMM-12251 Add test, logic changes. * PMM-12251 Test, tokens funcs. * PMM-12251 Not needed, set on transport. * PMM-12251 Mock gen. * PMM-12251 Node changes. * PMM-12251 Add existedServiceToken to NodeRegister. * PMM-12251 Typo. * PMM-12251 Small logic changes. Validation. * PMM-12251 Add API tests. * PMM-12251 Align mock with changes. * Revert "Merge remote-tracking branch 'origin/PMM-12251-service-accounts' into PMM-12251-service-accounts" This reverts commit 82b5826, reversing changes made to 88199cd. * PMM-12251 Tidy. * PMM-12251 Small refactor. * PMM-12251 Fix. * PMM-12251 Unregister. * PMM-12251 Tidy. * PMM-12251 Unregister complete. * PMM-12251 Unregister. * PMM-12251 Fix. * PMM-12251 Remove print. * PMM-12251 Refactor ID int64 to int. * PMM-12251 Modify description in md to be aligned with Service acc. * PMM-12251 Int64 to int in tests. * PMM-12251 Lint. * PMM-12251 Service token ID to int. * PMM-12251 Lint. * PMM-12251 Refactor of IF. * PMM-12251 Warning instead error. * PMM-12251 Auth tools, existed token got from headers. * PMM-12251 Fix in doc. * PMM-12251 Remove token prefix check. * Revert "Bump @typescript-eslint/parser from 6.9.0 to 6.10.0 in /cli-tests (#2601)" This reverts commit 2e66592. * Revert "Bump @typescript-eslint/eslint-plugin from 6.9.0 to 6.10.0 in /cli-tests (#2600)" This reverts commit b8a6e93. * Revert "Bump golang.org/x/text from 0.13.0 to 0.14.0 (#2593)" This reverts commit 7ca2c1a. * Revert "Bump golang.org/x/sys from 0.13.0 to 0.14.0 (#2594)" This reverts commit c472ab8. * Revert "Bump eslint from 8.52.0 to 8.53.0 in /cli-tests (#2596)" This reverts commit fac3eec. * PMM-12251 Remove not used code. * Revert "PMM-12251 Remove not used code." This reverts commit 16cbe9e. * PMM-12251 Token/headers fix. * Revert "Revert "PMM-12251 Remove not used code."" This reverts commit b979363. * PMM-12251 Doc update. * PMM-12251 Remove APIKey permissions tests. * PMM-12251 Better error message. * PMM-12251 Remove API key methods. Refactor. * PMM-12251 Fix when token is empty. * PMM-12251 Basic auth tests. * PMM-12251 Small refactor. * PMM-12251 API Tests clean. * PMM-12251 Typo. * PMM-12251 Start tests in parallel. * PMM-12251 Force in test. * PMM-12251 Merge CreateServiceAccount and CreateServiceToken together. * PMM-12251 Mock. * PMM-12251 Gen. * PMM-12251 Refactor, node name. * PMM-12251 Delete, mock and nodeName. * PMM-12251 Fix node test after changes. * PMM-12251 Fix test. * PMM-12251 nodeName in Service Account name. * PMM-12251 Change in naming. * PMM-12251 Modify API test. Data race. * PMM-12251 Changes. * PMM-12251 Fix V3 failing tests. * PMM-12251 Tests. * PMM-12251 Double paralel. * PMM-12251 Test. * PMM-12251 Changes. * PMM-12251 Changes in API test. * PMM-12251 Modify test back. * PMM-12251 Fix tests. * PMM-12251 Fix version test. * PMM-12251 Fix another cleanup. * PMM-12251 Fix another tests. * PMM-12251 Another fix of tests. * PMM-12251 URL query escape. * PMM-12251 Fix annotation API test. * PMM-12251 Fix external API test. * PMM-12251 Fix remove external API test. * PMM-12251 Fix HAProxy API test. * PMM-12251 Fix another API tests. * PMM-12251 Node test. * PMM-12251 Tidy. * PMM-12251 Comment out for now. * PMM-12251 TODO. * PMM-12251 Temp, TODO lefts. * PMM-12251 Cleanup for migrated API keys in API tests. * PMM-12251 Cleanup for tests. * PMM-12251 Add log error. * PMM-12251 Lint. * PMM-12251 Another fix for very long service accounts names. * PMM-12251 Lint. * PMM-12251 Required changes in mock. * PMM-12251 Lint. * PMM-12251 Remove comment. * PMM-12251 Remove another duplicate test. * PMM-12251 Seeds in generator, ctx. * PMM-12251 Cleanup. * PMM-12251 Make test names/SA names shorter due to limit. * PMM-12251 Lint, formatting. * PMM-12251 Remove leftover code, fix node tests. * Update docs/api/welcome/authentication.md Co-authored-by: Alex Demidoff <alexander.demidoff@percona.com> * Update managed/services/grafana/client.go Co-authored-by: Alex Demidoff <alexander.demidoff@percona.com> * PMM-12251 Add debug error message. * PMM-12251 Handle of non migrated API keys. * PMM-12251 Fix test. * PMM-12251 Small refactor. * PMM-12251 Lint. * Update api-tests/management/mongodb_test.go Co-authored-by: Nurlan Moldomurov <nurlan.moldomurov@percona.com> * Update api-tests/management/mongodb_test.go Co-authored-by: Nurlan Moldomurov <nurlan.moldomurov@percona.com> * Update api/managementpb/node.proto Co-authored-by: Nurlan Moldomurov <nurlan.moldomurov@percona.com> * PMM-12251 Gen after suggestions. * PMM-12251 Gen after merge. * PMM-12251 Another reverted changes. * PMM-12686 Years in licence. * PMM-12686 Basic/Token auth between server and client. (#2852) * PMM-12686 Authorization between server and client. * PMM-12686 Tests. * PMM-12686 Lint. * PMM-12686 Comment fix. * PMM-12686 New required permissions for Connect endpoint. * PMM-12686 Apply suggestion. * PMM-12686 Add unit test for authenticate method. * PMM-12686 Format. * PMM-12686 Part changes after review. * PMM-12686 Unit tests for auth server. * PMM-12686 Revert unnecessary changes anymore. * PMM-12686 Dynamic names in auth test. * PMM-12686 Skip check for pmm-server agent. * PMM-12686 Better local auth check. * PMM-12686 Local auth check. * PMM-12686 Refactor. * PMM-12686 Refactor. * PMM-12686 Refactor. * PMM-12686 Fix. * Update managed/services/grafana/auth_server.go Co-authored-by: Alex Demidoff <alexander.demidoff@percona.com> * PMM-12686 Revert of some changes. * PMM-12686 Another reverted changes. * PMM-12686 Years in licence. * PMM-12686 Missed parallel in one test case. --------- Co-authored-by: Alex Demidoff <alexander.demidoff@percona.com> --------- Co-authored-by: Alex Demidoff <alexander.demidoff@percona.com> Co-authored-by: Nurlan Moldomurov <nurlan.moldomurov@percona.com>
1 parent 848155a commit 3cb9f9f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2464
-553
lines changed

.mockery.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ packages:
3838
interfaces:
3939
agentsRegistry:
4040
agentsStateUpdater:
41-
apiKeyProvider:
41+
authProvider:
4242
checksService:
4343
connectionChecker:
4444
grafanaClient:

admin/commands/base/setup.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,13 @@ func SetupClients(ctx context.Context, globalFlags *flags.GlobalFlags) {
8888
// use JSON APIs over HTTP/1.1
8989
transport := httptransport.New(globalFlags.ServerURL.Host, globalFlags.ServerURL.Path, []string{globalFlags.ServerURL.Scheme})
9090
if u := globalFlags.ServerURL.User; u != nil {
91+
user := u.Username()
9192
password, _ := u.Password()
92-
transport.DefaultAuthentication = httptransport.BasicAuth(u.Username(), password)
93+
if user == "service_token" || user == "api_key" {
94+
transport.DefaultAuthentication = httptransport.BearerToken(password)
95+
} else {
96+
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
97+
}
9398
}
9499
transport.SetLogger(logrus.WithField("component", "server-transport"))
95100
transport.SetDebug(globalFlags.EnableDebug || globalFlags.EnableTrace)

admin/commands/management/unregister.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ package management
1616

1717
import (
1818
"github.com/pkg/errors"
19+
"github.com/sirupsen/logrus"
1920

2021
"github.com/percona/pmm/admin/agentlocal"
2122
"github.com/percona/pmm/admin/commands"
2223
"github.com/percona/pmm/admin/helpers"
23-
"github.com/percona/pmm/api/inventorypb/json/client"
24+
inventoryClient "github.com/percona/pmm/api/inventorypb/json/client"
2425
"github.com/percona/pmm/api/inventorypb/json/client/nodes"
26+
"github.com/percona/pmm/api/managementpb/json/client"
27+
"github.com/percona/pmm/api/managementpb/json/client/node"
2528
)
2629

2730
type unregisterResult struct {
@@ -63,7 +66,7 @@ func (cmd *UnregisterCommand) RunCmd() (commands.Result, error) {
6366
}
6467

6568
nodeID = status.NodeID
66-
node, err := client.Default.Nodes.GetNode(&nodes.GetNodeParams{
69+
node, err := inventoryClient.Default.Nodes.GetNode(&nodes.GetNodeParams{
6770
Context: commands.Ctx,
6871
Body: nodes.GetNodeBody{
6972
NodeID: nodeID,
@@ -78,27 +81,31 @@ func (cmd *UnregisterCommand) RunCmd() (commands.Result, error) {
7881
}
7982
}
8083

81-
params := &nodes.RemoveNodeParams{
82-
Body: nodes.RemoveNodeBody{
84+
params := &node.UnregisterNodeParams{
85+
Body: node.UnregisterNodeBody{
8386
NodeID: nodeID,
8487
Force: cmd.Force,
8588
},
8689
Context: commands.Ctx,
8790
}
8891

89-
_, err = client.Default.Nodes.RemoveNode(params)
92+
res, err := client.Default.Node.UnregisterNode(params)
9093
if err != nil {
9194
return nil, err
9295
}
9396

97+
if res.Payload.Warning != "" {
98+
logrus.Warning(res.Payload.Warning)
99+
}
100+
94101
return &unregisterResult{
95102
NodeID: nodeID,
96103
NodeName: nodeName,
97104
}, nil
98105
}
99106

100107
func nodeIDFromNodeName(nodeName string) (string, error) {
101-
listNodes, err := client.Default.Nodes.ListNodes(nil)
108+
listNodes, err := inventoryClient.Default.Nodes.ListNodes(nil)
102109
if err != nil {
103110
return "", err
104111
}

agent/client/basic_auth.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package client
1717
import (
1818
"context"
1919
"encoding/base64"
20+
"fmt"
2021

2122
"google.golang.org/grpc/credentials"
2223
)
@@ -31,7 +32,7 @@ func (b *basicAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[
3132
auth := b.username + ":" + b.password
3233
enc := base64.StdEncoding.EncodeToString([]byte(auth))
3334
return map[string]string{
34-
"authorization": "Basic " + enc,
35+
"Authorization": fmt.Sprintf("Basic %s", enc),
3536
}, nil
3637
}
3738

agent/client/client.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -748,10 +748,16 @@ func dial(dialCtx context.Context, cfg *config.Config, l *logrus.Entry) (*dialRe
748748
}
749749

750750
if cfg.Server.Username != "" {
751-
opts = append(opts, grpc.WithPerRPCCredentials(&basicAuth{
752-
username: cfg.Server.Username,
753-
password: cfg.Server.Password,
754-
}))
751+
if cfg.Server.Username == "service_token" || cfg.Server.Username == "api_key" {
752+
opts = append(opts, grpc.WithPerRPCCredentials(&tokenAuth{
753+
token: cfg.Server.Password,
754+
}))
755+
} else {
756+
opts = append(opts, grpc.WithPerRPCCredentials(&basicAuth{
757+
username: cfg.Server.Username,
758+
password: cfg.Server.Password,
759+
}))
760+
}
755761
}
756762

757763
l.Infof("Connecting to %s ...", cfg.Server.FilteredURL())

agent/client/token_auth.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (C) 2023 Percona LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package client
16+
17+
import (
18+
"context"
19+
"fmt"
20+
21+
"google.golang.org/grpc/credentials"
22+
)
23+
24+
type tokenAuth struct {
25+
token string
26+
}
27+
28+
// GetRequestMetadata implements credentials.PerRPCCredentials interface.
29+
func (t *tokenAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { //nolint:revive
30+
return map[string]string{
31+
"Authorization": fmt.Sprintf("Bearer %s", t.token),
32+
}, nil
33+
}
34+
35+
// RequireTransportSecurity implements credentials.PerRPCCredentials interface.
36+
func (*tokenAuth) RequireTransportSecurity() bool {
37+
return false
38+
}
39+
40+
// check interfaces.
41+
var (
42+
_ credentials.PerRPCCredentials = (*tokenAuth)(nil)
43+
)

agent/commands/clients.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,13 @@ func setServerTransport(u *url.URL, insecureTLS bool, l *logrus.Entry) {
104104
// use JSON APIs over HTTP/1.1
105105
transport := httptransport.New(u.Host, u.Path, []string{u.Scheme})
106106
if u.User != nil {
107+
user := u.User.Username()
107108
password, _ := u.User.Password()
108-
transport.DefaultAuthentication = httptransport.BasicAuth(u.User.Username(), password)
109+
if user == "service_token" || user == "api_key" {
110+
transport.DefaultAuthentication = httptransport.BearerToken(password)
111+
} else {
112+
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
113+
}
109114
}
110115
transport.SetLogger(l)
111116
transport.SetDebug(l.Logger.GetLevel() >= logrus.DebugLevel)

agent/commands/setup.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ func register(cfg *config.Config, l *logrus.Entry) {
160160
}
161161
cfg.ID = agentID
162162
if token != "" {
163-
cfg.Server.Username = "api_key"
163+
cfg.Server.Username = "service_token"
164164
cfg.Server.Password = token
165165
} else {
166-
l.Info("PMM Server responded with an empty api key token. Consider upgrading PMM Server to the latest version.")
166+
l.Info("PMM Server responded with an empty service token. Consider upgrading PMM Server to the latest version.")
167167
}
168168
fmt.Printf("Registered.\n")
169169
}

api-tests/helpers.go

+37-10
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,23 @@ package apitests
1717

1818
import (
1919
"context"
20+
"crypto/rand"
2021
"fmt"
21-
"math/rand"
22+
"math"
23+
"math/big"
2224
"reflect"
2325
"testing"
2426

2527
"github.com/stretchr/testify/assert"
2628
"github.com/stretchr/testify/require"
2729
"google.golang.org/grpc/codes"
2830

29-
"github.com/percona/pmm/api/inventorypb/json/client"
31+
inventoryClient "github.com/percona/pmm/api/inventorypb/json/client"
3032
"github.com/percona/pmm/api/inventorypb/json/client/agents"
3133
"github.com/percona/pmm/api/inventorypb/json/client/nodes"
3234
"github.com/percona/pmm/api/inventorypb/json/client/services"
35+
"github.com/percona/pmm/api/managementpb/json/client"
36+
"github.com/percona/pmm/api/managementpb/json/client/node"
3337
)
3438

3539
// ErrorResponse represents the response structure for error scenarios.
@@ -49,7 +53,10 @@ type TestingT interface {
4953
func TestString(t TestingT, name string) string {
5054
t.Helper()
5155

52-
n := rand.Int() //nolint:gosec
56+
// Without proper seed parallel tests can generate same "random" number.
57+
n, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt32))
58+
require.NoError(t, err)
59+
5360
return fmt.Sprintf("pmm-api-tests/%s/%s/%s/%d", Hostname, t.Name(), name, n)
5461
}
5562

@@ -130,6 +137,26 @@ func (tt *expectedFailureTestingT) Check() {
130137
tt.t.Fatalf("%s expected to fail, but didn't: %s", tt.Name(), tt.link)
131138
}
132139

140+
// UnregisterNodes unregister specified nodes.
141+
func UnregisterNodes(t TestingT, nodeIDs ...string) {
142+
t.Helper()
143+
144+
for _, nodeID := range nodeIDs {
145+
params := &node.UnregisterNodeParams{
146+
Body: node.UnregisterNodeBody{
147+
NodeID: nodeID,
148+
},
149+
Context: context.Background(),
150+
}
151+
152+
res, err := client.Default.Node.UnregisterNode(params)
153+
require.NoError(t, err)
154+
assert.NotNil(t, res)
155+
assert.NotNil(t, res.Payload)
156+
assert.Empty(t, res.Payload.Warning)
157+
}
158+
}
159+
133160
// RemoveNodes removes specified nodes.
134161
func RemoveNodes(t TestingT, nodeIDs ...string) {
135162
t.Helper()
@@ -141,7 +168,7 @@ func RemoveNodes(t TestingT, nodeIDs ...string) {
141168
},
142169
Context: context.Background(),
143170
}
144-
res, err := client.Default.Nodes.RemoveNode(params)
171+
res, err := inventoryClient.Default.Nodes.RemoveNode(params)
145172
assert.NoError(t, err)
146173
assert.NotNil(t, res)
147174
}
@@ -159,7 +186,7 @@ func RemoveServices(t TestingT, serviceIDs ...string) {
159186
},
160187
Context: context.Background(),
161188
}
162-
res, err := client.Default.Services.RemoveService(params)
189+
res, err := inventoryClient.Default.Services.RemoveService(params)
163190
assert.NoError(t, err)
164191
assert.NotNil(t, res)
165192
}
@@ -176,7 +203,7 @@ func RemoveAgents(t TestingT, agentIDs ...string) {
176203
},
177204
Context: context.Background(),
178205
}
179-
res, err := client.Default.Agents.RemoveAgent(params)
206+
res, err := inventoryClient.Default.Agents.RemoveAgent(params)
180207
assert.NoError(t, err)
181208
assert.NotNil(t, res)
182209
}
@@ -193,7 +220,7 @@ func AddGenericNode(t TestingT, nodeName string) *nodes.AddGenericNodeOKBodyGene
193220
},
194221
Context: Context,
195222
}
196-
res, err := client.Default.Nodes.AddGenericNode(params)
223+
res, err := inventoryClient.Default.Nodes.AddGenericNode(params)
197224
assert.NoError(t, err)
198225
require.NotNil(t, res)
199226
require.NotNil(t, res.Payload)
@@ -212,7 +239,7 @@ func AddRemoteNode(t TestingT, nodeName string) *nodes.AddRemoteNodeOKBody {
212239
},
213240
Context: Context,
214241
}
215-
res, err := client.Default.Nodes.AddRemoteNode(params)
242+
res, err := inventoryClient.Default.Nodes.AddRemoteNode(params)
216243
assert.NoError(t, err)
217244
require.NotNil(t, res)
218245
return res.Payload
@@ -227,7 +254,7 @@ func AddNode(t TestingT, nodeBody *nodes.AddNodeBody) *nodes.AddNodeOKBody {
227254
Context: Context,
228255
}
229256

230-
res, err := client.Default.Nodes.AddNode(params)
257+
res, err := inventoryClient.Default.Nodes.AddNode(params)
231258
assert.NoError(t, err)
232259
require.NotNil(t, res)
233260

@@ -238,7 +265,7 @@ func AddNode(t TestingT, nodeBody *nodes.AddNodeBody) *nodes.AddNodeOKBody {
238265
func AddPMMAgent(t TestingT, nodeID string) *agents.AddPMMAgentOKBody {
239266
t.Helper()
240267

241-
res, err := client.Default.Agents.AddPMMAgent(&agents.AddPMMAgentParams{
268+
res, err := inventoryClient.Default.Agents.AddPMMAgent(&agents.AddPMMAgentParams{
242269
Body: agents.AddPMMAgentBody{
243270
RunsOnNodeID: nodeID,
244271
},

0 commit comments

Comments
 (0)