Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix APM Server user role #3010

Merged
merged 1 commit into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 48 additions & 4 deletions pkg/controller/association/controller/apm_es.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
package controller

import (
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/manager"
"strings"

apmv1 "github.com/elastic/cloud-on-k8s/pkg/apis/apm/v1"
commonv1 "github.com/elastic/cloud-on-k8s/pkg/apis/common/v1"
"github.com/elastic/cloud-on-k8s/pkg/controller/association"
"github.com/elastic/cloud-on-k8s/pkg/controller/common/operator"
esuser "github.com/elastic/cloud-on-k8s/pkg/controller/elasticsearch/user"
"github.com/elastic/cloud-on-k8s/pkg/controller/common/version"
"github.com/elastic/cloud-on-k8s/pkg/controller/elasticsearch/user"
"github.com/elastic/cloud-on-k8s/pkg/utils/rbac"
pkgerrors "github.com/pkg/errors"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/manager"
)

const (
Expand All @@ -35,6 +38,47 @@ func AddApmES(mgr manager.Manager, accessReviewer rbac.AccessReviewer, params op
}
},
UserSecretSuffix: "apm-user",
ESUserRole: esuser.SuperUserBuiltinRole,
ESUserRole: getRoles,
})
}

// getRoles returns for a given version of the APM Server the set of required roles.
func getRoles(associated commonv1.Associated) (string, error) {
apmServer, ok := associated.(*apmv1.ApmServer)
if !ok {
return "", pkgerrors.Errorf(
"ApmServer expected, got %s/%s",
associated.GetObjectKind().GroupVersionKind().Group,
associated.GetObjectKind().GroupVersionKind().Kind,
)
}

v, err := version.Parse(apmServer.Spec.Version)
if err != nil {
return "", err
}

// 7.5.x and above
if v.IsSameOrAfter(version.From(7, 5, 0)) {
return strings.Join([]string{
user.ApmUserRoleV75, // Retrieve cluster details (e.g. version) and manage apm-* indices
"ingest_admin", // Set up index templates
"apm_system", // To collect metrics about APM Server
}, ","), nil
}

// 7.1.x to 7.4.x
if v.IsSameOrAfter(version.From(7, 1, 0)) {
return strings.Join([]string{
user.ApmUserRoleV7, // Retrieve cluster details (e.g. version) and manage apm-* indices
"ingest_admin", // Set up index templates
"apm_system", // To collect metrics about APM Server
}, ","), nil
}

// 6.8
return strings.Join([]string{
user.ApmUserRoleV6, // Retrieve cluster details (e.g. version) and manage apm-* indices
"apm_system", // To collect metrics about APM Server
}, ","), nil
}
91 changes: 91 additions & 0 deletions pkg/controller/association/controller/apm_es_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package controller

import (
"testing"

apmv1 "github.com/elastic/cloud-on-k8s/pkg/apis/apm/v1"
commonv1 "github.com/elastic/cloud-on-k8s/pkg/apis/common/v1"
)

func Test_getRoles(t *testing.T) {
type args struct {
associated commonv1.Associated
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "Test roles for APM Server v6.8.0",
args: args{
associated: &apmv1.ApmServer{
Spec: apmv1.ApmServerSpec{Version: "6.8.0"},
},
},
want: "eck_apm_user_role_v6,apm_system",
},
{
name: "Test roles for APM Server v6.8.99",
args: args{
associated: &apmv1.ApmServer{
Spec: apmv1.ApmServerSpec{Version: "6.8.99"},
},
},
want: "eck_apm_user_role_v6,apm_system",
},
{
name: "Test roles for APM Server v7.1.0",
args: args{
associated: &apmv1.ApmServer{
Spec: apmv1.ApmServerSpec{Version: "7.1.0"},
},
},
want: "eck_apm_user_role_v7,ingest_admin,apm_system",
},
{
name: "Test roles for APM Server v7.4.99",
args: args{
associated: &apmv1.ApmServer{
Spec: apmv1.ApmServerSpec{Version: "7.4.99"},
},
},
want: "eck_apm_user_role_v7,ingest_admin,apm_system",
},
{
name: "Test roles for APM Server v7.5.0",
args: args{
associated: &apmv1.ApmServer{
Spec: apmv1.ApmServerSpec{Version: "7.5.0"},
},
},
want: "eck_apm_user_role_v75,ingest_admin,apm_system",
},
{
name: "Test roles for APM Server v7.7.99",
args: args{
associated: &apmv1.ApmServer{
Spec: apmv1.ApmServerSpec{Version: "7.7.99"},
},
},
want: "eck_apm_user_role_v75,ingest_admin,apm_system",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getRoles(tt.args.associated)
if (err != nil) != tt.wantErr {
t.Errorf("getRoles() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("getRoles() = %v, want %v", got, tt.want)
}
})
}
}
4 changes: 3 additions & 1 deletion pkg/controller/association/controller/ent_es.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func AddEntES(mgr manager.Manager, accessReviewer rbac.AccessReviewer, params op
}
},
UserSecretSuffix: "ent-user",
ESUserRole: esuser.SuperUserBuiltinRole,
ESUserRole: func(_ commonv1.Associated) (string, error) {
return esuser.SuperUserBuiltinRole, nil
},
})
}
4 changes: 3 additions & 1 deletion pkg/controller/association/controller/kibana_es.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ func AddKibanaES(mgr manager.Manager, accessReviewer rbac.AccessReviewer, params
}
},
UserSecretSuffix: "kibana-user",
ESUserRole: KibanaSystemUserBuiltinRole,
ESUserRole: func(associated commonv1.Associated) (string, error) {
return KibanaSystemUserBuiltinRole, nil
},
})
}
9 changes: 7 additions & 2 deletions pkg/controller/association/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type AssociationInfo struct {
// UserSecretSuffix is used as a suffix in the name of the secret holding user data in the associated namespace.
UserSecretSuffix string
// ESUserRole is the role to use for the Elasticsearch user created by the association.
ESUserRole string
ESUserRole func(commonv1.Associated) (string, error)
}

// userLabelSelector returns labels selecting the ES user secret, including association labels and user type label.
Expand Down Expand Up @@ -177,12 +177,17 @@ func (r *Reconciler) doReconcile(ctx context.Context, associated commonv1.Associ
return commonv1.AssociationFailed, err
}

userRole, err := r.ESUserRole(associated)
if err != nil {
return commonv1.AssociationFailed, err
}

if err := ReconcileEsUser(
ctx,
r.Client,
associated,
assocLabels,
r.ESUserRole,
userRole,
r.UserSecretSuffix,
es,
); err != nil {
Expand Down
4 changes: 3 additions & 1 deletion pkg/controller/association/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ var (
}
},
UserSecretSuffix: "kibana-user",
ESUserRole: "kibana_system",
ESUserRole: func(associated commonv1.Associated) (string, error) {
return "kibana_system", nil
},
}

kibanaNamespace = "kbns"
Expand Down