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

Add support for Personal Access Token Authentication #110

Merged
merged 12 commits into from
Mar 15, 2022

Conversation

rporres
Copy link
Contributor

@rporres rporres commented Mar 4, 2022

https://github.com/andygrunwald/go-jira supports natively Personal Token Authentication (PAT). This PR brings it to jiralert.

In order to make this a reality, I needed to do a few things

  • Add tests to config. Since I was going to touch it, I thought that more tests were going to be required
  • Upgrade go to 1.15 due to a go-jira dependency: https://github.com/golang-jwt/jwt
  • Upgrade go-jira to 1.15.1 version to support PAT
  • Add PAT support
  • Test PAT changes in config package

Since some of the changes are related/needed but not exactly what the PR says, I've separated the above actions in different commits. Please let me know if you want them in separate PRs.

Lastly, I haven't written lots of Go code in my life, so apologies in advance for any obvious mistakes or not proper practices this code may have 😅

Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
@rporres rporres mentioned this pull request Mar 4, 2022
rporres added a commit to rporres/container-images that referenced this pull request Mar 7, 2022
This is temporary while
prometheus-community/jiralert#110 is reviewed
and hopefully merged.

Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
rporres added 5 commits March 10, 2022 12:54
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great!

And for all tests - amazing work.

Couple of nits:

  • Consider moving all config checks to one place
  • Please add trailing dot to all comments (we follow Full sentence English)
  • Table tests are great but consider consistent, smaller implementation wit anonymous struct and in place test cases

client, err = jira.NewClient(tp.Client(), conf.APIURL)
} else {
// Config should not allow us to get here, but just in case...
errorHandler(w, http.StatusInternalServerError, fmt.Errorf("missing JIRA auth config"), conf.Name, &data, logger)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
errorHandler(w, http.StatusInternalServerError, fmt.Errorf("missing JIRA auth config"), conf.Name, &data, logger)
errorHandler(w, http.StatusInternalServerError, fmt.Errorf("missing JIRA auth config"), conf.Name, &data, logger)
return

Copy link
Contributor Author

@rporres rporres Mar 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section was removed in ccb0fda as a result of #110 (comment)

@@ -158,11 +159,18 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
// We want to set c to the defaults and then overwrite it with the input.
// To make unmarshal fill the plain data struct rather than calling UnmarshalYAML
// again, we have to hide it using a type indirection.

// TODO: Handle the empty defaults case
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no defaults section, jiralert panics

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x13c40b5]

goroutine 1 [running]:
gopkg.in/yaml%2ev2.handleErr(0xc000157d58)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/yaml.go:249 +0x85
panic(0x15b0f60, 0x1a250c0)
	/Users/rporresm/.goenv/versions/1.15.15/src/runtime/panic.go:969 +0x1b9
github.com/prometheus-community/jiralert/pkg/config.(*Config).UnmarshalYAML(0xc00010f500, 0xc00000d860, 0x0, 0x94b6b18)
	/Users/rporresm/git/github.com/rporres/jiralert/pkg/config/config.go:170 +0x75
gopkg.in/yaml%2ev2.(*decoder).callUnmarshaler(0xc00002f080, 0xc000175ea0, 0x94b6b18, 0xc00010f500, 0xc00010f500)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/decode.go:270 +0xa6
gopkg.in/yaml%2ev2.(*decoder).prepare(0xc00002f080, 0xc000175ea0, 0x1606360, 0xc00010f500, 0x199, 0x104e0a5, 0xc00000e140, 0x0, 0x0)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/decode.go:313 +0x1d0
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00002f080, 0xc000175ea0, 0x1606360, 0xc00010f500, 0x199, 0x0)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/decode.go:364 +0xe9
gopkg.in/yaml%2ev2.(*decoder).document(0xc00002f080, 0xc000175e30, 0x1606360, 0xc00010f500, 0x199, 0x13913a7)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/decode.go:384 +0x7c
gopkg.in/yaml%2ev2.(*decoder).unmarshal(0xc00002f080, 0xc000175e30, 0x1606360, 0xc00010f500, 0x199, 0x199)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/decode.go:360 +0x250
gopkg.in/yaml%2ev2.unmarshal(0xc000132800, 0x3f4, 0x400, 0x15c02c0, 0xc00010f500, 0x400, 0x0, 0x0)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/yaml.go:148 +0x33d
gopkg.in/yaml%2ev2.Unmarshal(...)
	/Users/rporresm/go/1.15.15/pkg/mod/gopkg.in/yaml.v2@v2.3.0/yaml.go:81
github.com/prometheus-community/jiralert/pkg/config.Load(0xc000132400, 0x3f4, 0x3f4, 0xc000132400, 0x3f4)
	/Users/rporresm/git/github.com/rporres/jiralert/pkg/config/config.go:53 +0x99
github.com/prometheus-community/jiralert/pkg/config.LoadFile(0x1657b30, 0x13, 0x16fb140, 0xc000286e10, 0x0, 0x0, 0xc000286f00, 0x0, 0x0, 0x0)
	/Users/rporresm/git/github.com/rporres/jiralert/pkg/config/config.go:67 +0x214
