Skip to content

Commit 9b5d632

Browse files
authored
Merge branch 'coder:main' into rich-params-examples
2 parents d0ab600 + 8cf292f commit 9b5d632

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1538
-836
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141

4242
# Check for any typos!
4343
- name: Check for typos
44-
uses: crate-ci/typos@v1.13.9
44+
uses: crate-ci/typos@v1.13.14
4545
with:
4646
config: .github/workflows/typos.toml
4747
- name: Fix the typos

.github/workflows/contrib.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
steps:
3434
- name: cla
3535
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
36-
uses: contributor-assistant/github-action@v2.2.1
36+
uses: contributor-assistant/github-action@v2.3.0
3737
env:
3838
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3939
# the below token should have repo scope and must be manually added by you in the repository's secret

.github/workflows/docker-base.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,38 @@ jobs:
5353
project: wl5hnrrkns
5454
context: base-build-context
5555
file: scripts/Dockerfile.base
56+
platforms: linux/amd64,linux/arm64,linux/arm/v7
5657
pull: true
5758
no-cache: true
5859
push: true
5960
tags: |
6061
ghcr.io/coder/coder-base:latest
62+
63+
- name: Verify that images are pushed properly
64+
run: |
65+
# retry 10 times with a 5 second delay as the images may not be
66+
# available immediately
67+
for i in {1..10}; do
68+
rc=0
69+
raw_manifests=$(docker buildx imagetools inspect --raw ghcr.io/coder/coder-base:latest) || rc=$?
70+
if [[ "$rc" -eq 0 ]]; then
71+
break
72+
fi
73+
if [[ "$i" -eq 10 ]]; then
74+
echo "Failed to pull manifests after 10 retries"
75+
exit 1
76+
fi
77+
echo "Failed to pull manifests, retrying in 5 seconds"
78+
sleep 5
79+
done
80+
81+
manifests=$(
82+
echo "$raw_manifests" | \
83+
jq -r '.manifests[].platform | .os + "/" + .architecture + (if .variant then "/" + .variant else "" end)'
84+
)
85+
86+
# Verify all 3 platforms are present.
87+
set -euxo pipefail
88+
echo "$manifests" | grep -q linux/amd64
89+
echo "$manifests" | grep -q linux/arm64
90+
echo "$manifests" | grep -q linux/arm/v7

.github/workflows/release.yaml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,42 @@ jobs:
188188
project: wl5hnrrkns
189189
context: base-build-context
190190
file: scripts/Dockerfile.base
191+
platforms: linux/amd64,linux/arm64,linux/arm/v7
191192
pull: true
192193
no-cache: true
193194
push: true
194195
tags: |
195196
${{ steps.image-base-tag.outputs.tag }}
196197
198+
- name: Verify that images are pushed properly
199+
run: |
200+
# retry 10 times with a 5 second delay as the images may not be
201+
# available immediately
202+
for i in {1..10}; do
203+
rc=0
204+
raw_manifests=$(docker buildx imagetools inspect --raw "${{ steps.image-base-tag.outputs.tag }}") || rc=$?
205+
if [[ "$rc" -eq 0 ]]; then
206+
break
207+
fi
208+
if [[ "$i" -eq 10 ]]; then
209+
echo "Failed to pull manifests after 10 retries"
210+
exit 1
211+
fi
212+
echo "Failed to pull manifests, retrying in 5 seconds"
213+
sleep 5
214+
done
215+
216+
manifests=$(
217+
echo "$raw_manifests" | \
218+
jq -r '.manifests[].platform | .os + "/" + .architecture + (if .variant then "/" + .variant else "" end)'
219+
)
220+
221+
# Verify all 3 platforms are present.
222+
set -euxo pipefail
223+
echo "$manifests" | grep -q linux/amd64
224+
echo "$manifests" | grep -q linux/arm64
225+
echo "$manifests" | grep -q linux/arm/v7
226+
197227
- name: Build Linux Docker images
198228
run: |
199229
set -euxo pipefail
@@ -275,7 +305,7 @@ jobs:
275305
276306
- name: Upload artifacts to actions (if dry-run)
277307
if: ${{ inputs.dry_run }}
278-
uses: actions/upload-artifact@v2
308+
uses: actions/upload-artifact@v3
279309
with:
280310
name: release-artifacts
281311
path: |

.github/workflows/security.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ jobs:
116116
echo "image=$(cat "$image_job")" >> $GITHUB_OUTPUT
117117
118118
- name: Run Trivy vulnerability scanner
119-
uses: aquasecurity/trivy-action@9ab158e8597f3b310480b9a69402b419bc03dbd5
119+
uses: aquasecurity/trivy-action@8bd2f9fbda2109502356ff8a6a89da55b1ead252
120120
with:
121121
image-ref: ${{ steps.build.outputs.image }}
122122
format: sarif
@@ -130,7 +130,7 @@ jobs:
130130
category: "Trivy"
131131

