-
Notifications
You must be signed in to change notification settings - Fork 69
feat: Add dry-run functionality for WorkspaceKind creation #598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 69 commits
e07cc59
0ac6f9f
92661f0
4ce7875
cd02eb4
99538a7
72b3ba9
ca7f656
0c87cb6
234dee0
c0b8f7b
eb8d3ac
4c91627
eb70a94
48b690e
e3978c2
b6e664c
eae9e23
a4cd1c2
6ba18c0
23fed9c
c6e81c2
d680ea0
db3e000
60d6de0
08c206d
989fe53
da615f5
9607fab
3fed049
3feccf7
5e9c88f
0e90e5d
3e7f44a
13a66ae
de0e5c4
3218768
296f63f
b21cf69
b18812a
4b88c15
f1f1c83
dd94a8f
f02f07c
bdbfe1b
7bed0be
7a6bb30
77c69c5
039e0c9
c50bdbb
2d5b830
dcf6b93
673989f
053f278
d2b97e7
fd2dc79
a932c0f
1b14efd
1f5c6e1
1950ea3
877e6de
42ffd9b
e666e2e
b210a56
95431b4
253b25e
f3a4b51
073b16f
d2926ab
311812b
3610ec6
013f95f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ import ( | |
| "fmt" | ||
| "io" | ||
| "net/http" | ||
| "strings" | ||
|
|
||
| "github.com/julienschmidt/httprouter" | ||
| kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1" | ||
|
|
@@ -153,9 +154,17 @@ func (a *App) GetWorkspaceKindsHandler(w http.ResponseWriter, r *http.Request, _ | |
| // @Failure 500 {object} ErrorEnvelope "Internal server error. An unexpected error occurred on the server." | ||
| // @Router /workspacekinds [post] | ||
| func (a *App) CreateWorkspaceKindHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { | ||
| // Parse dry-run query parameter | ||
| dryRun := r.URL.Query().Get("dry_run") | ||
| if dryRun != "" && dryRun != "true" && dryRun != "false" { | ||
| a.badRequestResponse(w, r, fmt.Errorf("Invalid dry_run value. Must be 'true' or 'false'")) | ||
| return | ||
| } | ||
| isDryRun := dryRun == "true" | ||
|
|
||
| // validate the Content-Type header | ||
| if success := a.ValidateContentType(w, r, MediaTypeYaml); !success { | ||
| if !strings.EqualFold(r.Header.Get("Content-Type"), MediaTypeYaml) { | ||
| a.unsupportedMediaTypeResponse(w, r, fmt.Errorf("Only application/yaml is supported")) | ||
|
||
| return | ||
| } | ||
|
|
||
|
|
@@ -204,7 +213,7 @@ func (a *App) CreateWorkspaceKindHandler(w http.ResponseWriter, r *http.Request, | |
| } | ||
| // ============================================================ | ||
|
|
||
| createdWorkspaceKind, err := a.repositories.WorkspaceKind.Create(r.Context(), workspaceKind) | ||
| createdWorkspaceKind, err := a.repositories.WorkspaceKind.Create(r.Context(), workspaceKind, isDryRun) | ||
| if err != nil { | ||
| if errors.Is(err, repository.ErrWorkspaceKindAlreadyExists) { | ||
| a.conflictResponse(w, r, err) | ||
|
|
@@ -219,6 +228,16 @@ func (a *App) CreateWorkspaceKindHandler(w http.ResponseWriter, r *http.Request, | |
| return | ||
| } | ||
|
|
||
| // Set response Content-Type header | ||
| w.Header().Set("Content-Type", "application/json") | ||
|
||
|
|
||
| // Return appropriate response based on dry-run | ||
| if isDryRun { | ||
| responseEnvelope := &WorkspaceKindEnvelope{Data: *createdWorkspaceKind} | ||
| a.dataResponse(w, r, responseEnvelope) | ||
| return | ||
| } | ||
|
|
||
| // calculate the GET location for the created workspace kind (for the Location header) | ||
| location := a.LocationGetWorkspaceKind(createdWorkspaceKind.Name) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,24 +70,27 @@ func (r *WorkspaceKindRepository) GetWorkspaceKinds(ctx context.Context) ([]mode | |
| return workspaceKindsModels, nil | ||
| } | ||
|
|
||
| func (r *WorkspaceKindRepository) Create(ctx context.Context, workspaceKind *kubefloworgv1beta1.WorkspaceKind) (*models.WorkspaceKind, error) { | ||
| // create workspace kind | ||
| func (r *WorkspaceKindRepository) Create(ctx context.Context, workspaceKind *kubefloworgv1beta1.WorkspaceKind, dryRun bool) (*models.WorkspaceKind, error) { | ||
| if dryRun { | ||
| // For dry-run, just convert to model and return without creating | ||
| workspaceKindModel := models.NewWorkspaceKindModelFromWorkspaceKind(workspaceKind) | ||
| return &workspaceKindModel, nil | ||
| } | ||
|
Comment on lines
76
to
78
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As implemented - this is NOT achieving the desired outcome as written in the issue... primarly:
This code simply "echoes back" what was provided on the request - which won't inform the user if there were issues in the provided payload. Even when Something like the following is what I would expect to see in the implementation and then in testing this against a live cluster.. you should be able to see errors returned from k8s itself in the event you provided an invalid YAML
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| // Create workspace kind only if not dry-run | ||
| if err := r.client.Create(ctx, workspaceKind); err != nil { | ||
| if apierrors.IsAlreadyExists(err) { | ||
| return nil, ErrWorkspaceKindAlreadyExists | ||
| } | ||
| if apierrors.IsInvalid(err) { | ||
| // NOTE: we don't wrap this error so we can unpack it in the caller | ||
| // and extract the validation errors returned by the Kubernetes API server | ||
| // and extract the validation errors returned by the Kubernetes API server | ||
| return nil, err | ||
| } | ||
| return nil, err | ||
| } | ||
|
|
||
| // convert the created workspace to a WorkspaceKindUpdate model | ||
| // | ||
| // TODO: this function should return the WorkspaceKindUpdate model, once the update WSK api is implemented | ||
| // | ||
|
Comment on lines
88
to
90
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should preserve this i.e. once available - we would want a |
||
| // Convert the created workspace to a WorkspaceKindUpdate model | ||
| createdWorkspaceKindModel := models.NewWorkspaceKindModelFromWorkspaceKind(workspaceKind) | ||
|
|
||
| return &createdWorkspaceKindModel, nil | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file should not be included in this PR - as none of the actual changes implemented affect the I am guessing this is a side effect of the extreme amount of commits that are erroneously getting included in the PR. Feel free to reach out to me in Slack if you need help getting your source branch cleaned up! |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate this is the first time we are supporting a query parameter across any of our APIs - but it won't be the last! As such - I think its warranted to consider adding a helper function to
workspaces/backend/api/helpers.go.admittedly, I'm not immediately sure how to structure this for proper abstraction - presently leaning towards:
calling code would then look like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Note:
strconv.ParseBool(...)not being leveraged here (which I agree with) - as it will also properly parse0,1, etc as boolean values - which feels wrong to support in an API.