Skip to content
Open
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
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ define gen-doc-in-dir
cat ./$1/koyeb_sandbox_*.md >> ./$1/reference.md
cat ./$1/koyeb_version.md >> ./$1/reference.md
cat ./$1/koyeb_volumes.md >> ./$1/reference.md
cat ./$1/koyeb_projects.md >> ./$1/reference.md
cat ./$1/koyeb_projects_*.md >> ./$1/reference.md

find ./$1 -type f -not -name 'reference.md' -delete
endef

Expand Down
437 changes: 401 additions & 36 deletions docs/reference.md

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions pkg/koyeb/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func NewAppCmd() *cobra.Command {
}),
}
createAppCmd.Flags().Bool("delete-when-empty", false, "Automatically delete the app after the last service is deleted. Empty apps created without services are not deleted.")
createAppCmd.Flags().StringP("project", "p", "", "Project name or ID")
appCmd.AddCommand(createAppCmd)

initAppCmd := &cobra.Command{
Expand All @@ -64,6 +65,7 @@ func NewAppCmd() *cobra.Command {
}
initAppCmd.Flags().Bool("wait", false, "Waits until app deployment is done")
initAppCmd.Flags().Duration("wait-timeout", 5*time.Minute, "Duration the wait will last until timeout")
initAppCmd.Flags().StringP("project", "p", "", "Project name or ID")
appCmd.AddCommand(initAppCmd)
serviceHandler.addServiceDefinitionFlags(initAppCmd.Flags())

Expand All @@ -73,13 +75,16 @@ func NewAppCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Get),
}
getAppCmd.Flags().StringP("project", "p", "", "Project name or ID (optional context)")
appCmd.AddCommand(getAppCmd)

listAppCmd := &cobra.Command{
Use: "list",
Short: "List apps",
RunE: WithCLIContext(h.List),
}
listAppCmd.Flags().StringP("project", "p", "", "Project name or ID (filter apps by project)")
listAppCmd.Flags().Bool("all-projects", false, "List apps from all projects (overrides project filter)")
appCmd.AddCommand(listAppCmd)

describeAppCmd := &cobra.Command{
Expand All @@ -88,6 +93,7 @@ func NewAppCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Describe),
}
describeAppCmd.Flags().StringP("project", "p", "", "Project name or ID (optional context)")
appCmd.AddCommand(describeAppCmd)

