Skip to content

Commit e792973

Browse files
altieresfreitasAltieres Freitas
authored andcommitted
Add SASL_SCRAM authentication mechanism on kafka exporter
Fix godoc comment to better explain struct proposal Co-authored-by: Juraci Paixão Kröhling <[email protected]> Fix return error message format Co-authored-by: Juraci Paixão Kröhling <[email protected]> Fix Typo on test comment Co-authored-by: Juraci Paixão Kröhling <[email protected]> Add username and password validation to prevent empty values Add specific error message on username and password validation
1 parent 846b971 commit e792973

File tree

7 files changed

+156
-0
lines changed

7 files changed

+156
-0
lines changed

cmd/schemagen/go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,8 +957,11 @@ github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv
957957
github.com/vektra/mockery v0.0.0-20181123154057-e78b021dcbb5/go.mod h1:ppEjwdhyy7Y31EnHRDm1JkChoC7LXIJ7Ex0VYLWtZtQ=
958958
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
959959
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
960+
github.com/xdg-go/scram v0.0.0-20180814205039-7eeb5667e42c h1:Wm21TPasVdeOUTg1m/uNkRdMuvI+jIeYfTIwq98Z2V0=
961+
github.com/xdg-go/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:FV1RpvYFmF8wnKtr3ArzkC0b+tAySCbw8eP7QSIvLKM=
960962
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
961963
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
964+
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
962965
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
963966
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
964967
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=

exporter/kafkaexporter/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ The following settings can be optionally configured:
1919
- `plain_text`
2020
- `username`: The username to use.
2121
- `password`: The password to use
22+
- `sasl`
23+
- `username`: The username to use.
24+
- `password`: The password to use
25+
- `mechanism`: The sasl mechanism to use (SCRAM-SHA-256, SCRAM-SHA-512 or PLAIN)
2226
- `tls`
2327
- `ca_file`: path to the CA cert. For a client this verifies the server certificate. Should
2428
only be used if `insecure` is set to true.

exporter/kafkaexporter/authentication.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package kafkaexporter
1616