main.main()
	/Users/rporresm/git/github.com/rporres/jiralert/cmd/jiralert/main.go:74 +0x2a5

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarified comment in b7f35ac

client, err = jira.NewClient(tp.Client(), conf.APIURL)
} else {
// Config should not allow us to get here, but just in case...
errorHandler(w, http.StatusInternalServerError, fmt.Errorf("missing JIRA auth config"), conf.Name, &data, logger)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would consider having one place of checking config. Either here or in unmarshal, not mixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Fixed in ccb0fda

pkg/config/config.go Show resolved Hide resolved
pkg/config/config.go Show resolved Hide resolved
pkg/config/config_test.go Outdated Show resolved Hide resolved
pkg/config/config_test.go Outdated Show resolved Hide resolved
pkg/config/config_test.go Outdated Show resolved Hide resolved
Comment on lines 180 to 217
type testCase struct {
receiverTestConfigMandatoryFields []string
errorMessage string
}

mandatory := mandatoryReceiverFields()

// Test cases
// * missing user
// * missing password
// * specifying user/password and PAT auth
testTable := []testCase{
{
removeFromStrSlice(mandatory, "User"),
`missing authentication in receiver "Name"`,
},
{
removeFromStrSlice(mandatory, "Password"),
`missing authentication in receiver "Name"`,
},
{
append(mandatory, "PersonalAccessToken"),
"bad auth config in defaults section: user/password and PAT authentication are mutually exclusive",
},
}

minimalReceiverTestConfig := newReceiverTestConfig([]string{"Name"}, []string{})
for _, test := range testTable {
defaultsConfig := newReceiverTestConfig(test.receiverTestConfigMandatoryFields, []string{})
config := testConfig{
Defaults: defaultsConfig,
Receivers: []*receiverTestConfig{minimalReceiverTestConfig},
Template: "jiralert.tmpl",
}

configErrorTestRunner(t, config, test.errorMessage)
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great!

But there is one pattern we could reuse here to simplify code (and have consistency).

Suggested change
type testCase struct {
receiverTestConfigMandatoryFields []string
errorMessage string
}
mandatory := mandatoryReceiverFields()
// Test cases
// * missing user
// * missing password
// * specifying user/password and PAT auth
testTable := []testCase{
{
removeFromStrSlice(mandatory, "User"),
`missing authentication in receiver "Name"`,
},
{
removeFromStrSlice(mandatory, "Password"),
`missing authentication in receiver "Name"`,
},
{
append(mandatory, "PersonalAccessToken"),
"bad auth config in defaults section: user/password and PAT authentication are mutually exclusive",
},
}
minimalReceiverTestConfig := newReceiverTestConfig([]string{"Name"}, []string{})
for _, test := range testTable {
defaultsConfig := newReceiverTestConfig(test.receiverTestConfigMandatoryFields, []string{})
config := testConfig{
Defaults: defaultsConfig,
Receivers: []*receiverTestConfig{minimalReceiverTestConfig},
Template: "jiralert.tmpl",
}
configErrorTestRunner(t, config, test.errorMessage)
}
}
mandatory := mandatoryReceiverFields()
minimalReceiverTestConfig := newReceiverTestConfig([]string{"Name"}, []string{})
for _, test := range []struct {
receiverTestConfigMandatoryFields []string
errorMessage string
}{
{
// Missing user.
removeFromStrSlice(mandatory, "User"),
`missing authentication in receiver "Name"`,
},
{
// Missing password.
removeFromStrSlice(mandatory, "Password"),
`missing authentication in receiver "Name"`,
},
{
// Specifying user/password and PAT auth.
append(mandatory, "PersonalAccessToken"),
"bad auth config in defaults section: user/password and PAT authentication are mutually exclusive",
},
} {
defaultsConfig := newReceiverTestConfig(test.receiverTestConfigMandatoryFields, []string{})
config := testConfig{
Defaults: defaultsConfig,
Receivers: []*receiverTestConfig{minimalReceiverTestConfig},
Template: "jiralert.tmpl",
}
configErrorTestRunner(t, config, test.errorMessage)
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed this everywhere in b2861cf

rporres added 3 commits March 13, 2022 23:19
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
rporres added 2 commits March 13, 2022 23:35
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
@jankaluza
Copy link

Can we release new version once this is merged and tested? There is a move from basic auth to PAT in my company and we rely on jiralert for monitoring...

Signed-off-by: Rafa Porres Molina <rporresm@redhat.com>
@rporres
Copy link
Contributor Author

rporres commented Mar 14, 2022

This should be ready for a new review, @bwplotka. I've added separate commits to address comments separately. Happy to rearrange commits whenever this is ready to go.

Copy link
Member

@bwplotka bwplotka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, amazing job!

@bwplotka bwplotka merged commit 0c7c40f into prometheus-community:master Mar 15, 2022
@rporres rporres deleted the pat-support-1.15 branch March 15, 2022 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants