Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: handle default org handling for provisioner daemons
  • Loading branch information
Emyrk committed Feb 27, 2024
commit df54d89d562b4365d084af6fa358671fe453de08
24 changes: 19 additions & 5 deletions coderd/httpmw/organizationparam.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,26 @@ func ExtractOrganizationParam(db database.Store) func(http.Handler) http.Handler

var organization database.Organization
var err error
// Try by name or uuid.
id, err := uuid.Parse(arg)
if err == nil {
organization, err = db.GetOrganizationByID(ctx, id)

// If the name is exactly "default", then we fetch the default
// organization. This is a special case to make it easier
// for single org deployments.
//
// arg == uuid.Nil.String() should be a temporary workaround for
// legacy provisioners that don't provide an organization ID.
// This prevents a breaking change.
// TODO: This change was added March 2024, this should be removed
// some number of months after that date.
if arg == codersdk.DefaultOrganization || arg == uuid.Nil.String() {
organization, err = db.GetDefaultOrganization(ctx)
} else {
organization, err = db.GetOrganizationByName(ctx, arg)
// Try by name or uuid.
id, err := uuid.Parse(arg)
if err == nil {
organization, err = db.GetOrganizationByID(ctx, id)
} else {
organization, err = db.GetOrganizationByName(ctx, arg)
}
}
if httpapi.Is404Error(err) {
httpapi.ResourceNotFound(rw)
Expand Down
7 changes: 7 additions & 0 deletions coderd/organizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ func (api *API) postOrganizations(rw http.ResponseWriter, r *http.Request) {
return
}

if req.Name == codersdk.DefaultOrganization {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: fmt.Sprintf("Organization name %q is reserved.", codersdk.DefaultOrganization),
})
return
}

_, err := api.Database.GetOrganizationByName(ctx, req.Name)
if err == nil {
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{
Expand Down
3 changes: 3 additions & 0 deletions codersdk/organizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import (
"golang.org/x/xerrors"
)

// DefaultOrganization is used as a replacement for the default organization.
var DefaultOrganization = "default"

type ProvisionerStorageMethod string

const (
Expand Down
11 changes: 8 additions & 3 deletions codersdk/provisionerdaemons.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ type ServeProvisionerDaemonRequest struct {
ID uuid.UUID `json:"id" format:"uuid"`
// Name is the human-readable unique identifier for the daemon.
Name string `json:"name" example:"my-cool-provisioner-daemon"`
// Organization is the organization for the URL. At present provisioner daemons ARE NOT scoped to organizations
// and so the organization ID is optional.
// Organization is the organization for the URL. If no orgID is provided,
// then it is assumed to use the default organization.
Organization uuid.UUID `json:"organization" format:"uuid"`
// Provisioners is a list of provisioner types hosted by the provisioner daemon
Provisioners []ProvisionerType `json:"provisioners"`
Expand All @@ -194,7 +194,12 @@ type ServeProvisionerDaemonRequest struct {
// implementation. The context is during dial, not during the lifetime of the
// client. Client should be closed after use.
func (c *Client) ServeProvisionerDaemon(ctx context.Context, req ServeProvisionerDaemonRequest) (proto.DRPCProvisionerDaemonClient, error) {
serverURL, err := c.URL.Parse(fmt.Sprintf("/api/v2/organizations/%s/provisionerdaemons/serve", req.Organization))
orgParam := req.Organization.String()
if req.Organization == uuid.Nil {
orgParam = DefaultOrganization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why we don't like uuid.Nil meaning the default on the API, but are fine with it on the SDK.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went back and forth on this. I think we are the only users of our sdk atm, but if I was to require the OrgID argument in the sdk to be set now, that would be a breaking change for the sdk.

I've been trying to maintain that single org deployments do not have to make any changes, and they continue to work as they do today.

On the sdk side, this is an omission of a field being set.

On the API, the nil uuid could be an explicit value being set, rather than an omission.

}

serverURL, err := c.URL.Parse(fmt.Sprintf("/api/v2/organizations/%s/provisionerdaemons/serve", orgParam))
if err != nil {
return nil, xerrors.Errorf("parse url: %w", err)
}
Expand Down