Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
41 changes: 6 additions & 35 deletions components/ambient-api-server/openapi/openapi.credentials.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
paths:
# NEW ENDPOINT START
/api/ambient/v1/projects/{id}/credentials:
# NEW ENDPOINT END
/api/ambient/v1/credentials:
get:
summary: Returns a list of credentials in a project
summary: Returns a list of credentials
security:
- Bearer: []
responses:
Expand Down Expand Up @@ -45,7 +43,7 @@ paths:
type: string
enum: [github, gitlab, jira, google, vertex, kubeconfig]
post:
summary: Create a new credential in a project
summary: Create a new credential
security:
- Bearer: []
requestBody:
Expand Down Expand Up @@ -92,11 +90,7 @@ paths:
application/json:
schema:
$ref: 'openapi.yaml#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/id'
# NEW ENDPOINT START
/api/ambient/v1/projects/{id}/credentials/{cred_id}:
# NEW ENDPOINT END
/api/ambient/v1/credentials/{cred_id}:
get:
summary: Get a credential by id
security:
Expand Down Expand Up @@ -218,11 +212,8 @@ paths:
schema:
$ref: 'openapi.yaml#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/id'
- $ref: '#/components/parameters/cred_id'
# NEW ENDPOINT START
/api/ambient/v1/projects/{id}/credentials/{cred_id}/token:
# NEW ENDPOINT END
/api/ambient/v1/credentials/{cred_id}/token:
get:
summary: Get a decrypted token for a credential
description: Returns the decrypted token value for the given credential. Requires token-reader role.
Expand Down Expand Up @@ -260,24 +251,17 @@ paths:
schema:
$ref: 'openapi.yaml#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/id'
- $ref: '#/components/parameters/cred_id'
components:
schemas:
# NEW SCHEMA START
Credential:
# NEW SCHEMA END
allOf:
- $ref: 'openapi.yaml#/components/schemas/ObjectReference'
- type: object
required:
- name
- provider
- project_id
properties:
project_id:
type: string
description: ID of the project this credential belongs to
name:
type: string
description:
Expand All @@ -297,9 +281,7 @@ components:
type: string
annotations:
type: string
# NEW SCHEMA START
CredentialList:
# NEW SCHEMA END
allOf:
- $ref: 'openapi.yaml#/components/schemas/List'
- type: object
Expand All @@ -308,9 +290,7 @@ components:
type: array
items:
$ref: '#/components/schemas/Credential'
# NEW SCHEMA START
CredentialPatchRequest:
# NEW SCHEMA END
type: object
properties:
name:
Expand All @@ -332,9 +312,7 @@ components:
type: string
annotations:
type: string
# NEW SCHEMA START
CredentialTokenResponse:
# NEW SCHEMA END
type: object
required:
- credential_id
Expand All @@ -352,13 +330,6 @@ components:
type: string
description: Decrypted token value
parameters:
id:
name: id
in: path
description: The id of the project
required: true
schema:
type: string
cred_id:
name: cred_id
in: path
Expand Down Expand Up @@ -446,7 +417,7 @@ components:
Example: For each Subscription to get id, href, plan(id and kind) and labels (all fields)

