Use github package to access the GitHub API
This commit is contained in:
parent
5f608058cd
commit
3ccc51433f
|
|
@ -20,10 +20,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/go-github/v29/github"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/record"
|
||||
|
|
@ -34,6 +32,7 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/summerwind/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/summerwind/actions-runner-controller/github"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -41,23 +40,6 @@ const (
|
|||
finalizerName = "runner.actions.summerwind.dev"
|
||||
)
|
||||
|
||||
type GitHubRunnerList struct {
|
||||
TotalCount int `json:"total_count"`
|
||||
Runners []GitHubRunner `json:"runners,omitempty"`
|
||||
}
|
||||
|
||||
type GitHubRunner struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
OS string `json:"os"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type GitHubRegistrationToken struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt string `json:"expires_at"`
|
||||
}
|
||||
|
||||
// RunnerReconciler reconciles a Runner object
|
||||
type RunnerReconciler struct {
|
||||
client.Client
|
||||
|
|
@ -126,7 +108,7 @@ func (r *RunnerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||
}
|
||||
|
||||
if !runner.IsRegisterable() {
|
||||
reg, err := r.newRegistration(ctx, runner.Spec.Repository)
|
||||
rt, err := r.GitHubClient.GetRegistrationToken(ctx, runner.Spec.Repository, runner.Name)
|
||||
if err != nil {
|
||||
r.Recorder.Event(&runner, corev1.EventTypeWarning, "FailedUpdateRegistrationToken", "Updating registration token failed")
|
||||
log.Error(err, "Failed to get new registration token")
|
||||
|
|
@ -134,7 +116,11 @@ func (r *RunnerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||
}
|
||||
|
||||
updated := runner.DeepCopy()
|
||||
updated.Status.Registration = reg
|
||||
updated.Status.Registration = v1alpha1.RunnerStatusRegistration{
|
||||
Repository: runner.Spec.Repository,
|
||||
Token: rt.GetToken(),
|
||||
ExpiresAt: metav1.NewTime(rt.GetExpiresAt().Time),
|
||||
}
|
||||
|
||||
if err := r.Status().Update(ctx, updated); err != nil {
|
||||
log.Error(err, "Failed to update runner status")
|
||||
|
|
@ -226,109 +212,31 @@ func (r *RunnerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) newRegistration(ctx context.Context, repo string) (v1alpha1.RunnerStatusRegistration, error) {
|
||||
var reg v1alpha1.RunnerStatusRegistration
|
||||
|
||||
rt, err := r.getRegistrationToken(ctx, repo)
|
||||
if err != nil {
|
||||
return reg, err
|
||||
}
|
||||
|
||||
expiresAt, err := time.Parse(time.RFC3339, rt.ExpiresAt)
|
||||
if err != nil {
|
||||
return reg, err
|
||||
}
|
||||
|
||||
reg.Repository = repo
|
||||
reg.Token = rt.Token
|
||||
reg.ExpiresAt = metav1.NewTime(expiresAt)
|
||||
|
||||
return reg, err
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) getRegistrationToken(ctx context.Context, repo string) (GitHubRegistrationToken, error) {
|
||||
var regToken GitHubRegistrationToken
|
||||
|
||||
req, err := r.GitHubClient.NewRequest("POST", fmt.Sprintf("/repos/%s/actions/runners/registration-token", repo), nil)
|
||||
if err != nil {
|
||||
return regToken, err
|
||||
}
|
||||
|
||||
res, err := r.GitHubClient.Do(ctx, req, ®Token)
|
||||
if err != nil {
|
||||
return regToken, err
|
||||
}
|
||||
|
||||
if res.StatusCode != 201 {
|
||||
return regToken, fmt.Errorf("unexpected status: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
return regToken, nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) unregisterRunner(ctx context.Context, repo, name string) (bool, error) {
|
||||
runners, err := r.listRunners(ctx, repo)
|
||||
runners, err := r.GitHubClient.ListRunners(ctx, repo)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
id := 0
|
||||
for _, runner := range runners.Runners {
|
||||
if runner.Name == name {
|
||||
id = runner.ID
|
||||
id := int64(0)
|
||||
for _, runner := range runners {
|
||||
if runner.GetName() == name {
|
||||
id = runner.GetID()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if id == 0 {
|
||||
if id == int64(0) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := r.removeRunner(ctx, repo, id); err != nil {
|
||||
if err := r.GitHubClient.RemoveRunner(ctx, repo, id); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) listRunners(ctx context.Context, repo string) (GitHubRunnerList, error) {
|
||||
runners := GitHubRunnerList{}
|
||||
|
||||
req, err := r.GitHubClient.NewRequest("GET", fmt.Sprintf("/repos/%s/actions/runners", repo), nil)
|
||||
if err != nil {
|
||||
return runners, err
|
||||
}
|
||||
|
||||
res, err := r.GitHubClient.Do(ctx, req, &runners)
|
||||
if err != nil {
|
||||
return runners, err
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
return runners, fmt.Errorf("unexpected status: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
return runners, nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) removeRunner(ctx context.Context, repo string, id int) error {
|
||||
req, err := r.GitHubClient.NewRequest("DELETE", fmt.Sprintf("/repos/%s/actions/runners/%d", repo, id), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := r.GitHubClient.Do(ctx, req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if res.StatusCode != 204 {
|
||||
return fmt.Errorf("unexpected status: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *RunnerReconciler) newPod(runner v1alpha1.Runner) (corev1.Pod, error) {
|
||||
var (
|
||||
privileged bool = true
|
||||
|
|
|
|||
8
go.mod
8
go.mod
|
|
@ -3,18 +3,14 @@ module github.com/summerwind/actions-runner-controller
|
|||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
|
||||
github.com/bradleyfalzon/ghinstallation v1.1.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/go-logr/logr v0.1.0
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/google/go-github/v29 v29.0.3
|
||||
github.com/google/go-github/v31 v31.0.0
|
||||
github.com/onsi/ginkgo v1.8.0
|
||||
github.com/onsi/gomega v1.5.0
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275
|
||||
github.com/stretchr/testify v1.4.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
|
||||
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f
|
||||
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655
|
||||
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90
|
||||
|
|
|
|||
13
go.sum
13
go.sum
|
|
@ -18,10 +18,6 @@ github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
|||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
|
|
@ -120,12 +116,10 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
|||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts=
|
||||
github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
|
||||
github.com/google/go-github/v29 v29.0.3 h1:IktKCTwU//aFHnpA+2SLIi7Oo9uhAzgsdZNbcAqhgdc=
|
||||
github.com/google/go-github/v29 v29.0.3/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
|
||||
github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo=
|
||||
github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
|
|
@ -237,6 +231,7 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
|
|
@ -343,8 +338,6 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn
|
|||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
|
|
|
|||
25
main.go
25
main.go
|
|
@ -17,18 +17,14 @@ limitations under the License.
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/bradleyfalzon/ghinstallation"
|
||||
"github.com/google/go-github/v29/github"
|
||||
actionsv1alpha1 "github.com/summerwind/actions-runner-controller/api/v1alpha1"
|
||||
"github.com/summerwind/actions-runner-controller/controllers"
|
||||
"golang.org/x/oauth2"
|
||||
"github.com/summerwind/actions-runner-controller/github"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
|
|
@ -56,6 +52,9 @@ func init() {
|
|||
|
||||
func main() {
|
||||
var (
|
||||
err error
|
||||
ghClient *github.Client
|
||||
|
||||
metricsAddr string
|
||||
enableLeaderElection bool
|
||||
|
||||
|
|
@ -66,8 +65,6 @@ func main() {
|
|||
ghAppID int64
|
||||
ghAppInstallationID int64
|
||||
ghAppPrivateKey string
|
||||
|
||||
ghClient *github.Client
|
||||
)
|
||||
|
||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||
|
|
@ -111,17 +108,17 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
tr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, ghAppID, ghAppInstallationID, ghAppPrivateKey)
|
||||
ghClient, err = github.NewClient(ghAppID, ghAppInstallationID, ghAppPrivateKey)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: Invalid GitHub App credentials: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Error: Failed to create GitHub client: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
ghClient = github.NewClient(&http.Client{Transport: tr})
|
||||
} else if ghToken != "" {
|
||||
tc := oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: ghToken},
|
||||
))
|
||||
ghClient = github.NewClient(tc)
|
||||
ghClient, err = github.NewClientWithAccessToken(ghToken)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: Failed to create GitHub client: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, "Error: GitHub App credentials or personal access token must be specified.")
|
||||
os.Exit(1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue