* WIP: mutator added, start working on validator * first validator iteration * second validator iteration * wip: working on integration tests * re-working mutation and validation, using Connection interface * fixing some rebase things * fixing integration tests * formatting * fixing unit tests * k8s codegen * linting * moving tests which are available only for enterprise * addressing comments: using repo config for connections, updating tests * addressing comments: adding some more info in the app and installation * fixing app data * addressing comments: updating connection implementation * addressing comments * formatting * fixing tests
94 lines
2.5 KiB
Go
94 lines
2.5 KiB
Go
package github
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/google/go-github/v70/github"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
)
|
|
|
|
// API errors that we need to convey after parsing real GH errors (or faking them).
|
|
var (
|
|
//lint:ignore ST1005 this is not punctuation
|
|
ErrServiceUnavailable = apierrors.NewServiceUnavailable("github is unavailable")
|
|
)
|
|
|
|
//go:generate mockery --name Client --structname MockClient --inpackage --filename client_mock.go --with-expecter
|
|
type Client interface {
|
|
// Apps and installations
|
|
GetApp(ctx context.Context) (App, error)
|
|
GetAppInstallation(ctx context.Context, installationID string) (AppInstallation, error)
|
|
}
|
|
|
|
// App represents a Github App.
|
|
type App struct {
|
|
// ID represents the GH app ID.
|
|
ID int64
|
|
// Slug represents the GH app slug.
|
|
Slug string
|
|
// Owner represents the GH account/org owning the app
|
|
Owner string
|
|
}
|
|
|
|
// AppInstallation represents a Github App Installation.
|
|
type AppInstallation struct {
|
|
// ID represents the GH installation ID.
|
|
ID int64
|
|
// Whether the installation is enabled or not.
|
|
Enabled bool
|
|
}
|
|
|
|
type githubClient struct {
|
|
gh *github.Client
|
|
}
|
|
|
|
func NewClient(client *github.Client) Client {
|
|
return &githubClient{client}
|
|
}
|
|
|
|
// GetApp gets the app by using the given token.
|
|
func (r *githubClient) GetApp(ctx context.Context) (App, error) {
|
|
app, _, err := r.gh.Apps.Get(ctx, "")
|
|
if err != nil {
|
|
var ghErr *github.ErrorResponse
|
|
if errors.As(err, &ghErr) && ghErr.Response.StatusCode == http.StatusServiceUnavailable {
|
|
return App{}, ErrServiceUnavailable
|
|
}
|
|
return App{}, err
|
|
}
|
|
|
|
// TODO(ferruvich): do we need any other info?
|
|
return App{
|
|
ID: app.GetID(),
|
|
Slug: app.GetSlug(),
|
|
Owner: app.GetOwner().GetLogin(),
|
|
}, nil
|
|
}
|
|
|
|
// GetAppInstallation gets the installation of the app related to the given token.
|
|
func (r *githubClient) GetAppInstallation(ctx context.Context, installationID string) (AppInstallation, error) {
|
|
id, err := strconv.Atoi(installationID)
|
|
if err != nil {
|
|
return AppInstallation{}, fmt.Errorf("invalid installation ID: %s", installationID)
|
|
}
|
|
|
|
installation, _, err := r.gh.Apps.GetInstallation(ctx, int64(id))
|
|
if err != nil {
|
|
var ghErr *github.ErrorResponse
|
|
if errors.As(err, &ghErr) && ghErr.Response.StatusCode == http.StatusServiceUnavailable {
|
|
return AppInstallation{}, ErrServiceUnavailable
|
|
}
|
|
return AppInstallation{}, err
|
|
}
|
|
|
|
// TODO(ferruvich): do we need any other info?
|
|
return AppInstallation{
|
|
ID: installation.GetID(),
|
|
Enabled: installation.GetSuspendedAt().IsZero(),
|
|
}, nil
|
|
}
|