Files
teleport/lib/release/release.go
T
matheusandMichelle Bergquist 78a83b0b64 Add ListReleases and GetLicense endpoints (#19565)
* Add GetReleases and GetLicense methods

Co-authored-by: Michelle Bergquist <11967646+michellescripts@users.noreply.github.com>
2023-01-03 12:52:22 +00:00

191 lines
5.2 KiB
Go

/*
Copyright 2022 Gravitational, Inc.
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 release
import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"net/http"
"os"
"github.com/gravitational/roundtrip"
"github.com/gravitational/trace"
log "github.com/sirupsen/logrus"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/utils"
)
// ClientConfig contains configuration for the release client
type ClientConfig struct {
// TLSConfig is the client TLS configuration
TLSConfig *tls.Config
// ReleaseServerAddr is the address of the release server
ReleaseServerAddr string
}
// CheckAndSetDefaults checks and sets default config values
func (c *ClientConfig) CheckAndSetDefaults() error {
if c.TLSConfig == nil {
return trace.BadParameter("missing TLS configuration")
}
if c.ReleaseServerAddr == "" {
return trace.BadParameter("missing release server address")
}
return nil
}
// Client is a client to make HTTPS requests to the
// release server using the Teleport Enterprise license
// as authentication
type Client struct {
// client is the client used to make calls to the release API
client *roundtrip.Client
}
// NewClient returns a new release client with a client
// to make https requests to the release server
func NewClient(cfg ClientConfig) (*Client, error) {
err := cfg.CheckAndSetDefaults()
if err != nil {
return nil, trace.Wrap(err)
}
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: cfg.TLSConfig,
},
}
client, err := roundtrip.NewClient(fmt.Sprintf("https://%s", cfg.ReleaseServerAddr), "", roundtrip.HTTPClient(httpClient))
if err != nil {
return nil, trace.Wrap(err)
}
return &Client{
client: client,
}, nil
}
// ListReleases calls the release server and returns a list of releases
func (c *Client) ListReleases(ctx context.Context) ([]*types.Release, error) {
if c.client == nil {
return nil, trace.BadParameter("client not initialized")
}
resp, err := c.client.Get(ctx, c.client.Endpoint(types.EnterpriseReleaseEndpoint), nil)
if err != nil {
log.WithError(err).Error("failed to retrieve releases from release server")
return nil, trace.Wrap(err)
}
if resp.Code() == http.StatusUnauthorized {
return nil, trace.AccessDenied("access denied by the release server")
}
if resp.Code() != http.StatusOK {
return nil, trace.Errorf("release server responded with status %d", resp.Code())
}
var releases []Release
err = json.Unmarshal(resp.Bytes(), &releases)
if err != nil {
return nil, trace.Wrap(err)
}
var responseReleases []*types.Release
for _, r := range releases {
var releaseAssets []*types.Asset
for _, a := range r.Assets {
releaseAssets = append(releaseAssets, &types.Asset{
Arch: a.Arch,
Description: a.Description,
Name: a.Name,
OS: a.OS,
SHA256: a.SHA256,
AssetSize: a.Size,
DisplaySize: utils.ByteCount(a.Size),
ReleaseIDs: a.ReleaseIDs,
PublicURL: a.PublicURL,
})
}
responseReleases = append(responseReleases, &types.Release{
NotesMD: r.NotesMD,
Product: r.Product,
ReleaseID: r.ReleaseID,
Status: r.Status,
Version: r.Version,
Assets: releaseAssets,
})
}
return responseReleases, err
}
// GetServerAddr returns the release server address from the environment
// variables or, if not set, the default value
func GetServerAddr() string {
addr := os.Getenv(types.ReleaseServerEnvVar)
if addr == "" {
addr = types.DefaultReleaseServerAddr
}
return addr
}
// Release corresponds to a Teleport Enterprise release
// returned by the release service
type Release struct {
// NotesMD is the notes of the release in markdown
NotesMD string `json:"notesMd"`
// Product is the release product, teleport or teleport-ent
Product string `json:"product"`
// ReleaseId is the ID of the product
ReleaseID string `json:"releaseId"`
// Status is the status of the release
Status string `json:"status"`
// Version is the version of the release
Version string `json:"version"`
// Assets is a list of assets related to the release
Assets []*Asset `json:"assets"`
}
// Asset represents a release asset returned by the
// release service
type Asset struct {
// Arch is the architecture of the asset
Arch string `json:"arch"`
// Description is the description of the asset
Description string `json:"description"`
// Name is the name of the asset
Name string `json:"name"`
// OS is which OS the asset is built for
OS string `json:"os"`
// SHA256 is the sha256 of the asset
SHA256 string `json:"sha256"`
// Size is the size of the release in bytes
Size int64 `json:"size"`
// ReleaseIDs is a list of releases that have the asset included
ReleaseIDs []string `json:"releaseIds"`
// PublicURL is the public URL used to download the asset
PublicURL string `json:"publicUrl"`
}