mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Auth: Add empty role usage metrics for service and user accounts (#73108)
* Add tests for service accounts metrics usage * Add service account store implementation * Add service account service implementation * Add tests for org metrics usage * Add org implementation * Add service implementation
This commit is contained in:
@@ -12,10 +12,16 @@ func (s *ServiceAccountsStoreImpl) GetUsageMetrics(ctx context.Context) (*servic
|
||||
|
||||
sb := &db.SQLBuilder{}
|
||||
sb.Write("SELECT ")
|
||||
sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("user") +
|
||||
` WHERE is_service_account = ` + dialect.BooleanStr(true) + `) AS serviceaccounts,`)
|
||||
sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("user") + ` ` +
|
||||
`WHERE is_service_account = ` + dialect.BooleanStr(true) + `) AS serviceaccounts,`)
|
||||
sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("api_key") +
|
||||
` WHERE service_account_id IS NOT NULL ) AS serviceaccount_tokens`)
|
||||
`WHERE service_account_id IS NOT NULL ) AS serviceaccount_tokens,`)
|
||||
sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("org_user") + ` AS ou ` +
|
||||
`JOIN ` + dialect.Quote("user") + ` AS u ON u.id = ou.user_id ` +
|
||||
`WHERE u.is_disabled = ` + dialect.BooleanStr(false) + ` ` +
|
||||
`AND u.is_service_account = ` + dialect.BooleanStr(true) + ` ` +
|
||||
`AND ou.role=?) AS serviceaccounts_with_no_role`)
|
||||
sb.AddParams("None")
|
||||
|
||||
var sqlStats serviceaccounts.Stats
|
||||
if err := s.sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/satokengen"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/tests"
|
||||
)
|
||||
@@ -33,10 +34,18 @@ func TestIntegrationStore_UsageStats(t *testing.T) {
|
||||
_, err = store.AddServiceAccountToken(context.Background(), sa.ID, &cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
role := org.RoleNone
|
||||
form := serviceaccounts.UpdateServiceAccountForm{
|
||||
Role: &role,
|
||||
}
|
||||
_, err = store.UpdateServiceAccount(context.Background(), sa.OrgID, sa.ID, &form)
|
||||
require.NoError(t, err)
|
||||
|
||||
stats, err := store.GetUsageMetrics(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, int64(1), stats.ServiceAccounts)
|
||||
assert.Equal(t, int64(1), stats.ServiceAccountsWithNoRole)
|
||||
assert.Equal(t, int64(1), stats.Tokens)
|
||||
assert.Equal(t, true, stats.ForcedExpiryEnabled)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ var (
|
||||
// MStatTotalServiceAccounts is a metric gauge for total number of service accounts
|
||||
MStatTotalServiceAccounts prometheus.Gauge
|
||||
|
||||
// MStatTotalServiceAccountsNoRole is a metric gauge for total number of user accounts with no role
|
||||
MStatTotalServiceAccountsNoRole prometheus.Gauge
|
||||
|
||||
// MStatTotalServiceAccountTokens is a metric gauge for total number of service account tokens
|
||||
MStatTotalServiceAccountTokens prometheus.Gauge
|
||||
|
||||
@@ -27,6 +30,12 @@ func init() {
|
||||
Namespace: ExporterName,
|
||||
})
|
||||
|
||||
MStatTotalServiceAccountsNoRole = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "stat_total_service_accounts_role_none",
|
||||
Help: "total amount of service accounts with no role",
|
||||
Namespace: ExporterName,
|
||||
})
|
||||
|
||||
MStatTotalServiceAccountTokens = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "stat_total_service_account_tokens",
|
||||
Help: "total amount of service account tokens",
|
||||
@@ -36,6 +45,7 @@ func init() {
|
||||
prometheus.MustRegister(
|
||||
MStatTotalServiceAccounts,
|
||||
MStatTotalServiceAccountTokens,
|
||||
MStatTotalServiceAccountsNoRole,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -48,6 +58,7 @@ func (sa *ServiceAccountsService) getUsageMetrics(ctx context.Context) (map[stri
|
||||
}
|
||||
|
||||
stats["stats.serviceaccounts.count"] = storeStats.ServiceAccounts
|
||||
stats["stats.serviceaccounts.role_none.count"] = storeStats.ServiceAccountsWithNoRole
|
||||
stats["stats.serviceaccounts.tokens.count"] = storeStats.Tokens
|
||||
|
||||
var forcedExpiryEnabled int64 = 0
|
||||
@@ -64,8 +75,9 @@ func (sa *ServiceAccountsService) getUsageMetrics(ctx context.Context) (map[stri
|
||||
|
||||
stats["stats.serviceaccounts.secret_scan.enabled.count"] = secretScanEnabled
|
||||
|
||||
MStatTotalServiceAccountTokens.Set(float64(storeStats.Tokens))
|
||||
MStatTotalServiceAccounts.Set(float64(storeStats.ServiceAccounts))
|
||||
MStatTotalServiceAccountsNoRole.Set(float64(storeStats.ServiceAccountsWithNoRole))
|
||||
MStatTotalServiceAccountTokens.Set(float64(storeStats.Tokens))
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
@@ -18,15 +18,17 @@ func Test_UsageStats(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
storeMock.ExpectedStats = &serviceaccounts.Stats{
|
||||
ServiceAccounts: 1,
|
||||
Tokens: 1,
|
||||
ForcedExpiryEnabled: false,
|
||||
ServiceAccounts: 1,
|
||||
ServiceAccountsWithNoRole: 1,
|
||||
Tokens: 1,
|
||||
ForcedExpiryEnabled: false,
|
||||
}
|
||||
stats, err := svc.getUsageMetrics(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, stats, 4, stats)
|
||||
assert.Len(t, stats, 5, stats)
|
||||
assert.Equal(t, int64(1), stats["stats.serviceaccounts.count"].(int64))
|
||||
assert.Equal(t, int64(1), stats["stats.serviceaccounts.role_none.count"].(int64))
|
||||
assert.Equal(t, int64(1), stats["stats.serviceaccounts.tokens.count"].(int64))
|
||||
assert.Equal(t, int64(1), stats["stats.serviceaccounts.secret_scan.enabled.count"].(int64))
|
||||
assert.Equal(t, int64(0), stats["stats.serviceaccounts.forced_expiry_enabled.count"].(int64))
|
||||
|
||||
@@ -160,9 +160,10 @@ const (
|
||||
)
|
||||
|
||||
type Stats struct {
|
||||
ServiceAccounts int64 `xorm:"serviceaccounts"`
|
||||
Tokens int64 `xorm:"serviceaccount_tokens"`
|
||||
ForcedExpiryEnabled bool `xorm:"-"`
|
||||
ServiceAccounts int64 `xorm:"serviceaccounts"`
|
||||
ServiceAccountsWithNoRole int64 `xorm:"serviceaccounts_with_no_role"`
|
||||
Tokens int64 `xorm:"serviceaccount_tokens"`
|
||||
ForcedExpiryEnabled bool `xorm:"-"`
|
||||
}
|
||||
|
||||
// AccessEvaluator is used to protect the "Configuration > Service accounts" page access
|
||||
|
||||
Reference in New Issue
Block a user