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

Set up GitHub oauth for rerun button #13008

Merged
merged 1 commit into from
Jun 20, 2019

Conversation

mirandachrist
Copy link
Contributor

More specifically, this change will make it check if the user is logged in when they click the rerun button. If they are, the rerun button will do what it already does and show a popup with a command to run to rerun the test.
If the user is not logged in, it will redirect to GitHub oauth, then redirect back to prow.k8s.io

/assign @cjwagner
/cc @fejta
/cc @Katharine

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. area/prow Issues or PRs related to prow area/prow/deck Issues or PRs related to prow's deck component sig/testing Categorizes an issue or PR as relevant to SIG Testing. labels Jun 13, 2019
@krzyzacy
Copy link
Member

high-level design question (maybe for @cjwagner or @Katharine): how would this fit into things like gerrit?

@stevekuznetsov
Copy link
Contributor

Why do we want this? The modal popup doesn't do anything other than show you a command you already can't run if you don't have rights.

@mirandachrist
Copy link
Contributor Author

Why do we want this? The modal popup doesn't do anything other than show you a command you already can't run if you don't have rights.

We eventually want to make the button trigger the test directly, and we'll need the GitHub oauth to make sure the user has the rights. This is the first step toward that.

@stevekuznetsov
Copy link
Contributor

stevekuznetsov commented Jun 13, 2019

I don't want this change, though. Today, when people ask me to rerun a job for them they paste me the command and I just run it. This change would make it not possible for them to do that.

@mirandachrist
Copy link
Contributor Author

You'll still be able to rerun jobs for people, since the /rerun endpoint will stay the same, and they can send you the job number, which is viewable from the new YAML button. I could also still show the popup (without oauth required) in addition to giving the option to rerun directly (which would require oauth).
This PR lets anyone with a GitHub account view the popup, so in practice it shouldn't change much.

@stevekuznetsov
Copy link
Contributor

I would rather not change the current UX.

What is our final state we're designing towards, here? Are we changing the behavior of /rerun endpoint? Absent a design doc I was hoping we'd see a "rerun" button for jobs that would take you to a page, guarded by OAuth, that would allow you to:

  • run another job with the same spec
  • trigger another job by re-resolving the trigger-time spec data

The page could also be used to trigger a job (not necessarily by getting there from an exiting job's view) to allow users to trigger runs of jobs that did not have any current ProwJob records.

IMO we should present the new feature as a standalone item, let it mature, then migrate to it and remove the old button as necessary. This is similar to the approach @Katharine took in implementing spyglass and leads to a smooth transition from the current feature set to the new feature set.

@mirandachrist
Copy link
Contributor Author

@stevekuznetsov
Copy link
Contributor

Throw those out to the SIG on Slack and the mailing list when you've got them, it's great to read :)

@Katharine
Copy link
Member

I agree with Steve that I don't think it makes sense to launch parts of this piecemeal into production - the end state is strictly better, but the intermediate states include confusing regressions from current functionality, and shouldn't be what we serve users while we keep working on it.

@mirandachrist
Copy link
Contributor Author

I'll modify this PR so the current popup can still be viewed without oauth, and I'll add a button on the current popup that requires oauth but does nothing (this will turn into the "trigger job directly" button later). Thanks everyone for your input :)

@mirandachrist
Copy link
Contributor Author

It now doesn't require oauth until you click the "Run" button:
image
After clicking the "Run" button and logging in, you see:
image

prow/cmd/deck/static/prow/prow.ts Outdated Show resolved Hide resolved
prow/cmd/deck/static/prow/prow.ts Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth_test.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
@alvaroaleman
Copy link
Member

I agree with Steve that I don't think it makes sense to launch parts of this piecemeal into production - the end state is strictly better, but the intermediate states include confusing regressions from current functionality, and shouldn't be what we serve users while we keep working on it.

What about featuregating this? That way, @mirandachrist can get something merged without needing the full thing to be done. Additionally, users like us that have a deck instance that is not publicly accessible might want to never activate this feature, because everyone who gets to the point of seeing the button is permitted to use it

Copy link
Member

@Katharine Katharine left a comment

Choose a reason for hiding this comment

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

This looks good from the perspective of doing the authentication.

I'm not sure I love adding a button that explicitly doesn't work - it would be nice to gate that so everyone doesn't see it when they update. I'm also not totally convinced that it should be a link in the already-logged-in case, but I don't think that's the intended final form?

A side note: you've marked a bunch of comments as "resolved", but they haven't been changed. I assume you use this to mean you have made the changes in your working copy. For the sanity of your reviewers, I would request that you not mark something as resolved until you have pushed up the relevant changes.