132132
- name: Upload Trivy scan results as an artifact
133-
uses: actions/upload-artifact@v2
133+
uses: actions/upload-artifact@v3
134134
with:
135135
name: trivy
136136
path: trivy-results.sarif

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"agentsdk",
55
"apps",
66
"ASKPASS",
7+
"authcheck",
78
"autostop",
89
"awsidentity",
910
"bodyclose",

cli/tokens.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"strings"
77
"time"
88

9-
"github.com/google/uuid"
109
"github.com/spf13/cobra"
1110
"golang.org/x/exp/slices"
1211
"golang.org/x/xerrors"
@@ -99,16 +98,14 @@ type tokenListRow struct {
9998
Owner string `json:"-" table:"owner"`
10099
}
101100

102-
func tokenListRowFromToken(token codersdk.APIKey, usersByID map[uuid.UUID]codersdk.User) tokenListRow {
103-
user := usersByID[token.UserID]
104-
101+
func tokenListRowFromToken(token codersdk.APIKeyWithOwner) tokenListRow {
105102
return tokenListRow{
106-
APIKey: token,
103+
APIKey: token.APIKey,
107104
ID: token.ID,
108105
LastUsed: token.LastUsed,
109106
ExpiresAt: token.ExpiresAt,
110107
CreatedAt: token.CreatedAt,
111-
Owner: user.Username,
108+
Owner: token.Username,
112109
}
113110
}
114111

@@ -150,20 +147,10 @@ func listTokens() *cobra.Command {
150147
))
151148
}
152149

153-
userRes, err := client.Users(cmd.Context(), codersdk.UsersRequest{})
154-
if err != nil {
155-
return err
156-
}
157-
158-
usersByID := map[uuid.UUID]codersdk.User{}
159-
for _, user := range userRes.Users {
160-
usersByID[user.ID] = user
161-
}
162-
163150
displayTokens = make([]tokenListRow, len(tokens))
164151

165152
for i, token := range tokens {
166-
displayTokens[i] = tokenListRowFromToken(token, usersByID)
153+
displayTokens[i] = tokenListRowFromToken(token)
167154
}
168155

169156
out, err := formatter.Format(cmd.Context(), displayTokens)

coderd/apikey.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,30 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) {
216216
return
217217
}
218218

219-
var apiKeys []codersdk.APIKey
219+
var userIds []uuid.UUID
220220
for _, key := range keys {
221-
apiKeys = append(apiKeys, convertAPIKey(key))
221+
userIds = append(userIds, key.UserID)
222+
}
223+
224+
users, _ := api.Database.GetUsersByIDs(ctx, userIds)
225+
usersByID := map[uuid.UUID]database.User{}
226+
for _, user := range users {
227+
usersByID[user.ID] = user
228+
}
229+
230+
var apiKeys []codersdk.APIKeyWithOwner
231+
for _, key := range keys {
232+
if user, exists := usersByID[key.UserID]; exists {
233+
apiKeys = append(apiKeys, codersdk.APIKeyWithOwner{
234+
APIKey: convertAPIKey(key),
235+
Username: user.Username,
236+
})
237+
} else {
238+
apiKeys = append(apiKeys, codersdk.APIKeyWithOwner{
239+
APIKey: convertAPIKey(key),
240+
Username: "",
241+
})
242+
}
222243
}
223244

224245
httpapi.Write(ctx, rw, http.StatusOK, apiKeys)

coderd/audit.go

Lines changed: 2 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"net"
99
"net/http"
1010
"net/netip"
11-
"net/url"
12-
"strings"
1311
"time"
1412

1513
"github.com/google/uuid"
@@ -22,6 +20,7 @@ import (
2220
"github.com/coder/coder/coderd/httpapi"
2321
"github.com/coder/coder/coderd/httpmw"
2422
"github.com/coder/coder/coderd/rbac"
23+
"github.com/coder/coder/coderd/searchquery"
2524
"github.com/coder/coder/codersdk"
2625
)
2726

@@ -49,7 +48,7 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) {
4948
}
5049