updateAppCmd := &cobra.Command{
Expand Down Expand Up @@ -130,6 +136,7 @@ func NewAppCmd() *cobra.Command {
updateAppCmd.Flags().StringP("name", "n", "", "Change the name of the app")
updateAppCmd.Flags().StringP("domain", "D", "", "Change the subdomain of the app (only specify the subdomain, skipping \".koyeb.app\")")
updateAppCmd.Flags().Bool("delete-when-empty", false, "Automatically delete the app after the last service is deleted. Empty apps created without services are not deleted.")
updateAppCmd.Flags().StringP("project", "p", "", "Project name or ID (optional context)")
appCmd.AddCommand(updateAppCmd)

deleteAppCmd := &cobra.Command{
Expand All @@ -138,6 +145,7 @@ func NewAppCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Delete),
}
deleteAppCmd.Flags().StringP("project", "p", "", "Project name or ID (optional context)")
appCmd.AddCommand(deleteAppCmd)

pauseServiceCmd := &cobra.Command{
Expand Down
10 changes: 10 additions & 0 deletions pkg/koyeb/apps_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ func (h *AppHandler) CreateApp(ctx *CLIContext, payload *koyeb.CreateApp) (*koye
func (h *AppHandler) Create(ctx *CLIContext, cmd *cobra.Command, args []string, createApp *koyeb.CreateApp) error {
createApp.SetName(args[0])

projectFlag, _ := cmd.Flags().GetString("project")
if projectFlag != "" {
projectHandler := NewProjectHandler()
projectID, err := projectHandler.ResolveProjectArgs(ctx, projectFlag)
if err != nil {
return err
}
createApp.SetProjectId(projectID)
}

res, err := h.CreateApp(ctx, createApp)
if err != nil {
return err
Expand Down
15 changes: 15 additions & 0 deletions pkg/koyeb/apps_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ import (
func (h *AppHandler) List(ctx *CLIContext, cmd *cobra.Command, args []string) error {
list := []koyeb.AppListItem{}

// TODO: Implement project filtering when API support is available
// Check if we should filter by project
// allProjects, _ := cmd.Flags().GetBool("all-projects")
// projectFlag, _ := cmd.Flags().GetString("project")
//
// var projectID string
// if !allProjects && projectFlag != "" {
// projectHandler := NewProjectHandler()
// var err error
// projectID, err = projectHandler.ResolveProjectArgs(ctx, projectFlag)
// if err != nil {
// return err
// }
// }

page := int64(0)
offset := int64(0)
limit := int64(100)
Expand Down
18 changes: 17 additions & 1 deletion pkg/koyeb/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ const (
ctx_mapper
ctx_renderer
ctx_organization
ctx_project
)

// SetupCLIContext is called by the root command to setup the context for all subcommands.
// When `organization` is not empty, it should contain the ID of the organization to switch the context to.
func SetupCLIContext(cmd *cobra.Command, organization string) error {
// When `project` is not empty, it should contain the ID of the project to use in the context.
// If the project is invalid or doesn't exist in the current organization, it will be cleared.
func SetupCLIContext(cmd *cobra.Command, organization string, project string) error {
apiClient, err := getApiClient()
if err != nil {
return err
Expand Down Expand Up @@ -60,6 +63,17 @@ func SetupCLIContext(cmd *cobra.Command, organization string) error {
ctx = context.WithValue(ctx, ctx_mapper, idmapper.NewMapper(ctx, apiClient))
ctx = context.WithValue(ctx, ctx_renderer, renderer.NewRenderer(outputFormat))
ctx = context.WithValue(ctx, ctx_organization, organization)

// Validate project exists in current organization. If not, clear it as fallback.
if project != "" {
projectMapper := idmapper.NewMapper(ctx, apiClient).Project()
if _, err := projectMapper.ResolveID(project); err != nil {
// Project is invalid or doesn't exist - clear it silently as fallback
project = ""
}
}

ctx = context.WithValue(ctx, ctx_project, project)
cmd.SetContext(ctx)

return nil
Expand All @@ -74,6 +88,7 @@ type CLIContext struct {
Token string
Renderer renderer.Renderer
Organization string
Project string
}

// GetCLIContext transforms the untyped context passed to cobra commands into a CLIContext.
Expand All @@ -87,6 +102,7 @@ func GetCLIContext(ctx context.Context) *CLIContext {
Token: ctx.Value(koyeb.ContextAccessToken).(string),
Renderer: ctx.Value(ctx_renderer).(renderer.Renderer),
Organization: ctx.Value(ctx_organization).(string),
Project: ctx.Value(ctx_project).(string),
}
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/koyeb/databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func NewDatabaseCmd() *cobra.Command {
Short: "List databases",
RunE: WithCLIContext(h.List),
}
listDbCmd.Flags().StringP("project", "p", "", "Project name or ID")
databaseCmd.AddCommand(listDbCmd)

getDbCmd := &cobra.Command{
Expand All @@ -34,6 +35,7 @@ func NewDatabaseCmd() *cobra.Command {
RunE: WithCLIContext(h.Get),
}
getDbCmd.Flags().String("app", "", "Database application. If the application does not exist, it will be created. Can also be provided in the database name with the format `app-name/database-name`")
getDbCmd.Flags().StringP("project", "p", "", "Project name or ID")
databaseCmd.AddCommand(getDbCmd)

createDbCmd := &cobra.Command{
Expand All @@ -58,6 +60,7 @@ func NewDatabaseCmd() *cobra.Command {
}),
}
addCreateDbServiceDefinitionFlags(createDbCmd.Flags())
createDbCmd.Flags().StringP("project", "p", "", "Project name or ID")
databaseCmd.AddCommand(createDbCmd)

updateDbCmd := &cobra.Command{
Expand Down Expand Up @@ -113,6 +116,7 @@ func NewDatabaseCmd() *cobra.Command {
}),
}
addUpdateDbServiceDefinitionFlags(updateDbCmd.Flags())
updateDbCmd.Flags().StringP("project", "p", "", "Project name or ID")
databaseCmd.AddCommand(updateDbCmd)

deleteDbCmd := &cobra.Command{
Expand All @@ -121,6 +125,7 @@ func NewDatabaseCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Delete),
}
deleteDbCmd.Flags().StringP("project", "p", "", "Project name or ID")
databaseCmd.AddCommand(deleteDbCmd)

return databaseCmd
Expand Down
8 changes: 8 additions & 0 deletions pkg/koyeb/domains.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func NewDomainCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Get),
}
getDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(getDomainCmd)

createDomainCmd := &cobra.Command{
Expand All @@ -28,6 +29,7 @@ func NewDomainCmd() *cobra.Command {
RunE: WithCLIContext(h.Create),
}
createDomainCmd.Flags().String("attach-to", "", "Upon creation, assign to given app")
createDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(createDomainCmd)

describeDomainCmd := &cobra.Command{
Expand All @@ -36,20 +38,23 @@ func NewDomainCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Describe),
}
describeDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(describeDomainCmd)

listDomainCmd := &cobra.Command{
Use: "list",
Short: "List domains",
RunE: WithCLIContext(h.List),
}
listDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(listDomainCmd)

deleteDomainCmd := &cobra.Command{
Use: "delete",
Short: "Delete domain",
RunE: WithCLIContext(h.Delete),
}
deleteDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(deleteDomainCmd)

refreshDomainCmd := &cobra.Command{
Expand All @@ -58,6 +63,7 @@ func NewDomainCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Refresh),
}
refreshDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(refreshDomainCmd)

attachDomainCmd := &cobra.Command{
Expand All @@ -66,6 +72,7 @@ func NewDomainCmd() *cobra.Command {
Args: cobra.ExactArgs(2),
RunE: WithCLIContext(h.Attach),
}
attachDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(attachDomainCmd)

detachDomainCmd := &cobra.Command{
Expand All @@ -74,6 +81,7 @@ func NewDomainCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(h.Detach),
}
detachDomainCmd.Flags().StringP("project", "p", "", "Project name or ID")
domainCmd.AddCommand(detachDomainCmd)

return domainCmd
Expand Down
10 changes: 10 additions & 0 deletions pkg/koyeb/domains_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ func (h *DomainHandler) Create(ctx *CLIContext, cmd *cobra.Command, args []strin
createDomainReq.SetName(args[0])
createDomainReq.SetType(koyeb.DOMAINTYPE_CUSTOM)

projectFlag, _ := cmd.Flags().GetString("project")
if projectFlag != "" {
projectHandler := NewProjectHandler()
projectID, err := projectHandler.ResolveProjectArgs(ctx, projectFlag)
if err != nil {
return err
}
createDomainReq.SetProjectId(projectID)
}

attachToApp := GetStringFlags(cmd, "attach-to")
if attachToApp != "" {
appID, err := ctx.Mapper.App().ResolveID(attachToApp)
Expand Down
7 changes: 7 additions & 0 deletions pkg/koyeb/idmapper/idmapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Mapper struct {
database *DatabaseMapper
volume *VolumeMapper
snapshot *SnapshotMapper
project *ProjectMapper
}

func NewMapper(ctx context.Context, client *koyeb.APIClient) *Mapper {
Expand All @@ -32,6 +33,7 @@ func NewMapper(ctx context.Context, client *koyeb.APIClient) *Mapper {
databaseMapper := NewDatabaseMapper(ctx, client, appMapper)
volumeMapper := NewVolumeMapper(ctx, client)
snapshotMapper := NewSnapshotMapper(ctx, client)
projectMapper := NewProjectMapper(ctx, client)

return &Mapper{
app: appMapper,
Expand All @@ -45,6 +47,7 @@ func NewMapper(ctx context.Context, client *koyeb.APIClient) *Mapper {
database: databaseMapper,
volume: volumeMapper,
snapshot: snapshotMapper,
project: projectMapper,
}
}

Expand Down Expand Up @@ -91,3 +94,7 @@ func (mapper *Mapper) Volume() *VolumeMapper {
func (mapper *Mapper) Snapshot() *SnapshotMapper {
return mapper.snapshot
}

func (mapper *Mapper) Project() *ProjectMapper {
return mapper.project
}
Loading
Loading