@@ -387,8 +387,10 @@ function getFullPRContext(builds: Job[], contexts: Context[]): UnifiedContext[]
*/
function loadPrStatus(prData: UserData): void {
const tideQueries: TideQuery[] = [];
for (const query of tideData.TideQueries) {
tideQueries.push(new TideQuery(query));
if (tideData.TideQueries != null) {
Copy link
Member

@Katharine Katharine Jun 17, 2019

Choose a reason for hiding this comment

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

Can this happen? According to the definition of TideData, it can't, in which case this check makes no sense.

If you think it can happen, then a) please explain when it happens, and then b) fix the typescript definition of TideData to match. You'll probably subsequently have to make a lot of other changes too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This fixed a null pointer error that was coming up in my test instance when there were no TideQueries. Honestly, I'm not really sure what was going on. Should I just change it back?

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 probably a real bug that should probably be fixed. I haven't traced the code in depth, but my educated guess is as follows:

Go considers nil to be a valid, empty slice. Consequently, it is idiomatic to initialise a slice with nil (by doing e.g. var someSlice []string or whatever). This nil then eventually gets JSON serialised as null (because it's not really an empty slice, it's just null). While the Go structs do not specify omitempty, and so the empty value is included, the empty value is null rather than an empty array ([]). Unfortunately, Go is unusual in thinking that null is a valid array, and so when we later parse that in TypeScript, it is null with no type and any attempt to operate on it fails.

To fix this, we should either change the TypeScript type so it accepts nulls (and then add null checks probably all over the place), or change the Go code so it can never be nil (e.g. by actually initialising to an empty slice somewhere).

In either case, though, the fix probably belongs in another PR - I'd file an issue, remove this change, and follow up later.

Copy link
Contributor

Choose a reason for hiding this comment

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

Go is unusual in thinking that null is a valid array

If we're being very pedantic, nil is a valid (zero) value for a slice, but not an array ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added an issue

prow/cmd/deck/static/prow/prow.ts Show resolved Hide resolved
prow/cmd/deck/static/prow/prow.ts Outdated Show resolved Hide resolved
prow/cmd/deck/static/prow/prow.ts Outdated Show resolved Hide resolved
prow/cmd/deck/static/prow/prow.ts Outdated Show resolved Hide resolved
@@ -92,6 +109,8 @@ func NewAgent(config *config.GitHubOAuthConfig, logger *logrus.Entry) *Agent {
// redirect user to GitHub OAuth end-point for authentication.
func (ga *Agent) HandleLogin(client OAuthClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
destPage := r.URL.Query().Get("dest")
rerunStatus := r.URL.Query().Get("rerun_status")
Copy link
Member

Choose a reason for hiding this comment

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

This feels very specific to the particular reason we are logging in. Would it make sense to be more generic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the future, this will contain the name of the prow job, so when the page reloads after logging in, the same popup for the same job appears. I renamed it to make it make a little more sense.

prow/cmd/deck/static/prow/prow.ts Outdated Show resolved Hide resolved
// Exchanges code from GitHub OAuth redirect for user access token.
Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
// Returns a URL to GitHub's OAuth 2.0 consent page. The state is a token to protect the user
// from an XSRF attack.
AuthCodeURL(state string, opts ...oauth2.AuthCodeOption) string
}

type RealOAuthClient struct {
Copy link
Member

Choose a reason for hiding this comment

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

Why is this "real"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got rid of this. It was "real" in contrast to the mock OAuthClient in the tests.

if (login === "") {
i.href = `https://${window.location.hostname}/github-login?rerun_status=work_in_progress`;
} else {
runButton.href = `https://${window.location.hostname}/?rerun_status=work_in_progress`;
Copy link
Member

Choose a reason for hiding this comment

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

On further thought, I'm also not a huge fan of this being a link at all, but perhaps that's going to change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the future, it will link to the /rerun endpoint and rerun the job, as in Alvaro's PR

Copy link
Member

Choose a reason for hiding this comment

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

Did we decide against a dialog in the page? I haven't checked the design doc recently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We will have a dialog:
image

runButton will become the button in the bottom right. After the test is triggered, we'll have another dialog saying it was successful.

@Katharine
Copy link
Member

/lint

Copy link
Contributor

@k8s-ci-robot k8s-ci-robot left a comment

Choose a reason for hiding this comment

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

@Katharine: 5 warnings.

In response to this:

/lint

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth.go Outdated Show resolved Hide resolved
prow/githuboauth/githuboauth_test.go Outdated Show resolved Hide resolved
@stevekuznetsov
Copy link
Contributor

I think these two comments are still outstanding:
#13008 (comment)
#13008 (comment)

@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 19, 2019
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 19, 2019
@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jun 19, 2019
@Katharine
Copy link
Member

Katharine commented Jun 20, 2019

I don't think you wanted to include prow.ts.orig

@k8s-ci-robot k8s-ci-robot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Jun 20, 2019
@k8s-ci-robot
Copy link
Contributor

k8s-ci-robot commented Jun 20, 2019

@mirandachrist: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
pull-test-infra-gubernator 8e2923e link /test pull-test-infra-gubernator

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 20, 2019
@mirandachrist
Copy link
Contributor Author

Removed @Katharine

@stevekuznetsov
Copy link
Contributor

You likely want to squash your commits :)

@mirandachrist
Copy link
Contributor Author

Done

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 20, 2019
@k8s-ci-robot
Copy link
Contributor

LGTM label has been added.

Git tree hash: 7f73954eb39aa90c502ab0826a5cd7d802ae213f

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Katharine, mirandachrist, stevekuznetsov

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@stevekuznetsov
Copy link
Contributor

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 20, 2019
@k8s-ci-robot k8s-ci-robot merged commit d6e1977 into kubernetes:master Jun 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/prow/deck Issues or PRs related to prow's deck component area/prow Issues or PRs related to prow cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. sig/cluster-lifecycle Categorizes an issue or PR as relevant to SIG Cluster Lifecycle. sig/release Categorizes an issue or PR as relevant to SIG Release. sig/testing Categorizes an issue or PR as relevant to SIG Testing. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants