...

Source file src/edge-infra.dev/pkg/f8n/devinfra/github-client/config.go

Documentation: edge-infra.dev/pkg/f8n/devinfra/github-client

     1  package githubclient
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  	"regexp"
     8  	"time"
     9  
    10  	"go.uber.org/multierr"
    11  	"golang.org/x/oauth2"
    12  
    13  	"github.com/bradleyfalzon/ghinstallation/v2"
    14  )
    15  
    16  type Config struct {
    17  	// HTTPS Github Repository URL
    18  	Repository string
    19  
    20  	// For Github App authentication
    21  	PrivateKey     []byte // PEM encoded private key. If empty, use oauth.
    22  	AppID          int64
    23  	InstallationID int64 // Optional. See documentation
    24  
    25  	AccessToken string // optional personal access token
    26  }
    27  
    28  var (
    29  	errEmptyRepositoryError   = fmt.Errorf("Repository must be provided")
    30  	errInvalidRepositoryError = fmt.Errorf("Invalid repository URL")
    31  	errEmptyKeyError          = fmt.Errorf("PrivateKey or AccessToken must be set")
    32  	errEmptyAppIDError        = fmt.Errorf("AppID must be greater than zero")
    33  )
    34  
    35  // Ensure the repository will work with the GithubOwner and GithubRepo methods
    36  var reValidRepository = regexp.MustCompile("^https://github.com/[^/]+/[^/]+([.]git)?$")
    37  
    38  var (
    39  	// used to remove everything from the Repository url, except the owner.
    40  	reGithubOwner = regexp.MustCompile(`^https://github.com/|/[^/]*$`)
    41  	// used to remove everything from the Repository url, except the repo name.
    42  	reGithubRepo = regexp.MustCompile(`^.*/|[.]git$`)
    43  )
    44  
    45  // Owner uses the Repository url to find the owner.
    46  func (c *Config) Owner() string {
    47  	return reGithubOwner.ReplaceAllString(c.Repository, "")
    48  }
    49  
    50  // Repo uses the Repository url to find the repository name.
    51  func (c *Config) Repo() string {
    52  	return reGithubRepo.ReplaceAllString(c.Repository, "")
    53  }
    54  
    55  // Validate returns an error if the configuration is missing required fields.
    56  func (c *Config) Validate() error {
    57  	var errs []error
    58  	if c.AccessToken != "" { // if the access token is set dont worry about the rest
    59  		return nil
    60  	}
    61  	if c.PrivateKey == nil && c.AccessToken == "" {
    62  		errs = append(errs, errEmptyKeyError)
    63  	}
    64  	if c.AppID <= 0 {
    65  		errs = append(errs, errEmptyAppIDError)
    66  	}
    67  	if c.Repository == "" {
    68  		errs = append(errs, errEmptyRepositoryError)
    69  	}
    70  	if !reValidRepository.MatchString(c.Repository) {
    71  		errs = append(errs, errInvalidRepositoryError)
    72  	}
    73  	return multierr.Combine(errs...)
    74  }
    75  
    76  func (c *Config) HTTPClient() (*http.Client, error) {
    77  	if err := c.Validate(); err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	if c.AccessToken != "" {
    82  		return oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(
    83  			&oauth2.Token{AccessToken: c.AccessToken},
    84  		)), nil
    85  	}
    86  
    87  	transport := http.DefaultTransport
    88  	const timeout = 5 * time.Minute
    89  
    90  	if c.InstallationID == 0 {
    91  		// Create an AppsService API compatible http client.
    92  		tr, err := ghinstallation.NewAppsTransport(transport, c.AppID, c.PrivateKey)
    93  		if err != nil {
    94  			return nil, err
    95  		}
    96  		return &http.Client{
    97  			Transport: tr,
    98  			Timeout:   timeout,
    99  		}, nil
   100  	}
   101  	tr, err := ghinstallation.New(transport, c.AppID, c.InstallationID, c.PrivateKey)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	return &http.Client{
   106  		Transport: tr,
   107  		Timeout:   timeout,
   108  	}, nil
   109  }
   110  

View as plain text