garm/util/github/scalesets/token.go
Gabriel Adrian Samfira 40e6581a75 Rename GitHub specific types
This change renames a lot of variables, types and functions to be more
generic. The goal is to allow GARM to add more forges in the future.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-12 21:47:13 +00:00

105 lines
3.1 KiB
Go

// Copyright 2024 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package scalesets
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"github.com/cloudbase/garm/params"
)
func (s *ScaleSetClient) getActionServiceInfo(ctx context.Context) (params.ActionsServiceAdminInfoResponse, error) {
regPath := "/actions/runner-registration"
baseURL := s.ghCli.GithubBaseURL()
url, err := baseURL.Parse(regPath)
if err != nil {
return params.ActionsServiceAdminInfoResponse{}, fmt.Errorf("failed to parse url: %w", err)
}
entity := s.ghCli.GetEntity()
body := params.ActionsServiceAdminInfoRequest{
URL: entity.ForgeURL(),
RunnerEvent: "register",
}
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
if err := enc.Encode(body); err != nil {
return params.ActionsServiceAdminInfoResponse{}, err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url.String(), buf)
if err != nil {
return params.ActionsServiceAdminInfoResponse{}, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("RemoteAuth %s", *s.runnerRegistrationToken.Token))
resp, err := s.Do(req)
if err != nil {
return params.ActionsServiceAdminInfoResponse{}, fmt.Errorf("failed to get actions service admin info: %w", err)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return params.ActionsServiceAdminInfoResponse{}, fmt.Errorf("failed to read response body: %w", err)
}
data = bytes.TrimPrefix(data, []byte("\xef\xbb\xbf"))
var info params.ActionsServiceAdminInfoResponse
if err := json.Unmarshal(data, &info); err != nil {
return params.ActionsServiceAdminInfoResponse{}, fmt.Errorf("failed to decode response: %w", err)
}
return info, nil
}
func (s *ScaleSetClient) ensureAdminInfo(ctx context.Context) error {
s.mux.Lock()
defer s.mux.Unlock()
var expiresAt time.Time
if s.runnerRegistrationToken != nil {
expiresAt = s.runnerRegistrationToken.GetExpiresAt().Time
}
now := time.Now().UTC().Add(2 * time.Minute)
if now.After(expiresAt) || s.runnerRegistrationToken == nil {
token, _, err := s.ghCli.CreateEntityRegistrationToken(ctx)
if err != nil {
return fmt.Errorf("failed to fetch runner registration token: %w", err)
}
s.runnerRegistrationToken = token
}
if s.actionsServiceInfo == nil || s.actionsServiceInfo.ExpiresIn(2*time.Minute) {
info, err := s.getActionServiceInfo(ctx)
if err != nil {
return fmt.Errorf("failed to get action service info: %w", err)
}
s.actionsServiceInfo = &info
}
return nil
}