mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
149 lines
5.3 KiB
Go
149 lines
5.3 KiB
Go
package codersdk
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/google/uuid"
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
const (
|
|
WorkspaceAgentPortShareLevelOwner WorkspaceAgentPortShareLevel = "owner"
|
|
WorkspaceAgentPortShareLevelAuthenticated WorkspaceAgentPortShareLevel = "authenticated"
|
|
WorkspaceAgentPortShareLevelOrganization WorkspaceAgentPortShareLevel = "organization"
|
|
WorkspaceAgentPortShareLevelPublic WorkspaceAgentPortShareLevel = "public"
|
|
|
|
WorkspaceAgentPortShareProtocolHTTP WorkspaceAgentPortShareProtocol = "http"
|
|
WorkspaceAgentPortShareProtocolHTTPS WorkspaceAgentPortShareProtocol = "https"
|
|
)
|
|
|
|
type (
|
|
WorkspaceAgentPortShareLevel string
|
|
WorkspaceAgentPortShareProtocol string
|
|
UpsertWorkspaceAgentPortShareRequest struct {
|
|
AgentName string `json:"agent_name"`
|
|
Port int32 `json:"port"`
|
|
ShareLevel WorkspaceAgentPortShareLevel `json:"share_level" enums:"owner,authenticated,organization,public"`
|
|
Protocol WorkspaceAgentPortShareProtocol `json:"protocol" enums:"http,https"`
|
|
}
|
|
WorkspaceAgentPortShares struct {
|
|
Shares []WorkspaceAgentPortShare `json:"shares"`
|
|
}
|
|
WorkspaceAgentPortShare struct {
|
|
WorkspaceID uuid.UUID `json:"workspace_id" format:"uuid"`
|
|
AgentName string `json:"agent_name"`
|
|
Port int32 `json:"port"`
|
|
ShareLevel WorkspaceAgentPortShareLevel `json:"share_level" enums:"owner,authenticated,organization,public"`
|
|
Protocol WorkspaceAgentPortShareProtocol `json:"protocol" enums:"http,https"`
|
|
}
|
|
DeleteWorkspaceAgentPortShareRequest struct {
|
|
AgentName string `json:"agent_name"`
|
|
Port int32 `json:"port"`
|
|
}
|
|
)
|
|
|
|
func (l WorkspaceAgentPortShareLevel) ValidMaxLevel() bool {
|
|
return l == WorkspaceAgentPortShareLevelOwner ||
|
|
l == WorkspaceAgentPortShareLevelAuthenticated ||
|
|
l == WorkspaceAgentPortShareLevelOrganization ||
|
|
l == WorkspaceAgentPortShareLevelPublic
|
|
}
|
|
|
|
func (l WorkspaceAgentPortShareLevel) ValidPortShareLevel() bool {
|
|
return l == WorkspaceAgentPortShareLevelAuthenticated ||
|
|
l == WorkspaceAgentPortShareLevelOrganization ||
|
|
l == WorkspaceAgentPortShareLevelPublic
|
|
}
|
|
|
|
// IsCompatibleWithMaxLevel determines whether the sharing level is valid under
|
|
// the specified maxLevel. The values are fully ordered, from "highest" to
|
|
// "lowest" as
|
|
// 1. Public
|
|
// 2. Authenticated
|
|
// 3. Organization
|
|
// 4. Owner
|
|
// Returns an error if either level is invalid.
|
|
func (l WorkspaceAgentPortShareLevel) IsCompatibleWithMaxLevel(maxLevel WorkspaceAgentPortShareLevel) error {
|
|
// Owner is always allowed.
|
|
if l == WorkspaceAgentPortShareLevelOwner {
|
|
return nil
|
|
}
|
|
// If public is allowed, anything is allowed.
|
|
if maxLevel == WorkspaceAgentPortShareLevelPublic {
|
|
return nil
|
|
}
|
|
// Public is not allowed.
|
|
if l == WorkspaceAgentPortShareLevelPublic {
|
|
return xerrors.Errorf("%q sharing level is not allowed under max level %q", l, maxLevel)
|
|
}
|
|
// If authenticated is allowed, public has already been filtered out so
|
|
// anything is allowed.
|
|
if maxLevel == WorkspaceAgentPortShareLevelAuthenticated {
|
|
return nil
|
|
}
|
|
// Authenticated is not allowed.
|
|
if l == WorkspaceAgentPortShareLevelAuthenticated {
|
|
return xerrors.Errorf("%q sharing level is not allowed under max level %q", l, maxLevel)
|
|
}
|
|
// If organization is allowed, public and authenticated have already been
|
|
// filtered out so anything is allowed.
|
|
if maxLevel == WorkspaceAgentPortShareLevelOrganization {
|
|
return nil
|
|
}
|
|
// Organization is not allowed.
|
|
if l == WorkspaceAgentPortShareLevelOrganization {
|
|
return xerrors.Errorf("%q sharing level is not allowed under max level %q", l, maxLevel)
|
|
}
|
|
|
|
// An invalid value was provided.
|
|
return xerrors.New("port sharing level is invalid.")
|
|
}
|
|
|
|
func (p WorkspaceAgentPortShareProtocol) ValidPortProtocol() bool {
|
|
return p == WorkspaceAgentPortShareProtocolHTTP ||
|
|
p == WorkspaceAgentPortShareProtocolHTTPS
|
|
}
|
|
|
|
func (c *Client) GetWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) (WorkspaceAgentPortShares, error) {
|
|
var shares WorkspaceAgentPortShares
|
|
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/port-share", workspaceID), nil)
|
|
if err != nil {
|
|
return shares, err
|
|
}
|
|
defer res.Body.Close()
|
|
if res.StatusCode != http.StatusOK {
|
|
return shares, ReadBodyAsError(res)
|
|
}
|
|
|
|
return shares, json.NewDecoder(res.Body).Decode(&shares)
|
|
}
|
|
|
|
func (c *Client) UpsertWorkspaceAgentPortShare(ctx context.Context, workspaceID uuid.UUID, req UpsertWorkspaceAgentPortShareRequest) (WorkspaceAgentPortShare, error) {
|
|
var share WorkspaceAgentPortShare
|
|
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/workspaces/%s/port-share", workspaceID), req)
|
|
if err != nil {
|
|
return share, err
|
|
}
|
|
defer res.Body.Close()
|
|
if res.StatusCode != http.StatusOK {
|
|
return share, ReadBodyAsError(res)
|
|
}
|
|
|
|
return share, json.NewDecoder(res.Body).Decode(&share)
|
|
}
|
|
|
|
func (c *Client) DeleteWorkspaceAgentPortShare(ctx context.Context, workspaceID uuid.UUID, req DeleteWorkspaceAgentPortShareRequest) error {
|
|
res, err := c.Request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/workspaces/%s/port-share", workspaceID), req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer res.Body.Close()
|
|
if res.StatusCode != http.StatusOK {
|
|
return ReadBodyAsError(res)
|
|
}
|
|
return nil
|
|
}
|