```
curl "/api/ambient/v1/sessions?fields=id,href,name,project_id"
curl "/api/ambient/v1/sessions?fields=id,href,name"
```
schema:
type: string
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ func newCredential(name string) (*credentials.Credential, error) {
credentialService := credentials.Service(&environments.Environment().Services)

credential := &credentials.Credential{
ProjectID: "test-project",
Name: name,
Description: stringPtr("test-description"),
Provider: "test-provider",
Provider: "github",
Token: stringPtr("test-token"),
Url: stringPtr("test-url"),
Email: stringPtr("test-email"),
Expand Down
40 changes: 2 additions & 38 deletions components/ambient-api-server/plugins/credentials/handler.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package credentials

import (
"fmt"
"net/http"
"regexp"

"github.com/gorilla/mux"

Expand All @@ -14,8 +12,6 @@ import (
"github.com/openshift-online/rh-trex-ai/pkg/services"
)

var safeProjectIDPattern = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)

var _ handlers.RestHandler = credentialHandler{}

type credentialHandler struct {
Expand All @@ -39,8 +35,7 @@ func (h credentialHandler) Create(w http.ResponseWriter, r *http.Request) {
},
Action: func() (interface{}, *errors.ServiceError) {
ctx := r.Context()
projectID := mux.Vars(r)["id"]
credentialModel := ConvertCredential(credential, projectID)
credentialModel := ConvertCredential(credential)
credentialModel, err := h.credential.Create(ctx, credentialModel)
if err != nil {
return nil, err
Expand All @@ -61,15 +56,11 @@ func (h credentialHandler) Patch(w http.ResponseWriter, r *http.Request) {
Validators: []handlers.Validate{},
Action: func() (interface{}, *errors.ServiceError) {
ctx := r.Context()
projectID := mux.Vars(r)["id"]
id := mux.Vars(r)["cred_id"]
found, err := h.credential.Get(ctx, id)
if err != nil {
return nil, err
}
if found.ProjectID != projectID {
return nil, errors.NotFound("credential with id='%s' not found", id)
}

if patch.Name != nil {
found.Name = *patch.Name
Expand Down Expand Up @@ -112,18 +103,7 @@ func (h credentialHandler) List(w http.ResponseWriter, r *http.Request) {
cfg := &handlers.HandlerConfig{
Action: func() (interface{}, *errors.ServiceError) {
ctx := r.Context()
projectID := mux.Vars(r)["id"]
if !safeProjectIDPattern.MatchString(projectID) {
return nil, errors.Validation("invalid project ID format")
}

listArgs := services.NewListArguments(r.URL.Query())
projectFilter := fmt.Sprintf("project_id = '%s'", projectID)
if listArgs.Search != "" {
listArgs.Search = fmt.Sprintf("(%s) and %s", listArgs.Search, projectFilter)
} else {
listArgs.Search = projectFilter
}
var credentials []Credential
paging, err := h.generic.List(ctx, "id", listArgs, &credentials)
if err != nil {
Expand Down Expand Up @@ -158,16 +138,12 @@ func (h credentialHandler) List(w http.ResponseWriter, r *http.Request) {
func (h credentialHandler) Get(w http.ResponseWriter, r *http.Request) {
cfg := &handlers.HandlerConfig{
Action: func() (interface{}, *errors.ServiceError) {
projectID := mux.Vars(r)["id"]
id := mux.Vars(r)["cred_id"]
ctx := r.Context()
credential, err := h.credential.Get(ctx, id)
if err != nil {
return nil, err
}
if credential.ProjectID != projectID {
return nil, errors.NotFound("credential with id='%s' not found", id)
}

return PresentCredential(credential), nil
},
Expand All @@ -179,17 +155,9 @@ func (h credentialHandler) Get(w http.ResponseWriter, r *http.Request) {
func (h credentialHandler) Delete(w http.ResponseWriter, r *http.Request) {
cfg := &handlers.HandlerConfig{
Action: func() (interface{}, *errors.ServiceError) {
projectID := mux.Vars(r)["id"]
id := mux.Vars(r)["cred_id"]
ctx := r.Context()
found, err := h.credential.Get(ctx, id)
if err != nil {
return nil, err
}
if found.ProjectID != projectID {
return nil, errors.NotFound("credential with id='%s' not found", id)
}
err = h.credential.Delete(ctx, id)
err := h.credential.Delete(ctx, id)
if err != nil {
return nil, err
}
Expand All @@ -202,16 +170,12 @@ func (h credentialHandler) Delete(w http.ResponseWriter, r *http.Request) {
func (h credentialHandler) GetToken(w http.ResponseWriter, r *http.Request) {
cfg := &handlers.HandlerConfig{
Action: func() (interface{}, *errors.ServiceError) {
projectID := mux.Vars(r)["id"]
id := mux.Vars(r)["cred_id"]
ctx := r.Context()
credential, err := h.credential.Get(ctx, id)
if err != nil {
return nil, err
}
if credential.ProjectID != projectID {
return nil, errors.NotFound("credential with id='%s' not found", id)
}

return PresentCredentialToken(credential), nil
},
Expand Down
16 changes: 14 additions & 2 deletions components/ambient-api-server/plugins/credentials/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ func addProjectIDMigration() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202604101200",
Migrate: func(tx *gorm.DB) error {
return tx.Exec("ALTER TABLE credentials ADD COLUMN IF NOT EXISTS project_id TEXT NOT NULL DEFAULT ''").Error
return tx.Exec("ALTER TABLE IF EXISTS credentials ADD COLUMN IF NOT EXISTS project_id TEXT NOT NULL DEFAULT ''").Error
},
Rollback: func(tx *gorm.DB) error {
return tx.Exec("ALTER TABLE credentials DROP COLUMN IF EXISTS project_id").Error
return tx.Exec("ALTER TABLE IF EXISTS credentials DROP COLUMN IF EXISTS project_id").Error
},
}
}
Expand Down Expand Up @@ -105,3 +105,15 @@ func rolesMigration() *gormigrate.Migration {
},
}
}

func dropProjectIDMigration() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202505120001",
Migrate: func(tx *gorm.DB) error {
return tx.Exec(`ALTER TABLE IF EXISTS credentials DROP COLUMN IF EXISTS project_id`).Error
},
Rollback: func(tx *gorm.DB) error {
return tx.Exec(`ALTER TABLE IF EXISTS credentials ADD COLUMN IF NOT EXISTS project_id TEXT NOT NULL DEFAULT ''`).Error
},
}
}
1 change: 0 additions & 1 deletion components/ambient-api-server/plugins/credentials/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

type Credential struct {
api.Meta
ProjectID string `json:"project_id"`
Name string `json:"name"`
Description *string `json:"description"`
Provider string `json:"provider"`
Expand Down
15 changes: 8 additions & 7 deletions components/ambient-api-server/plugins/credentials/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ func init() {
}
credentialHandler := NewCredentialHandler(Service(envServices), generic.Service(envServices))

credentialsRouter := apiV1Router.PathPrefix("/projects").Subrouter()
credentialsRouter.HandleFunc("/{id}/credentials", credentialHandler.List).Methods(http.MethodGet)
credentialsRouter.HandleFunc("/{id}/credentials", credentialHandler.Create).Methods(http.MethodPost)
credentialsRouter.HandleFunc("/{id}/credentials/{cred_id}", credentialHandler.Get).Methods(http.MethodGet)
credentialsRouter.HandleFunc("/{id}/credentials/{cred_id}", credentialHandler.Patch).Methods(http.MethodPatch)
credentialsRouter.HandleFunc("/{id}/credentials/{cred_id}", credentialHandler.Delete).Methods(http.MethodDelete)
credentialsRouter.HandleFunc("/{id}/credentials/{cred_id}/token", credentialHandler.GetToken).Methods(http.MethodGet)
credentialsRouter := apiV1Router.PathPrefix("/credentials").Subrouter()
credentialsRouter.HandleFunc("", credentialHandler.List).Methods(http.MethodGet)
credentialsRouter.HandleFunc("", credentialHandler.Create).Methods(http.MethodPost)
credentialsRouter.HandleFunc("/{cred_id}", credentialHandler.Get).Methods(http.MethodGet)
credentialsRouter.HandleFunc("/{cred_id}", credentialHandler.Patch).Methods(http.MethodPatch)
credentialsRouter.HandleFunc("/{cred_id}", credentialHandler.Delete).Methods(http.MethodDelete)
credentialsRouter.HandleFunc("/{cred_id}/token", credentialHandler.GetToken).Methods(http.MethodGet)
credentialsRouter.Use(authMiddleware.AuthenticateAccountJWT)
credentialsRouter.Use(authzMiddleware.AuthorizeApi)
})
Expand All @@ -85,4 +85,5 @@ func init() {
db.RegisterMigration(rolesMigration())
db.RegisterMigration(addProjectIDMigration())
db.RegisterMigration(removeCredentialReaderRoleMigration())
db.RegisterMigration(dropProjectIDMigration())
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import (
"github.com/openshift-online/rh-trex-ai/pkg/util"
)

func ConvertCredential(credential openapi.Credential, projectID string) *Credential {
func ConvertCredential(credential openapi.Credential) *Credential {
c := &Credential{
Meta: api.Meta{
ID: util.NilToEmptyString(credential.Id),
},
ProjectID: projectID,
}
c.Name = credential.Name
c.Description = credential.Description
Expand Down Expand Up @@ -41,7 +40,6 @@ func PresentCredential(credential *Credential) openapi.Credential {
Href: reference.Href,
CreatedAt: openapi.PtrTime(credential.CreatedAt),
UpdatedAt: openapi.PtrTime(credential.UpdatedAt),
ProjectId: credential.ProjectID,
Name: credential.Name,
Description: credential.Description,
Provider: credential.Provider,
Expand Down
4 changes: 2 additions & 2 deletions components/ambient-sdk/go-sdk/client/agent_api.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions components/ambient-sdk/go-sdk/client/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading