diff --git a/go.mod b/go.mod index 0c20f3ae4..033126a15 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/docker/docker v28.3.3+incompatible github.com/docker/go-connections v0.5.0 github.com/fsnotify/fsnotify v1.9.0 - github.com/getsentry/sentry-go v0.34.1 + github.com/getsentry/sentry-go v0.35.0 github.com/go-errors/errors v1.5.1 github.com/go-git/go-git/v5 v5.16.2 github.com/go-xmlfmt/xmlfmt v1.1.3 @@ -151,7 +151,7 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v5 v5.2.3 // indirect + github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect diff --git a/go.sum b/go.sum index 6dea04751..eff73ce59 100644 --- a/go.sum +++ b/go.sum @@ -296,8 +296,8 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/getkin/kin-openapi v0.131.0 h1:NO2UeHnFKRYhZ8wg6Nyh5Cq7dHk4suQQr72a4pMrDxE= github.com/getkin/kin-openapi v0.131.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58= -github.com/getsentry/sentry-go v0.34.1 h1:HSjc1C/OsnZttohEPrrqKH42Iud0HuLCXpv8cU1pWcw= -github.com/getsentry/sentry-go v0.34.1/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE= +github.com/getsentry/sentry-go v0.35.0 h1:+FJNlnjJsZMG3g0/rmmP7GiKjQoUF5EXfEtBwtPtkzY= +github.com/getsentry/sentry-go v0.35.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE= github.com/ghostiam/protogetter v0.3.15 h1:1KF5sXel0HE48zh1/vn0Loiw25A9ApyseLzQuif1mLY= github.com/ghostiam/protogetter v0.3.15/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= @@ -377,8 +377,8 @@ github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0= -github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= diff --git a/internal/link/link.go b/internal/link/link.go index 471d469d9..9bf77675e 100644 --- a/internal/link/link.go +++ b/internal/link/link.go @@ -39,7 +39,7 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs, options ...func( if err != nil { return err } - LinkServices(ctx, projectRef, keys.Anon, fsys) + LinkServices(ctx, projectRef, keys.ServiceRole, fsys) // 2. Check database connection config := flags.NewDbConfigWithPassword(ctx, projectRef) @@ -66,7 +66,7 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs, options ...func( return nil } -func LinkServices(ctx context.Context, projectRef, anonKey string, fsys afero.Fs) { +func LinkServices(ctx context.Context, projectRef, serviceKey string, fsys afero.Fs) { // Ignore non-fatal errors linking services var wg sync.WaitGroup wg.Add(8) @@ -106,7 +106,7 @@ func LinkServices(ctx context.Context, projectRef, anonKey string, fsys afero.Fs fmt.Fprintln(os.Stderr, err) } }() - api := tenant.NewTenantAPI(ctx, projectRef, anonKey) + api := tenant.NewTenantAPI(ctx, projectRef, serviceKey) go func() { defer wg.Done() if err := linkPostgrestVersion(ctx, api, fsys); err != nil && viper.GetBool("DEBUG") { diff --git a/internal/services/services.go b/internal/services/services.go index 0d31891ac..a84e3a878 100644 --- a/internal/services/services.go +++ b/internal/services/services.go @@ -9,6 +9,7 @@ import ( "sync" "github.com/spf13/afero" + "github.com/spf13/viper" "github.com/supabase/cli/internal/migration/list" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" @@ -79,18 +80,22 @@ func listRemoteImages(ctx context.Context, projectRef string) map[string]string wg.Wait() return linked } - api := tenant.NewTenantAPI(ctx, projectRef, keys.Anon) + api := tenant.NewTenantAPI(ctx, projectRef, keys.ServiceRole) wg.Add(2) go func() { defer wg.Done() if version, err := api.GetGotrueVersion(ctx); err == nil { linked[utils.Config.Auth.Image] = version + } else if viper.GetBool("DEBUG") { + fmt.Fprintln(os.Stderr, err) } }() go func() { defer wg.Done() if version, err := api.GetPostgrestVersion(ctx); err == nil { linked[utils.Config.Api.Image] = version + } else if viper.GetBool("DEBUG") { + fmt.Fprintln(os.Stderr, err) } }() wg.Wait() diff --git a/internal/utils/tenant/client.go b/internal/utils/tenant/client.go index c8bb26cfe..3d6d039fa 100644 --- a/internal/utils/tenant/client.go +++ b/internal/utils/tenant/client.go @@ -88,10 +88,10 @@ type TenantAPI struct { *fetcher.Fetcher } -func NewTenantAPI(ctx context.Context, projectRef, anonKey string) TenantAPI { +func NewTenantAPI(ctx context.Context, projectRef, serviceKey string) TenantAPI { return TenantAPI{Fetcher: fetcher.NewServiceGateway( "https://"+utils.GetSupabaseHost(projectRef), - anonKey, + serviceKey, fetcher.WithUserAgent("SupabaseCLI/"+utils.Version), )} } diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go index 45e92c6a4..b3898e0f3 100644 --- a/pkg/api/client.gen.go +++ b/pkg/api/client.gen.go @@ -377,6 +377,20 @@ type ClientInterface interface { // V1GetDatabaseMetadata request V1GetDatabaseMetadata(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1GetJitAccess request + V1GetJitAccess(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // V1UpdateJitAccessWithBody request with any body + V1UpdateJitAccessWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + V1UpdateJitAccess(ctx context.Context, ref string, body V1UpdateJitAccessJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // V1ListJitAccess request + V1ListJitAccess(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // V1DeleteJitAccess request + V1DeleteJitAccess(ctx context.Context, ref string, userId openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1ListMigrationHistory request V1ListMigrationHistory(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -1803,6 +1817,66 @@ func (c *Client) V1GetDatabaseMetadata(ctx context.Context, ref string, reqEdito return c.Client.Do(req) } +func (c *Client) V1GetJitAccess(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1GetJitAccessRequest(c.Server, ref) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1UpdateJitAccessWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1UpdateJitAccessRequestWithBody(c.Server, ref, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1UpdateJitAccess(ctx context.Context, ref string, body V1UpdateJitAccessJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1UpdateJitAccessRequest(c.Server, ref, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1ListJitAccess(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1ListJitAccessRequest(c.Server, ref) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1DeleteJitAccess(ctx context.Context, ref string, userId openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1DeleteJitAccessRequest(c.Server, ref, userId) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) V1ListMigrationHistory(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewV1ListMigrationHistoryRequest(c.Server, ref) if err != nil { @@ -6217,6 +6291,162 @@ func NewV1GetDatabaseMetadataRequest(server string, ref string) (*http.Request, return req, nil } +// NewV1GetJitAccessRequest generates requests for V1GetJitAccess +func NewV1GetJitAccessRequest(server string, ref string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/database/jit", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewV1UpdateJitAccessRequest calls the generic V1UpdateJitAccess builder with application/json body +func NewV1UpdateJitAccessRequest(server string, ref string, body V1UpdateJitAccessJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewV1UpdateJitAccessRequestWithBody(server, ref, "application/json", bodyReader) +} + +// NewV1UpdateJitAccessRequestWithBody generates requests for V1UpdateJitAccess with any type of body +func NewV1UpdateJitAccessRequestWithBody(server string, ref string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/database/jit", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PUT", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewV1ListJitAccessRequest generates requests for V1ListJitAccess +func NewV1ListJitAccessRequest(server string, ref string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/database/jit/list", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewV1DeleteJitAccessRequest generates requests for V1DeleteJitAccess +func NewV1DeleteJitAccessRequest(server string, ref string, userId openapi_types.UUID) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + var pathParam1 string + + pathParam1, err = runtime.StyleParamWithLocation("simple", false, "user_id", runtime.ParamLocationPath, userId) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/database/jit/%s", pathParam0, pathParam1) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewV1ListMigrationHistoryRequest generates requests for V1ListMigrationHistory func NewV1ListMigrationHistoryRequest(server string, ref string) (*http.Request, error) { var err error @@ -8870,6 +9100,20 @@ type ClientWithResponsesInterface interface { // V1GetDatabaseMetadataWithResponse request V1GetDatabaseMetadataWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetDatabaseMetadataResponse, error) + // V1GetJitAccessWithResponse request + V1GetJitAccessWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetJitAccessResponse, error) + + // V1UpdateJitAccessWithBodyWithResponse request with any body + V1UpdateJitAccessWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessResponse, error) + + V1UpdateJitAccessWithResponse(ctx context.Context, ref string, body V1UpdateJitAccessJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessResponse, error) + + // V1ListJitAccessWithResponse request + V1ListJitAccessWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1ListJitAccessResponse, error) + + // V1DeleteJitAccessWithResponse request + V1DeleteJitAccessWithResponse(ctx context.Context, ref string, userId openapi_types.UUID, reqEditors ...RequestEditorFn) (*V1DeleteJitAccessResponse, error) + // V1ListMigrationHistoryWithResponse request V1ListMigrationHistoryWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1ListMigrationHistoryResponse, error) @@ -10773,6 +11017,93 @@ func (r V1GetDatabaseMetadataResponse) StatusCode() int { return 0 } +type V1GetJitAccessResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *JitAccessResponse +} + +// Status returns HTTPResponse.Status +func (r V1GetJitAccessResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1GetJitAccessResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type V1UpdateJitAccessResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *JitAccessResponse +} + +// Status returns HTTPResponse.Status +func (r V1UpdateJitAccessResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1UpdateJitAccessResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type V1ListJitAccessResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *JitListAccessResponse +} + +// Status returns HTTPResponse.Status +func (r V1ListJitAccessResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1ListJitAccessResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type V1DeleteJitAccessResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r V1DeleteJitAccessResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1DeleteJitAccessResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type V1ListMigrationHistoryResponse struct { Body []byte HTTPResponse *http.Response @@ -12703,6 +13034,50 @@ func (c *ClientWithResponses) V1GetDatabaseMetadataWithResponse(ctx context.Cont return ParseV1GetDatabaseMetadataResponse(rsp) } +// V1GetJitAccessWithResponse request returning *V1GetJitAccessResponse +func (c *ClientWithResponses) V1GetJitAccessWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetJitAccessResponse, error) { + rsp, err := c.V1GetJitAccess(ctx, ref, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1GetJitAccessResponse(rsp) +} + +// V1UpdateJitAccessWithBodyWithResponse request with arbitrary body returning *V1UpdateJitAccessResponse +func (c *ClientWithResponses) V1UpdateJitAccessWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessResponse, error) { + rsp, err := c.V1UpdateJitAccessWithBody(ctx, ref, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1UpdateJitAccessResponse(rsp) +} + +func (c *ClientWithResponses) V1UpdateJitAccessWithResponse(ctx context.Context, ref string, body V1UpdateJitAccessJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessResponse, error) { + rsp, err := c.V1UpdateJitAccess(ctx, ref, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1UpdateJitAccessResponse(rsp) +} + +// V1ListJitAccessWithResponse request returning *V1ListJitAccessResponse +func (c *ClientWithResponses) V1ListJitAccessWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1ListJitAccessResponse, error) { + rsp, err := c.V1ListJitAccess(ctx, ref, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1ListJitAccessResponse(rsp) +} + +// V1DeleteJitAccessWithResponse request returning *V1DeleteJitAccessResponse +func (c *ClientWithResponses) V1DeleteJitAccessWithResponse(ctx context.Context, ref string, userId openapi_types.UUID, reqEditors ...RequestEditorFn) (*V1DeleteJitAccessResponse, error) { + rsp, err := c.V1DeleteJitAccess(ctx, ref, userId, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1DeleteJitAccessResponse(rsp) +} + // V1ListMigrationHistoryWithResponse request returning *V1ListMigrationHistoryResponse func (c *ClientWithResponses) V1ListMigrationHistoryWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1ListMigrationHistoryResponse, error) { rsp, err := c.V1ListMigrationHistory(ctx, ref, reqEditors...) @@ -15194,6 +15569,100 @@ func ParseV1GetDatabaseMetadataResponse(rsp *http.Response) (*V1GetDatabaseMetad return response, nil } +// ParseV1GetJitAccessResponse parses an HTTP response from a V1GetJitAccessWithResponse call +func ParseV1GetJitAccessResponse(rsp *http.Response) (*V1GetJitAccessResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1GetJitAccessResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest JitAccessResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseV1UpdateJitAccessResponse parses an HTTP response from a V1UpdateJitAccessWithResponse call +func ParseV1UpdateJitAccessResponse(rsp *http.Response) (*V1UpdateJitAccessResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1UpdateJitAccessResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest JitAccessResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseV1ListJitAccessResponse parses an HTTP response from a V1ListJitAccessWithResponse call +func ParseV1ListJitAccessResponse(rsp *http.Response) (*V1ListJitAccessResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1ListJitAccessResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest JitListAccessResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseV1DeleteJitAccessResponse parses an HTTP response from a V1DeleteJitAccessWithResponse call +func ParseV1DeleteJitAccessResponse(rsp *http.Response) (*V1DeleteJitAccessResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1DeleteJitAccessResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseV1ListMigrationHistoryResponse parses an HTTP response from a V1ListMigrationHistoryWithResponse call func ParseV1ListMigrationHistoryResponse(rsp *http.Response) (*V1ListMigrationHistoryResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index ca0fd71c5..7079302fc 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -537,6 +537,8 @@ const ( // Defines values for ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion. const ( + N13 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "13" + N14 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "14" N15 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "15" N17 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "17" N17Oriole ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "17-oriole" @@ -632,6 +634,12 @@ const ( SnippetResponseVisibilityUser SnippetResponseVisibility = "user" ) +// Defines values for StorageConfigResponseExternalUpstreamTarget. +const ( + StorageConfigResponseExternalUpstreamTargetCanary StorageConfigResponseExternalUpstreamTarget = "canary" + StorageConfigResponseExternalUpstreamTargetMain StorageConfigResponseExternalUpstreamTarget = "main" +) + // Defines values for SupavisorConfigResponseDatabaseType. const ( PRIMARY SupavisorConfigResponseDatabaseType = "PRIMARY" @@ -701,6 +709,12 @@ const ( UpdateSigningKeyBodyStatusStandby UpdateSigningKeyBodyStatus = "standby" ) +// Defines values for UpdateStorageConfigBodyExternalUpstreamTarget. +const ( + UpdateStorageConfigBodyExternalUpstreamTargetCanary UpdateStorageConfigBodyExternalUpstreamTarget = "canary" + UpdateStorageConfigBodyExternalUpstreamTargetMain UpdateStorageConfigBodyExternalUpstreamTarget = "main" +) + // Defines values for UpdateSupavisorConfigBodyPoolMode. const ( UpdateSupavisorConfigBodyPoolModeSession UpdateSupavisorConfigBodyPoolMode = "session" @@ -1744,6 +1758,26 @@ type GetProviderResponse struct { UpdatedAt *string `json:"updated_at,omitempty"` } +// JitAccessResponse defines model for JitAccessResponse. +type JitAccessResponse struct { + UserId openapi_types.UUID `json:"user_id"` + UserRoles []struct { + ExpiresAt *string `json:"expires_at,omitempty"` + Role string `json:"role"` + } `json:"user_roles"` +} + +// JitListAccessResponse defines model for JitListAccessResponse. +type JitListAccessResponse struct { + Items []struct { + UserId openapi_types.UUID `json:"user_id"` + UserRoles []struct { + ExpiresAt *string `json:"expires_at,omitempty"` + Role string `json:"role"` + } `json:"user_roles"` + } `json:"items"` +} + // LegacyApiKeysResponse defines model for LegacyApiKeysResponse. type LegacyApiKeysResponse struct { Enabled bool `json:"enabled"` @@ -2249,6 +2283,13 @@ type SslEnforcementResponse struct { // StorageConfigResponse defines model for StorageConfigResponse. type StorageConfigResponse struct { + Capabilities struct { + IcebergCatalog bool `json:"iceberg_catalog"` + ListV2 bool `json:"list_v2"` + } `json:"capabilities"` + External struct { + UpstreamTarget StorageConfigResponseExternalUpstreamTarget `json:"upstreamTarget"` + } `json:"external"` Features struct { IcebergCatalog *struct { Enabled bool `json:"enabled"` @@ -2263,6 +2304,9 @@ type StorageConfigResponse struct { FileSizeLimit int64 `json:"fileSizeLimit"` } +// StorageConfigResponseExternalUpstreamTarget defines model for StorageConfigResponse.External.UpstreamTarget. +type StorageConfigResponseExternalUpstreamTarget string + // StreamableFile defines model for StreamableFile. type StreamableFile = map[string]interface{} @@ -2561,6 +2605,15 @@ type UpdateCustomHostnameResponse struct { // UpdateCustomHostnameResponseStatus defines model for UpdateCustomHostnameResponse.Status. type UpdateCustomHostnameResponseStatus string +// UpdateJitAccessBody defines model for UpdateJitAccessBody. +type UpdateJitAccessBody struct { + Roles []struct { + ExpiresAt *string `json:"expires_at,omitempty"` + Role string `json:"role"` + } `json:"roles"` + UserId openapi_types.UUID `json:"user_id"` +} + // UpdatePgsodiumConfigBody defines model for UpdatePgsodiumConfigBody. type UpdatePgsodiumConfigBody struct { RootKey string `json:"root_key"` @@ -2649,6 +2702,9 @@ type UpdateSigningKeyBodyStatus string // UpdateStorageConfigBody defines model for UpdateStorageConfigBody. type UpdateStorageConfigBody struct { + External *struct { + UpstreamTarget UpdateStorageConfigBodyExternalUpstreamTarget `json:"upstreamTarget"` + } `json:"external,omitempty"` Features *struct { IcebergCatalog *struct { Enabled bool `json:"enabled"` @@ -2663,6 +2719,9 @@ type UpdateStorageConfigBody struct { FileSizeLimit *int64 `json:"fileSizeLimit,omitempty"` } +// UpdateStorageConfigBodyExternalUpstreamTarget defines model for UpdateStorageConfigBody.External.UpstreamTarget. +type UpdateStorageConfigBodyExternalUpstreamTarget string + // UpdateSupavisorConfigBody defines model for UpdateSupavisorConfigBody. type UpdateSupavisorConfigBody struct { DefaultPoolSize nullable.Nullable[int] `json:"default_pool_size,omitempty"` @@ -3313,6 +3372,9 @@ type V1CreateRestorePointJSONRequestBody = V1RestorePointPostBody // V1UndoJSONRequestBody defines body for V1Undo for application/json ContentType. type V1UndoJSONRequestBody = V1UndoBody +// V1UpdateJitAccessJSONRequestBody defines body for V1UpdateJitAccess for application/json ContentType. +type V1UpdateJitAccessJSONRequestBody = UpdateJitAccessBody + // V1ApplyAMigrationJSONRequestBody defines body for V1ApplyAMigration for application/json ContentType. type V1ApplyAMigrationJSONRequestBody = V1CreateMigrationBody diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 52d1f6c4a..80a6488fd 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -3,16 +3,16 @@ FROM supabase/postgres:17.4.1.068 AS pg # Append to ServiceImages when adding new dependencies below FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit -FROM postgrest/postgrest:v12.2.12 AS postgrest -FROM supabase/postgres-meta:v0.91.3 AS pgmeta +FROM postgrest/postgrest:v13.0.4 AS postgrest +FROM supabase/postgres-meta:v0.91.4 AS pgmeta FROM supabase/studio:2025.07.28-sha-578b707 AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy -FROM supabase/edge-runtime:v1.68.2 AS edgeruntime +FROM supabase/edge-runtime:v1.68.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector -FROM supabase/supavisor:2.5.7 AS supavisor +FROM supabase/supavisor:2.6.0 AS supavisor FROM supabase/gotrue:v2.177.0 AS gotrue -FROM supabase/realtime:v2.41.10 AS realtime -FROM supabase/storage-api:v1.25.12 AS storage +FROM supabase/realtime:v2.41.11 AS realtime +FROM supabase/storage-api:v1.26.0 AS storage FROM supabase/logflare:1.14.2 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ diff --git a/pkg/go.mod b/pkg/go.mod index 6af4557b6..da9ff4f6c 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -10,7 +10,7 @@ require ( github.com/ecies/go/v2 v2.0.11 github.com/go-errors/errors v1.5.1 github.com/go-viper/mapstructure/v2 v2.4.0 - github.com/golang-jwt/jwt/v5 v5.2.3 + github.com/golang-jwt/jwt/v5 v5.3.0 github.com/h2non/gock v1.2.0 github.com/jackc/pgconn v1.14.3 github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 diff --git a/pkg/go.sum b/pkg/go.sum index f347a7ff0..c7f70e16f 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -40,8 +40,8 @@ github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9L github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0= -github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= diff --git a/pkg/migration/scripts/dump_data.sh b/pkg/migration/scripts/dump_data.sh index 764766510..c3c5d478b 100755 --- a/pkg/migration/scripts/dump_data.sh +++ b/pkg/migration/scripts/dump_data.sh @@ -22,6 +22,7 @@ echo "SET session_replication_role = replica; pg_dump \ --data-only \ --quote-all-identifier \ + --role "postgres" \ --exclude-schema "${EXCLUDED_SCHEMAS:-}" \ --exclude-table "auth.schema_migrations" \ --exclude-table "storage.migrations" \ diff --git a/pkg/migration/scripts/dump_role.sh b/pkg/migration/scripts/dump_role.sh index e5c157ba3..cadc8c542 100755 --- a/pkg/migration/scripts/dump_role.sh +++ b/pkg/migration/scripts/dump_role.sh @@ -19,6 +19,7 @@ export PGDATABASE="$PGDATABASE" # - do not alter membership grants by supabase_admin role pg_dumpall \ --roles-only \ + --role "postgres" \ --quote-all-identifier \ --no-role-passwords \ --no-comments \ diff --git a/pkg/migration/scripts/dump_schema.sh b/pkg/migration/scripts/dump_schema.sh index dbcd18dc2..ee8407dad 100755 --- a/pkg/migration/scripts/dump_schema.sh +++ b/pkg/migration/scripts/dump_schema.sh @@ -25,6 +25,7 @@ export PGDATABASE="$PGDATABASE" pg_dump \ --schema-only \ --quote-all-identifier \ + --role "postgres" \ --exclude-schema "${EXCLUDED_SCHEMAS:-}" \ ${EXTRA_FLAGS:-} \ | sed -E 's/^CREATE SCHEMA "/CREATE SCHEMA IF NOT EXISTS "/' \