Skip to content

Commit 433fb7a

Browse files
committed
Merge branch 'main' into 9983-license-prometheus
2 parents c4c434e + 570f963 commit 433fb7a

File tree

10 files changed

+165
-38
lines changed

10 files changed

+165
-38
lines changed

coderd/coderdtest/coderdtest.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func New(t testing.TB, options *Options) *codersdk.Client {
155155
// the provisioner. This is a temporary function while work is done to
156156
// standardize how provisioners are registered with coderd. The option
157157
// to include a provisioner is set to true for convenience.
158-
func NewWithProvisionerCloser(t *testing.T, options *Options) (*codersdk.Client, io.Closer) {
158+
func NewWithProvisionerCloser(t testing.TB, options *Options) (*codersdk.Client, io.Closer) {
159159
if options == nil {
160160
options = &Options{}
161161
}
@@ -532,7 +532,7 @@ func NewProvisionerDaemon(t testing.TB, coderAPI *coderd.API) io.Closer {
532532
return closer
533533
}
534534

535-
func NewExternalProvisionerDaemon(t *testing.T, client *codersdk.Client, org uuid.UUID, tags map[string]string) io.Closer {
535+
func NewExternalProvisionerDaemon(t testing.TB, client *codersdk.Client, org uuid.UUID, tags map[string]string) io.Closer {
536536
echoClient, echoServer := provisionersdk.MemTransportPipe()
537537
ctx, cancelFunc := context.WithCancel(context.Background())
538538
serveDone := make(chan struct{})
@@ -594,15 +594,15 @@ func CreateFirstUser(t testing.TB, client *codersdk.Client) codersdk.CreateFirst
594594
}
595595

596596
// CreateAnotherUser creates and authenticates a new user.
597-
func CreateAnotherUser(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, roles ...string) (*codersdk.Client, codersdk.User) {
597+
func CreateAnotherUser(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, roles ...string) (*codersdk.Client, codersdk.User) {
598598
return createAnotherUserRetry(t, client, organizationID, 5, roles)
599599
}
600600

601-
func CreateAnotherUserMutators(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, roles []string, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
601+
func CreateAnotherUserMutators(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, roles []string, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
602602
return createAnotherUserRetry(t, client, organizationID, 5, roles, mutators...)
603603
}
604604

605-
func createAnotherUserRetry(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, retries int, roles []string, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
605+
func createAnotherUserRetry(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, retries int, roles []string, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
606606
req := codersdk.CreateUserRequest{
607607
Email: namesgenerator.GetRandomName(10) + "@coder.com",
608608
Username: randomUsername(t),
@@ -695,7 +695,7 @@ func createAnotherUserRetry(t *testing.T, client *codersdk.Client, organizationI
695695
// CreateTemplateVersion creates a template import provisioner job
696696
// with the responses provided. It uses the "echo" provisioner for compatibility
697697
// with testing.
698-
func CreateTemplateVersion(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, mutators ...func(*codersdk.CreateTemplateVersionRequest)) codersdk.TemplateVersion {
698+
func CreateTemplateVersion(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, mutators ...func(*codersdk.CreateTemplateVersionRequest)) codersdk.TemplateVersion {
699699
t.Helper()
700700
data, err := echo.Tar(res)
701701
require.NoError(t, err)
@@ -737,7 +737,7 @@ func CreateWorkspaceBuild(
737737

738738
// CreateTemplate creates a template with the "echo" provisioner for
739739
// compatibility with testing. The name assigned is randomly generated.
740-
func CreateTemplate(t *testing.T, client *codersdk.Client, organization uuid.UUID, version uuid.UUID, mutators ...func(*codersdk.CreateTemplateRequest)) codersdk.Template {
740+
func CreateTemplate(t testing.TB, client *codersdk.Client, organization uuid.UUID, version uuid.UUID, mutators ...func(*codersdk.CreateTemplateRequest)) codersdk.Template {
741741
req := codersdk.CreateTemplateRequest{
742742
Name: randomUsername(t),
743743
VersionID: version,
@@ -752,7 +752,7 @@ func CreateTemplate(t *testing.T, client *codersdk.Client, organization uuid.UUI
752752

753753
// UpdateTemplateVersion creates a new template version with the "echo" provisioner
754754
// and associates it with the given templateID.
755-
func UpdateTemplateVersion(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, templateID uuid.UUID) codersdk.TemplateVersion {
755+
func UpdateTemplateVersion(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, templateID uuid.UUID) codersdk.TemplateVersion {
756756
ctx := context.Background()
757757
data, err := echo.Tar(res)
758758
require.NoError(t, err)
@@ -768,15 +768,15 @@ func UpdateTemplateVersion(t *testing.T, client *codersdk.Client, organizationID
768768
return templateVersion
769769
}
770770

771-
func UpdateActiveTemplateVersion(t *testing.T, client *codersdk.Client, templateID, versionID uuid.UUID) {
771+
func UpdateActiveTemplateVersion(t testing.TB, client *codersdk.Client, templateID, versionID uuid.UUID) {
772772
err := client.UpdateActiveTemplateVersion(context.Background(), templateID, codersdk.UpdateActiveTemplateVersion{
773773
ID: versionID,
774774
})
775775
require.NoError(t, err)
776776
}
777777

778778
// AwaitTemplateVersionJobRunning waits for the build to be picked up by a provisioner.
779-
func AwaitTemplateVersionJobRunning(t *testing.T, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
779+
func AwaitTemplateVersionJobRunning(t testing.TB, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
780780
t.Helper()
781781

782782
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
@@ -807,7 +807,7 @@ func AwaitTemplateVersionJobRunning(t *testing.T, client *codersdk.Client, versi
807807

808808
// AwaitTemplateVersionJobCompleted waits for the build to be completed. This may result
809809
// from cancelation, an error, or from completing successfully.
810-
func AwaitTemplateVersionJobCompleted(t *testing.T, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
810+
func AwaitTemplateVersionJobCompleted(t testing.TB, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
811811
t.Helper()
812812

813813
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
@@ -826,7 +826,7 @@ func AwaitTemplateVersionJobCompleted(t *testing.T, client *codersdk.Client, ver
826826
}
827827

828828
// AwaitWorkspaceBuildJobCompleted waits for a workspace provision job to reach completed status.
829-
func AwaitWorkspaceBuildJobCompleted(t *testing.T, client *codersdk.Client, build uuid.UUID) codersdk.WorkspaceBuild {
829+
func AwaitWorkspaceBuildJobCompleted(t testing.TB, client *codersdk.Client, build uuid.UUID) codersdk.WorkspaceBuild {
830830
t.Helper()
831831

832832
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
@@ -897,7 +897,7 @@ func AwaitWorkspaceAgents(t testing.TB, client *codersdk.Client, workspaceID uui
897897
// CreateWorkspace creates a workspace for the user and template provided.
898898
// A random name is generated for it.
899899
// To customize the defaults, pass a mutator func.
900-
func CreateWorkspace(t *testing.T, client *codersdk.Client, organization uuid.UUID, templateID uuid.UUID, mutators ...func(*codersdk.CreateWorkspaceRequest)) codersdk.Workspace {
900+
func CreateWorkspace(t testing.TB, client *codersdk.Client, organization uuid.UUID, templateID uuid.UUID, mutators ...func(*codersdk.CreateWorkspaceRequest)) codersdk.Workspace {
901901
t.Helper()
902902
req := codersdk.CreateWorkspaceRequest{
903903
TemplateID: templateID,
@@ -915,7 +915,7 @@ func CreateWorkspace(t *testing.T, client *codersdk.Client, organization uuid.UU
915915
}
916916

917917
// TransitionWorkspace is a convenience method for transitioning a workspace from one state to another.
918-
func MustTransitionWorkspace(t *testing.T, client *codersdk.Client, workspaceID uuid.UUID, from, to database.WorkspaceTransition) codersdk.Workspace {
918+
func MustTransitionWorkspace(t testing.TB, client *codersdk.Client, workspaceID uuid.UUID, from, to database.WorkspaceTransition) codersdk.Workspace {
919919
t.Helper()
920920
ctx := context.Background()
921921
workspace, err := client.Workspace(ctx, workspaceID)
@@ -939,7 +939,7 @@ func MustTransitionWorkspace(t *testing.T, client *codersdk.Client, workspaceID
939939
}
940940

941941
// MustWorkspace is a convenience method for fetching a workspace that should exist.
942-
func MustWorkspace(t *testing.T, client *codersdk.Client, workspaceID uuid.UUID) codersdk.Workspace {
942+
func MustWorkspace(t testing.TB, client *codersdk.Client, workspaceID uuid.UUID) codersdk.Workspace {
943943
t.Helper()
944944
ctx := context.Background()
945945
ws, err := client.Workspace(ctx, workspaceID)
@@ -952,7 +952,7 @@ func MustWorkspace(t *testing.T, client *codersdk.Client, workspaceID uuid.UUID)
952952

953953
// RequestExternalAuthCallback makes a request with the proper OAuth2 state cookie
954954
// to the external auth callback endpoint.
955-
func RequestExternalAuthCallback(t *testing.T, providerID string, client *codersdk.Client) *http.Response {
955+
func RequestExternalAuthCallback(t testing.TB, providerID string, client *codersdk.Client) *http.Response {
956956
client.HTTPClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
957957
return http.ErrUseLastResponse
958958
}
@@ -980,7 +980,7 @@ func RequestExternalAuthCallback(t *testing.T, providerID string, client *coders
980980
// NewGoogleInstanceIdentity returns a metadata client and ID token validator for faking
981981
// instance authentication for Google Cloud.
982982
// nolint:revive
983-
func NewGoogleInstanceIdentity(t *testing.T, instanceID string, expired bool) (*idtoken.Validator, *metadata.Client) {
983+
func NewGoogleInstanceIdentity(t testing.TB, instanceID string, expired bool) (*idtoken.Validator, *metadata.Client) {
984984
keyID, err := cryptorand.String(12)
985985
require.NoError(t, err)
986986
claims := jwt.MapClaims{
@@ -1042,7 +1042,7 @@ func NewGoogleInstanceIdentity(t *testing.T, instanceID string, expired bool) (*
10421042

10431043
// NewAWSInstanceIdentity returns a metadata client and ID token validator for faking
10441044
// instance authentication for AWS.
1045-
func NewAWSInstanceIdentity(t *testing.T, instanceID string) (awsidentity.Certificates, *http.Client) {
1045+
func NewAWSInstanceIdentity(t testing.TB, instanceID string) (awsidentity.Certificates, *http.Client) {
10461046
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
10471047
require.NoError(t, err)
10481048

@@ -1102,7 +1102,7 @@ func NewAWSInstanceIdentity(t *testing.T, instanceID string) (awsidentity.Certif
11021102

11031103
// NewAzureInstanceIdentity returns a metadata client and ID token validator for faking
11041104
// instance authentication for Azure.
1105-
func NewAzureInstanceIdentity(t *testing.T, instanceID string) (x509.VerifyOptions, *http.Client) {
1105+
func NewAzureInstanceIdentity(t testing.TB, instanceID string) (x509.VerifyOptions, *http.Client) {
11061106
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
11071107
require.NoError(t, err)
11081108

@@ -1182,7 +1182,7 @@ type nopcloser struct{}
11821182
func (nopcloser) Close() error { return nil }
11831183

11841184
// SDKError coerces err into an SDK error.
1185-
func SDKError(t *testing.T, err error) *codersdk.Error {
1185+
func SDKError(t testing.TB, err error) *codersdk.Error {
11861186
var cerr *codersdk.Error
11871187
require.True(t, errors.As(err, &cerr))
11881188
return cerr

coderd/database/dbtestutil/db.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func WillUsePostgres() bool {
3131
type options struct {
3232
fixedTimezone string
3333
dumpOnFailure bool
34+
returnSQLDB func(*sql.DB)
3435
}
3536

3637
type Option func(*options)
@@ -49,6 +50,27 @@ func WithDumpOnFailure() Option {
4950
}
5051
}
5152

53+
func withReturnSQLDB(f func(*sql.DB)) Option {
54+
return func(o *options) {
55+
o.returnSQLDB = f
56+
}
57+
}
58+
59+
func NewDBWithSQLDB(t testing.TB, opts ...Option) (database.Store, pubsub.Pubsub, *sql.DB) {
60+
t.Helper()
61+
62+
if !WillUsePostgres() {
63+
t.Fatal("cannot use NewDBWithSQLDB without PostgreSQL, consider adding `if !dbtestutil.WillUsePostgres() { t.Skip() }` to this test")
64+
}
65+
66+
var sqlDB *sql.DB
67+
opts = append(opts, withReturnSQLDB(func(db *sql.DB) {
68+
sqlDB = db
69+
}))
70+
db, ps := NewDB(t, opts...)
71+
return db, ps, sqlDB
72+
}
73+
5274
func NewDB(t testing.TB, opts ...Option) (database.Store, pubsub.Pubsub) {
5375
t.Helper()
5476

@@ -88,6 +110,9 @@ func NewDB(t testing.TB, opts ...Option) (database.Store, pubsub.Pubsub) {
88110
t.Cleanup(func() {
89111
_ = sqlDB.Close()
90112
})
113+
if o.returnSQLDB != nil {
114+
o.returnSQLDB(sqlDB)
115+
}
91116
if o.dumpOnFailure {
92117
t.Cleanup(func() { DumpOnFailure(t, connectionURL) })
93118
}

coderd/rbac/roles.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
143143

144144
memberRole := Role{
145145
Name: member,
146-
DisplayName: "",
146+
DisplayName: "Member",
147147
Site: Permissions(map[string][]Action{
148148
ResourceRoleAssignment.Type: {ActionRead},
149149
// All users can see the provisioner daemons.

coderd/roles.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ func (api *API) assignableOrgRoles(rw http.ResponseWriter, r *http.Request) {
5858
func assignableRoles(actorRoles rbac.ExpandableRoles, roles []rbac.Role) []codersdk.AssignableRoles {
5959
assignable := make([]codersdk.AssignableRoles, 0)
6060
for _, role := range roles {
61-
if role.DisplayName == "" {
61+
// The member role is implied, and not assignable.
62+
// If there is no display name, then the role is also unassigned.
63+
// This is not the ideal logic, but works for now.
64+
if role.Name == rbac.RoleMember() || (role.DisplayName == "") {
6265
continue
6366
}
6467
assignable = append(assignable, codersdk.AssignableRoles{

docs/admin/external-auth.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,11 @@ provider deployments.
101101
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://github.example.com/oauth/authorize"
102102
CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://github.example.com/oauth/token"
103103
CODER_EXTERNAL_AUTH_0_VALIDATE_URL="https://your-domain.com/oauth/token/info"
104+
CODER_EXTERNAL_AUTH_0_REGEX=github\.company\.org
104105
```
105106

107+
> Note: The `REGEX` variable must be set if using a custom git domain.
108+
106109
### Custom scopes
107110

108111
Optionally, you can request custom scopes:
@@ -114,9 +117,7 @@ CODER_EXTERNAL_AUTH_0_SCOPES="repo:read repo:write write:gpg_key"
114117
### Multiple External Providers (enterprise)
115118

116119
Multiple providers are an Enterprise feature. [Learn more](../enterprise.md).
117-
118-
A custom regex can be used to match a specific repository or organization to
119-
limit auth scope. Here's a sample config:
120+
Below is an example configuration with multiple providers.
120121

121122
```env
122123
# Provider 1) github.com

docs/images/icons-gallery.png

2.83 MB
Loading

docs/manifest.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@
207207
"description": "Audit commands in workspaces with exectrace",
208208
"path": "./templates/process-logging.md",
209209
"state": "enterprise"
210+
},
211+
{
212+
"title": "Icons",
213+
"description": "Coder includes icons for popular cloud providers and programming languages for you to use",
214+
"path": "./templates/icons.md"
210215
}
211216
]
212217
},

docs/templates/icons.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Icons
2+
3+
---
4+
5+
Coder uses icons in several places, including ones that can be configured
6+
throughout the app, or specified in your Terraform. They're specified by a URL,
7+
which can be to an image hosted on a CDN of your own, or one of the icons that
8+
come bundled with your Coder deployment.
9+
10+
- **Template Icons**:
11+
12+
- Make templates and workspaces visually recognizable with a relevant or
13+
memorable icon
14+
15+
- [**Terraform**](https://registry.terraform.io/providers/coder/coder/latest/docs):
16+
17+
- [`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#icon)
18+
- [`coder_parameter`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter#icon)
19+
and
20+
[`option`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter#nested-schema-for-option)
21+
blocks
22+
- [`coder_script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script#icon)
23+
24+
These can all be configured to use an icon by setting the `icon` field.
25+
26+
```terraform
27+
data "coder_parameter" "my_parameter" {
28+
icon = "/icon/coder.svg"
29+
30+
option {
31+
icon = "/emojis/1f3f3-fe0f-200d-26a7-fe0f.png"
32+
}
33+
}
34+
```
35+
36+
- [**Authentication Providers**](https://coder.com/docs/v2/latest/admin/external-auth):
37+
38+
- Use icons for external authentication providers to make them recognizable
39+
40+
## Bundled icons
41+
42+
Coder is distributed with a bundle of icons for popular cloud providers and
43+
programming languages. You can see all of the icons (or suggest new ones) in our
44+
repository on
45+
[GitHub](https://github.com/coder/coder/tree/main/site/static/icon).
46+
47+
You can also view the entire list, with search and previews, by navigating to
48+
/icons on your Coder deployment. E.g. [https://coder.example.com/icons](#). This
49+
can be particularly useful in airgapped deployments.
50+
51+
![The icon gallery](../images/icons-gallery.png)
52+
53+
## External icons
54+
55+
You can use any image served over HTTPS as an icon, by specifying the full URL
56+
of the image. We recommend that you use a CDN that you control, but it can be
57+
served from any source that you trust.
58+
59+
You can also embed an image by using data: URLs.
60+
61+
- Only the https: and data: protocols are supported in icon URLs (not http:)
62+
63+
- Be careful when using images hosted by someone else; they might disappear or
64+
change!
65+
66+
- Be careful when using data: URLs. They can get rather large, and can
67+
negatively impact loading times for pages and queries they appear in. Only use
68+
them for very small icons that compress well.

0 commit comments

Comments
 (0)