5150
queryStr := r.URL.Query().Get("q")
52-
filter, errs := auditSearchQuery(queryStr)
51+
filter, errs := searchquery.AuditLogs(queryStr)
5352
if len(errs) > 0 {
5453
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
5554
Message: "Invalid audit search query.",
@@ -373,125 +372,3 @@ func (api *API) auditLogResourceLink(ctx context.Context, alog database.GetAudit
373372
return ""
374373
}
375374
}
376-
377-
// auditSearchQuery takes a query string and returns the auditLog filter.
378-
// It also can return the list of validation errors to return to the api.
379-
func auditSearchQuery(query string) (database.GetAuditLogsOffsetParams, []codersdk.ValidationError) {
380-
searchParams := make(url.Values)
381-
if query == "" {
382-
// No filter
383-
return database.GetAuditLogsOffsetParams{}, nil
384-
}
385-
query = strings.ToLower(query)
386-
// Because we do this in 2 passes, we want to maintain quotes on the first
387-
// pass.Further splitting occurs on the second pass and quotes will be
388-
// dropped.
389-
elements := splitQueryParameterByDelimiter(query, ' ', true)
390-
for _, element := range elements {
391-
parts := splitQueryParameterByDelimiter(element, ':', false)
392-
switch len(parts) {
393-
case 1:
394-
// No key:value pair.
395-
searchParams.Set("resource_type", parts[0])
396-
case 2:
397-
searchParams.Set(parts[0], parts[1])
398-
default:
399-
return database.GetAuditLogsOffsetParams{}, []codersdk.ValidationError{
400-
{Field: "q", Detail: fmt.Sprintf("Query element %q can only contain 1 ':'", element)},
401-
}
402-
}
403-
}
404-
405-
// Using the query param parser here just returns consistent errors with
406-
// other parsing.
407-
parser := httpapi.NewQueryParamParser()
408-
const layout = "2006-01-02"
409-
410-
var (
411-
dateFromString = parser.String(searchParams, "", "date_from")
412-
dateToString = parser.String(searchParams, "", "date_to")
413-
parsedDateFrom, _ = time.Parse(layout, dateFromString)
414-
parsedDateTo, _ = time.Parse(layout, dateToString)
415-
)
416-
417-
if dateToString != "" {
418-
parsedDateTo = parsedDateTo.Add(23*time.Hour + 59*time.Minute + 59*time.Second) // parsedDateTo goes to 23:59
419-
}
420-
421-
if dateToString != "" && parsedDateTo.Before(parsedDateFrom) {
422-
return database.GetAuditLogsOffsetParams{}, []codersdk.ValidationError{
423-
{Field: "q", Detail: fmt.Sprintf("DateTo value %q cannot be before than DateFrom", parsedDateTo)},
424-
}
425-
}
426-
427-
filter := database.GetAuditLogsOffsetParams{
428-
ResourceType: resourceTypeFromString(parser.String(searchParams, "", "resource_type")),
429-
ResourceID: parser.UUID(searchParams, uuid.Nil, "resource_id"),
430-
Action: actionFromString(parser.String(searchParams, "", "action")),
431-
Username: parser.String(searchParams, "", "username"),
432-
Email: parser.String(searchParams, "", "email"),
433-
DateFrom: parsedDateFrom,
434-
DateTo: parsedDateTo,
435-
BuildReason: buildReasonFromString(parser.String(searchParams, "", "build_reason")),
436-
}
437-
438-
return filter, parser.Errors
439-
}
440-
441-
func resourceTypeFromString(resourceTypeString string) string {
442-
switch codersdk.ResourceType(resourceTypeString) {
443-
case codersdk.ResourceTypeTemplate:
444-
return resourceTypeString
445-
case codersdk.ResourceTypeTemplateVersion:
446-
return resourceTypeString
447-
case codersdk.ResourceTypeUser:
448-
return resourceTypeString
449-
case codersdk.ResourceTypeWorkspace:
450-
return resourceTypeString
451-
case codersdk.ResourceTypeWorkspaceBuild:
452-
return resourceTypeString
453-
case codersdk.ResourceTypeGitSSHKey:
454-
return resourceTypeString
455-
case codersdk.ResourceTypeAPIKey:
456-
return resourceTypeString
457-
case codersdk.ResourceTypeGroup:
458-
return resourceTypeString
459-
case codersdk.ResourceTypeLicense:
460-
return resourceTypeString
461-
}
462-
return ""
463-
}
464-
465-
func actionFromString(actionString string) string {
466-
switch codersdk.AuditAction(actionString) {
467-
case codersdk.AuditActionCreate:
468-
return actionString
469-
case codersdk.AuditActionWrite:
470-
return actionString
471-
case codersdk.AuditActionDelete:
472-
return actionString
473-
case codersdk.AuditActionStart:
474-
return actionString
475-
case codersdk.AuditActionStop:
476-
return actionString
477-
case codersdk.AuditActionLogin:
478-
return actionString
479-
case codersdk.AuditActionLogout:
480-
return actionString
481-
default:
482-
}
483-
return ""
484-
}
485-
486-
func buildReasonFromString(buildReasonString string) string {
487-
switch codersdk.BuildReason(buildReasonString) {
488-
case codersdk.BuildReasonInitiator:
489-
return buildReasonString
490-
case codersdk.BuildReasonAutostart:
491-
return buildReasonString
492-
case codersdk.BuildReasonAutostop:
493-
return buildReasonString
494-
default:
495-
}
496-
return ""
497-
}

0 commit comments

Comments
 (0)