diff --git a/cmd/preview.go b/cmd/preview.go index 83f8fb1..0f1528e 100644 --- a/cmd/preview.go +++ b/cmd/preview.go @@ -38,20 +38,22 @@ func NewCmdPreview() *cobra.Command { previewInitCmd.Flags().StringVarP(&previewInitParamsPath, "output", "o", "./preview.json", "Output path for preview environment params file. This file supports bash interpolation and can be manually edited or programatically modified during CI.") previewDeployCmd := &cobra.Command{ - Use: "deploy", - Short: "Deploys a preview environment in your project", - Long: helpdocs.MustRender("preview/deploy"), - RunE: runPreviewDeploy, + Use: "deploy", + Aliases: []string{"apply"}, + Short: "Deploys a preview environment in your project", + Long: helpdocs.MustRender("preview/deploy"), + RunE: runPreviewDeploy, } previewDeployCmd.Flags().StringVarP(&previewInitParamsPath, "params", "p", previewInitParamsPath, "Path to preview environment configuration file. This file supports bash interpolation.") previewDeployCmd.Flags().StringVarP(&previewDeployCiContextPath, "ci-context", "c", previewDeployCiContextPath, "Path to GitHub Actions event.json") previewDecommissionCmd := &cobra.Command{ - Use: "decommission $projectTargetSlug", - Short: "Decommissions a preview environment in your project", - Long: helpdocs.MustRender("preview/decommission"), - RunE: runPreviewDecommission, - Args: cobra.ExactArgs(1), + Use: "decommission $projectTargetSlug", + Aliases: []string{"destroy"}, + Short: "Decommissions a preview environment in your project", + Long: helpdocs.MustRender("preview/decommission"), + RunE: runPreviewDecommission, + Args: cobra.ExactArgs(1), } previewCmd.AddCommand(previewInitCmd) diff --git a/cmd/project.go b/cmd/project.go index 173c18d..f4228a1 100644 --- a/cmd/project.go +++ b/cmd/project.go @@ -44,10 +44,10 @@ func runProjList(cmd *cobra.Command, args []string) error { projects, err := api.ListProjects(client, config.OrgID) w := tabwriter.NewWriter(os.Stdout, 10, 1, 5, ' ', 0) - fmt.Fprintln(w, "ID\tNAME\tSLUG") + fmt.Fprintln(w, "SLUG\tNAME\tMONTHLY\tDAILY") - for _, project := range *projects { - line := fmt.Sprintf("%s\t%s\t%s", project.ID, project.Name, project.Slug) + for _, project := range projects { + line := fmt.Sprintf("%s\t%s\t%.2f\t%.2f", project.Slug, project.Name, project.MonthlyAverageCost, project.DailyAverageCost) fmt.Fprintln(w, line) } diff --git a/pkg/api/genqlient.graphql b/pkg/api/genqlient.graphql index e7bc31f..e79531c 100644 --- a/pkg/api/genqlient.graphql +++ b/pkg/api/genqlient.graphql @@ -10,7 +10,23 @@ query getArtifactsByType($organizationId: ID!, $artifactType: String!) { query projects($organizationId: ID!){ projects(organizationId: $organizationId){ - id, name, defaultParams, slug, description + name + id + slug + description + defaultParams + cost{ + monthly{ + average{ + amount + } + } + daily{ + average{ + amount + } + } + } } } diff --git a/pkg/api/preview_config.go b/pkg/api/preview_config.go index ddeeb79..b78702b 100644 --- a/pkg/api/preview_config.go +++ b/pkg/api/preview_config.go @@ -7,7 +7,7 @@ type PreviewConfig struct { } type PreviewPackage struct { - Params map[string]interface{} `json:"params"` + Params map[string]interface{} `json:"params,omitempty"` Secrets []Secret `json:"secrets,omitempty"` RemoteReferences []RemoteRef `json:"remoteReferences,omitempty"` } diff --git a/pkg/api/project.go b/pkg/api/project.go index 79f0945..d13a8c0 100644 --- a/pkg/api/project.go +++ b/pkg/api/project.go @@ -9,11 +9,13 @@ import ( ) type Project struct { - ID string - Name string - Slug string - Description string - DefaultParams map[string]interface{} + ID string + Name string + Slug string + Description string + DefaultParams map[string]interface{} + MonthlyAverageCost float64 + DailyAverageCost float64 } func GetProject(client graphql.Client, orgID string, idOrSlug string) (*Project, error) { @@ -34,15 +36,17 @@ func (p *getProjectByIdProject) toProject() *Project { func (p *projectsProjectsProject) toProject() Project { return Project{ - ID: p.Id, - Slug: p.Slug, - Name: p.Name, - Description: p.Description, - DefaultParams: p.DefaultParams, + ID: p.Id, + Slug: p.Slug, + Name: p.Name, + Description: p.Description, + DefaultParams: p.DefaultParams, + MonthlyAverageCost: p.Cost.Monthly.Average.Amount, + DailyAverageCost: p.Cost.Daily.Average.Amount, } } -func ListProjects(client graphql.Client, orgID string) (*[]Project, error) { +func ListProjects(client graphql.Client, orgID string) ([]Project, error) { response, err := projects(context.Background(), client, orgID) records := []Project{} @@ -50,7 +54,7 @@ func ListProjects(client graphql.Client, orgID string) (*[]Project, error) { records = append(records, prj.toProject()) } - return &records, err + return records, err } func (p *Project) GetDefaultParams() map[string]PreviewPackage { diff --git a/pkg/api/project_test.go b/pkg/api/project_test.go index 5408be5..7393028 100644 --- a/pkg/api/project_test.go +++ b/pkg/api/project_test.go @@ -57,7 +57,7 @@ func TestListProjects(t *testing.T) { t.Fatal(err) } - got := len(*projects) + got := len(projects) want := 2 diff --git a/pkg/api/zz_generated.go b/pkg/api/zz_generated.go index 04d0002..cb0d254 100644 --- a/pkg/api/zz_generated.go +++ b/pkg/api/zz_generated.go @@ -1346,21 +1346,20 @@ func (v *getProjectByIdResponse) GetProject() getProjectByIdProject { return v.P // projectsProjectsProject includes the requested fields of the GraphQL type Project. type projectsProjectsProject struct { - Id string `json:"id"` Name string `json:"name"` - DefaultParams map[string]interface{} `json:"-"` + Id string `json:"id"` Slug string `json:"slug"` Description string `json:"description"` + DefaultParams map[string]interface{} `json:"-"` + // Cloud provider costs for this project + Cost projectsProjectsProjectCost `json:"cost"` } -// GetId returns projectsProjectsProject.Id, and is useful for accessing the field via an interface. -func (v *projectsProjectsProject) GetId() string { return v.Id } - // GetName returns projectsProjectsProject.Name, and is useful for accessing the field via an interface. func (v *projectsProjectsProject) GetName() string { return v.Name } -// GetDefaultParams returns projectsProjectsProject.DefaultParams, and is useful for accessing the field via an interface. -func (v *projectsProjectsProject) GetDefaultParams() map[string]interface{} { return v.DefaultParams } +// GetId returns projectsProjectsProject.Id, and is useful for accessing the field via an interface. +func (v *projectsProjectsProject) GetId() string { return v.Id } // GetSlug returns projectsProjectsProject.Slug, and is useful for accessing the field via an interface. func (v *projectsProjectsProject) GetSlug() string { return v.Slug } @@ -1368,6 +1367,12 @@ func (v *projectsProjectsProject) GetSlug() string { return v.Slug } // GetDescription returns projectsProjectsProject.Description, and is useful for accessing the field via an interface. func (v *projectsProjectsProject) GetDescription() string { return v.Description } +// GetDefaultParams returns projectsProjectsProject.DefaultParams, and is useful for accessing the field via an interface. +func (v *projectsProjectsProject) GetDefaultParams() map[string]interface{} { return v.DefaultParams } + +// GetCost returns projectsProjectsProject.Cost, and is useful for accessing the field via an interface. +func (v *projectsProjectsProject) GetCost() projectsProjectsProjectCost { return v.Cost } + func (v *projectsProjectsProject) UnmarshalJSON(b []byte) error { if string(b) == "null" { @@ -1402,15 +1407,17 @@ func (v *projectsProjectsProject) UnmarshalJSON(b []byte) error { } type __premarshalprojectsProjectsProject struct { - Id string `json:"id"` - Name string `json:"name"` - DefaultParams json.RawMessage `json:"defaultParams"` + Id string `json:"id"` Slug string `json:"slug"` Description string `json:"description"` + + DefaultParams json.RawMessage `json:"defaultParams"` + + Cost projectsProjectsProjectCost `json:"cost"` } func (v *projectsProjectsProject) MarshalJSON() ([]byte, error) { @@ -1424,8 +1431,10 @@ func (v *projectsProjectsProject) MarshalJSON() ([]byte, error) { func (v *projectsProjectsProject) __premarshalJSON() (*__premarshalprojectsProjectsProject, error) { var retval __premarshalprojectsProjectsProject - retval.Id = v.Id retval.Name = v.Name + retval.Id = v.Id + retval.Slug = v.Slug + retval.Description = v.Description { dst := &retval.DefaultParams @@ -1438,11 +1447,66 @@ func (v *projectsProjectsProject) __premarshalJSON() (*__premarshalprojectsProje "unable to marshal projectsProjectsProject.DefaultParams: %w", err) } } - retval.Slug = v.Slug - retval.Description = v.Description + retval.Cost = v.Cost return &retval, nil } +// projectsProjectsProjectCost includes the requested fields of the GraphQL type Cost. +type projectsProjectsProjectCost struct { + Monthly projectsProjectsProjectCostMonthlySummary `json:"monthly"` + Daily projectsProjectsProjectCostDailySummary `json:"daily"` +} + +// GetMonthly returns projectsProjectsProjectCost.Monthly, and is useful for accessing the field via an interface. +func (v *projectsProjectsProjectCost) GetMonthly() projectsProjectsProjectCostMonthlySummary { + return v.Monthly +} + +// GetDaily returns projectsProjectsProjectCost.Daily, and is useful for accessing the field via an interface. +func (v *projectsProjectsProjectCost) GetDaily() projectsProjectsProjectCostDailySummary { + return v.Daily +} + +// projectsProjectsProjectCostDailySummary includes the requested fields of the GraphQL type Summary. +type projectsProjectsProjectCostDailySummary struct { + Average projectsProjectsProjectCostDailySummaryAverageCostSample `json:"average"` +} + +// GetAverage returns projectsProjectsProjectCostDailySummary.Average, and is useful for accessing the field via an interface. +func (v *projectsProjectsProjectCostDailySummary) GetAverage() projectsProjectsProjectCostDailySummaryAverageCostSample { + return v.Average +} + +// projectsProjectsProjectCostDailySummaryAverageCostSample includes the requested fields of the GraphQL type CostSample. +type projectsProjectsProjectCostDailySummaryAverageCostSample struct { + Amount float64 `json:"amount"` +} + +// GetAmount returns projectsProjectsProjectCostDailySummaryAverageCostSample.Amount, and is useful for accessing the field via an interface. +func (v *projectsProjectsProjectCostDailySummaryAverageCostSample) GetAmount() float64 { + return v.Amount +} + +// projectsProjectsProjectCostMonthlySummary includes the requested fields of the GraphQL type Summary. +type projectsProjectsProjectCostMonthlySummary struct { + Average projectsProjectsProjectCostMonthlySummaryAverageCostSample `json:"average"` +} + +// GetAverage returns projectsProjectsProjectCostMonthlySummary.Average, and is useful for accessing the field via an interface. +func (v *projectsProjectsProjectCostMonthlySummary) GetAverage() projectsProjectsProjectCostMonthlySummaryAverageCostSample { + return v.Average +} + +// projectsProjectsProjectCostMonthlySummaryAverageCostSample includes the requested fields of the GraphQL type CostSample. +type projectsProjectsProjectCostMonthlySummaryAverageCostSample struct { + Amount float64 `json:"amount"` +} + +// GetAmount returns projectsProjectsProjectCostMonthlySummaryAverageCostSample.Amount, and is useful for accessing the field via an interface. +func (v *projectsProjectsProjectCostMonthlySummaryAverageCostSample) GetAmount() float64 { + return v.Amount +} + // projectsResponse is returned by projects on success. type projectsResponse struct { Projects []projectsProjectsProject `json:"projects"` @@ -1947,11 +2011,23 @@ func getProjectById( const projects_Operation = ` query projects ($organizationId: ID!) { projects(organizationId: $organizationId) { - id name - defaultParams + id slug description + defaultParams + cost { + monthly { + average { + amount + } + } + daily { + average { + amount + } + } + } } } `