1717
import (
18+
"crypto/sha256"
19+
"crypto/sha512"
1820
"fmt"
1921

2022
"github.com/Shopify/sarama"
@@ -25,6 +27,7 @@ import (
2527
// Authentication defines authentication.
2628
type Authentication struct {
2729
PlainText *PlainTextConfig `mapstructure:"plain_text"`
30+
SASL *SASLConfig `mapstructure:"sasl"`
2831
TLS *configtls.TLSClientSetting `mapstructure:"tls"`
2932
Kerberos *KerberosConfig `mapstructure:"kerberos"`
3033
}
@@ -35,6 +38,16 @@ type PlainTextConfig struct {
3538
Password string `mapstructure:"password"`
3639
}
3740

41+
// SASLConfig defines the configuration for the SASL authentication.
42+
type SASLConfig struct {
43+
// Username to be used on authentication
44+
Username string `mapstructure:"username"`
45+
// Password to be used on authentication
46+
Password string `mapstructure:"password"`
47+
// SASL Mechanism to be used, possible values are: (PLAIN, SCRAM-SHA-256 or SCRAM-SHA-512).
48+
Mechanism string `mapstructure:"mechanism"`
49+
}
50+
3851
// KerberosConfig defines kereros configuration.
3952
type KerberosConfig struct {
4053
ServiceName string `mapstructure:"service_name"`
@@ -56,6 +69,12 @@ func ConfigureAuthentication(config Authentication, saramaConfig *sarama.Config)
5669
return err
5770
}
5871
}
72+
if config.SASL != nil {
73+
if err := configureSASL(*config.SASL, saramaConfig); err != nil {
74+
return err
75+
}
76+
}
77+
5978
if config.Kerberos != nil {
6079
configureKerberos(*config.Kerberos, saramaConfig)
6180
}
@@ -68,6 +87,36 @@ func configurePlaintext(config PlainTextConfig, saramaConfig *sarama.Config) {
6887
saramaConfig.Net.SASL.Password = config.Password
6988
}
7089

90+
func configureSASL(config SASLConfig, saramaConfig *sarama.Config) error {
91+
92+
if config.Username == "" {
93+
return fmt.Errorf("username have to be provided")
94+
}
95+
96+
if config.Password == "" {
97+
return fmt.Errorf("password have to be provided")
98+
}
99+
100+
saramaConfig.Net.SASL.Enable = true
101+
saramaConfig.Net.SASL.User = config.Username
102+
saramaConfig.Net.SASL.Password = config.Password
103+
104+
switch config.Mechanism {
105+
case "SCRAM-SHA-512":
106+
saramaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: sha512.New} }
107+
saramaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512
108+
case "SCRAM-SHA-256":
109+
saramaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: sha256.New} }
110+
saramaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA256
111+
case "PLAIN":
112+
saramaConfig.Net.SASL.Mechanism = sarama.SASLTypePlaintext
113+
default:
114+
return fmt.Errorf("invalid SASL Mechanism %q: can be either \"PLAIN\" , \"SCRAM-SHA-256\" or \"SCRAM-SHA-512\"", config.Mechanism)
115+
}
116+
117+
return nil
118+
}
119+
71120
func configureTLS(config configtls.TLSClientSetting, saramaConfig *sarama.Config) error {
72121
tlsConfig, err := config.LoadTLSConfig()
73122
if err != nil {

exporter/kafkaexporter/authentication_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,25 @@ func TestAuthentication(t *testing.T) {
3030
saramaPlaintext.Net.SASL.User = "jdoe"
3131
saramaPlaintext.Net.SASL.Password = "pass"
3232

33+
saramaSASLSCRAM256Config := &sarama.Config{}
34+
saramaSASLSCRAM256Config.Net.SASL.Enable = true
35+
saramaSASLSCRAM256Config.Net.SASL.User = "jdoe"
36+
saramaSASLSCRAM256Config.Net.SASL.Password = "pass"
37+
saramaSASLSCRAM256Config.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA256
38+
39+
saramaSASLSCRAM512Config := &sarama.Config{}
40+
saramaSASLSCRAM512Config.Net.SASL.Enable = true
41+
saramaSASLSCRAM512Config.Net.SASL.User = "jdoe"
42+
saramaSASLSCRAM512Config.Net.SASL.Password = "pass"
43+
saramaSASLSCRAM512Config.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512
44+
45+
saramaSASLPLAINConfig := &sarama.Config{}
46+
saramaSASLPLAINConfig.Net.SASL.Enable = true
47+
saramaSASLPLAINConfig.Net.SASL.User = "jdoe"
48+
saramaSASLPLAINConfig.Net.SASL.Password = "pass"
49+
50+
saramaSASLPLAINConfig.Net.SASL.Mechanism = sarama.SASLTypePlaintext
51+
3352
saramaTLSCfg := &sarama.Config{}
3453
saramaTLSCfg.Net.TLS.Enable = true
3554
tlsClient := configtls.TLSClientSetting{}
@@ -77,6 +96,34 @@ func TestAuthentication(t *testing.T) {
7796
auth: Authentication{Kerberos: &KerberosConfig{UseKeyTab: true, KeyTabPath: "/path"}},
7897
saramaConfig: saramaKerberosKeyTabCfg,
7998
},
99+
{
100+
auth: Authentication{SASL: &SASLConfig{Username: "jdoe", Password: "pass", Mechanism: "SCRAM-SHA-256"}},
101+
saramaConfig: saramaSASLSCRAM256Config,
102+
},
103+
{
104+
auth: Authentication{SASL: &SASLConfig{Username: "jdoe", Password: "pass", Mechanism: "SCRAM-SHA-512"}},
105+
saramaConfig: saramaSASLSCRAM512Config,
106+
},
107+
108+
{
109+
auth: Authentication{SASL: &SASLConfig{Username: "jdoe", Password: "pass", Mechanism: "PLAIN"}},
110+
saramaConfig: saramaSASLPLAINConfig,
111+
},
112+
{
113+
auth: Authentication{SASL: &SASLConfig{Username: "jdoe", Password: "pass", Mechanism: "SCRAM-SHA-222"}},
114+
saramaConfig: saramaSASLSCRAM512Config,
115+
err: "invalid SASL Mechanism",
116+
},
117+
{
118+
auth: Authentication{SASL: &SASLConfig{Username: "", Password: "pass", Mechanism: "SCRAM-SHA-512"}},
119+
saramaConfig: saramaSASLSCRAM512Config,
120+
err: "username have to be provided",
121+
},
122+
{
123+
auth: Authentication{SASL: &SASLConfig{Username: "jdoe", Password: "", Mechanism: "SCRAM-SHA-512"}},
124+
saramaConfig: saramaSASLSCRAM512Config,
125+
err: "password have to be provided",
126+
},
80127
}
81128
for _, test := range tests {
82129
t.Run("", func(t *testing.T) {
@@ -86,6 +133,8 @@ func TestAuthentication(t *testing.T) {
86133
require.Error(t, err)
87134
assert.Contains(t, err.Error(), test.err)
88135
} else {
136+
// equalizes SCRAMClientGeneratorFunc to do assertion with the same reference.
137+
config.Net.SASL.SCRAMClientGeneratorFunc = test.saramaConfig.Net.SASL.SCRAMClientGeneratorFunc
89138
assert.Equal(t, test.saramaConfig, config)
90139
}
91140
})
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright The OpenTelemetry Authors
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 kafkaexporter
16+
17+
import (
18+
"github.com/Shopify/sarama"
19+
"github.com/xdg-go/scram"
20+
)
21+
22+
var _ sarama.SCRAMClient = (*XDGSCRAMClient)(nil)
23+
24+
// XDGSCRAMClient uses xdg-go scram to authentication conversation
25+
type XDGSCRAMClient struct {
26+
*scram.Client
27+
*scram.ClientConversation
28+
scram.HashGeneratorFcn
29+
}
30+
31+
func (x *XDGSCRAMClient) Begin(userName, password, authzID string) (err error) {
32+
x.Client, err = x.HashGeneratorFcn.NewClient(userName, password, authzID)
33+
if err != nil {
34+
return err
35+
}
36+
x.ClientConversation = x.Client.NewConversation()
37+
return nil
38+
}
39+
40+
func (x *XDGSCRAMClient) Step(challenge string) (response string, err error) {
41+
return x.ClientConversation.Step(challenge)
42+
43+
}
44+
45+
func (x *XDGSCRAMClient) Done() bool {
46+
return x.ClientConversation.Done()
47+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ require (
4949
github.com/tinylib/msgp v1.1.5
5050
github.com/uber/jaeger-lib v2.4.0+incompatible
5151
go.opencensus.io v0.22.6
52+
github.com/xdg-go/scram v0.0.0-20180814205039-7eeb5667e42c
5253
go.uber.org/atomic v1.7.0
5354
go.uber.org/zap v1.16.0
5455
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,11 @@ github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv
959959
github.com/vektra/mockery v0.0.0-20181123154057-e78b021dcbb5/go.mod h1:ppEjwdhyy7Y31EnHRDm1JkChoC7LXIJ7Ex0VYLWtZtQ=
960960
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
961961
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
962+
github.com/xdg-go/scram v0.0.0-20180814205039-7eeb5667e42c h1:Wm21TPasVdeOUTg1m/uNkRdMuvI+jIeYfTIwq98Z2V0=
963+
github.com/xdg-go/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:FV1RpvYFmF8wnKtr3ArzkC0b+tAySCbw8eP7QSIvLKM=
962964
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
963965
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
966+
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
964967
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
965968
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
966969
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=

0 commit comments

Comments
 (0)