Documentation
¶
Overview ¶
Package rpp is a client for the Deckhouse registry-packages-proxy (RPP) CLI routes:
- GET /v1/images/<image>/tags - list available versions
- GET /v1/images/<image>/images/<version> - download a version's image
- GET /v1/images/<image>/manifests/<ref> - fetch an image's raw manifest
It lets deckhouse-cli list available versions of itself and its plugins and download their images. All traffic goes to the in-cluster proxy and is authenticated with the caller's kubeconfig identity; no separate registry credentials are needed, because the proxy fetches from the backing registry on the CLI's behalf.
Pulls carry a ?platform=<os>-<arch> query (from the running binary's GOOS/GOARCH) so the proxy selects the matching image from a multi-platform index. A proxy too old to honor it falls back to its default platform.
Index ¶
- Constants
- Variables
- func ExtractFileToPath(r io.Reader, entryName, destination string, mode os.FileMode, maxBytes int64) error
- func ReadFile(r io.Reader, entryName string, maxBytes int64) ([]byte, bool, error)
- type Client
- func New(baseURL string, restConfig *rest.Config, logger *dkplog.Logger, opts ...Option) (*Client, error)
- func NewClusterClient(ctx context.Context, kube kubernetes.Interface, restConfig *rest.Config, ...) (*Client, error)
- func NewWithHTTPClient(baseURL string, httpClient *http.Client, logger *dkplog.Logger) *Client
- type ImageRef
- type Option
Constants ¶
const ( // ExecutableMode is the mode forced on extracted binaries so they are always // runnable regardless of the mode recorded in the image. ExecutableMode os.FileMode = 0o755 // DefaultBinaryByteLimit caps an extracted binary. 512 MiB is far above the d8 // binary (~130 MiB) and any plugin; shared so callers do not redefine it. DefaultBinaryByteLimit int64 = 512 << 20 )
Variables ¶
var ( // ErrInvalidImage means the requested image or tag is malformed or outside // the proxy allow-list (e.g. a plugin name containing a slash). ErrInvalidImage = errors.New("invalid image reference") // ErrInvalidEndpoint means the proxy endpoint URL is empty or not an https URL with a host. ErrInvalidEndpoint = errors.New("invalid proxy endpoint") // ErrEndpointDiscovery means the proxy endpoint could not be discovered through // the Kubernetes API (the kubeconfig 'server:'). Causes: // - the API was unreachable // - its certificate was invalid // - the identity was rejected // - no usable proxy was found // This is the kube-API leg, not the proxy itself - bypass it with an explicit // endpoint (--rpp-endpoint / D8_RPP_ENDPOINT). ErrEndpointDiscovery = errors.New("registry-packages-proxy endpoint discovery failed") // ErrInvalidCA means the supplied CA bundle contained no usable certificates. ErrInvalidCA = errors.New("invalid CA bundle") // ErrUnsupportedConfig means the requested client configuration is // contradictory or unsupported (e.g. insecure TLS together with a CA bundle, // or a rest.Config carrying a custom transport that would bypass CA verification). ErrUnsupportedConfig = errors.New("unsupported client configuration") // ErrNotFound means the proxy has no such image or tag (HTTP 404). ErrNotFound = errors.New("image or tag not found") // were missing, invalid or expired (HTTP 401). ErrUnauthorized = errors.New("unauthorized") // ErrForbidden means the caller is authenticated but not allowed to download. // In practice the cli-download ClusterRole is not bound to the subject (HTTP 403). ErrForbidden = errors.New("forbidden") // ErrUpstream means the proxy failed while talking to the backing registry // (HTTP 5xx). ErrUpstream = errors.New("registry proxy upstream error") // ErrFileNotFound means a requested entry was absent from the downloaded image // archive. ErrFileNotFound = errors.New("file not found in image") )
Sentinel errors let callers branch on the outcome via errors.Is instead of inspecting HTTP status codes themselves.
Functions ¶
func ExtractFileToPath ¶
func ExtractFileToPath(r io.Reader, entryName, destination string, mode os.FileMode, maxBytes int64) error
ExtractFileToPath finds the entry whose base name is entryName and writes it to destination with mode. The mode is forced (the archive's recorded mode is ignored) because these artifacts are executables that must be runnable. The copy is capped at maxBytes to guard against a decompression bomb. Returns ErrFileNotFound if no such entry exists.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to the registry-packages-proxy CLI routes, authenticating with the caller's kubeconfig identity.
func New ¶
func New(baseURL string, restConfig *rest.Config, logger *dkplog.Logger, opts ...Option) (*Client, error)
New builds a Client whose requests carry the kubeconfig identity from restConfig. baseURL is the proxy endpoint root, for example "https://10.0.0.1:4219".
func NewClusterClient ¶
func NewClusterClient( ctx context.Context, kube kubernetes.Interface, restConfig *rest.Config, logger *dkplog.Logger, endpoint, caFile string, insecure bool, ) (*Client, error)
NewClusterClient builds a Client for the proxy reachable from the given cluster connection. The endpoint is used as-is when set, otherwise discovered (Ingress preferred, pod IPs as fallback; see chooseDiscoveredEndpoint). caFile / insecure select TLS verification (mutually exclusive; New reports the contradiction).
func NewWithHTTPClient ¶
NewWithHTTPClient builds a Client around a pre-built HTTP client. It is used in tests and by callers that construct the transport themselves.
func (*Client) GetManifest ¶
GetManifest fetches the raw image manifest for a version without pulling layers. The plugin contract lives as a base64-JSON annotation inside it; the caller reads it from the returned bytes. The manifest is platform-independent (it is the index for a multi-platform image), so no platform is sent.
func (*Client) PullImage ¶
func (c *Client) PullImage(ctx context.Context, ref ImageRef, version string) (io.ReadCloser, error)
PullImage downloads the image tag as a gzipped tar stream (the binary, and the contract when present, are files inside it). The caller owns the returned reader and must close it.
No integrity check: the proxy exposes only a manifest digest, not a hash of the gzip-tar body. Trust rests on the TLS-authenticated proxy channel. The caller may want to cap the read with an io.LimitReader.
type ImageRef ¶
type ImageRef struct {
// contains filtered or unexported fields
}
ImageRef identifies an image the proxy is allowed to serve over /v1/images: either the deckhouse-cli binary or a single plugin. Construct it through CLIImage or PluginImage so the value always stays within the allow-list.
func PluginImage ¶
PluginImage refers to a plugin image (deckhouse-cli/plugins/<name>). name must be a single OCI path component, matching the proxy allow-list.
type Option ¶
type Option func(*options)
Option configures the proxy client transport.
func WithCAData ¶
WithCAData is WithCAFile with the PEM bytes supplied directly. Mutually exclusive with WithCAFile and WithInsecureSkipTLSVerify.
func WithCAFile ¶
WithCAFile verifies the proxy TLS certificate against the CA bundle in the given PEM file, in addition to the system roots. Mutually exclusive with WithCAData and WithInsecureSkipTLSVerify.
func WithInsecureSkipTLSVerify ¶
func WithInsecureSkipTLSVerify() Option
WithInsecureSkipTLSVerify disables proxy TLS verification. Intended for debugging only. Mutually exclusive with WithCAFile and WithCAData.