Skip to content

feat: add --prices flag to server plans command#633

Merged
kangasta merged 20 commits intoUpCloudLtd:mainfrom
mgajda:feat/budget-planning
Jan 14, 2026
Merged

feat: add --prices flag to server plans command#633
kangasta merged 20 commits intoUpCloudLtd:mainfrom
mgajda:feat/budget-planning

Conversation

@mgajda
Copy link
Copy Markdown
Contributor

@mgajda mgajda commented Dec 15, 2025

Implements cost calculation features for capacity planning and budgeting.

Features:

  • Add --pricing flag to display hourly pricing for server plans in a given zone
  • Add --pricing-duration flag with standard Go duration format (1h, 24h, 720h) or a number of months 1m, 3m, 12m
  • Dynamic cost calculation based on requested duration and UpWork pricing policy (at least 1h billed, at most 28 days in a month)
  • Human-friendly column headers (per hour/day/week/month/year)
  • Fallback to component pricing when specific plan prices unavailable

This helps users with:

  • Budget planning for infrastructure costs
  • Comparing costs across different plan types
  • Capacity planning with cost visibility
  • Multi-period cost projections

Examples:

  • hourly pricing in Warsaw, Poland:
    upctl server plans --pricing pl-waw1
    
  • daily pricing in Helsinki 1 zone
    upctl server plans --pricing fi-hel1 --pricing-duration 24h
    
  • monthly pricing in Helsinki 2 zone (~30 days, but price for 28 days)
    upctl server plans --pricing fi-hel2 --pricing-duration 720h
    

Related to #339 (billing/budget visibility)

@mgajda mgajda requested a review from a team as a code owner December 15, 2025 07:50
@mgajda
Copy link
Copy Markdown
Contributor Author

mgajda commented Dec 29, 2025

@kangasta This is independent of #606, but improves budgeting.

Copy link
Copy Markdown
Member

@kangasta kangasta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR! Added few comments about the arguments and calculations, didn't yet go through the rest of the getPlanCost function 👀

Comment thread internal/commands/server/plan_list.go Outdated
Comment thread internal/commands/server/plan_list.go Outdated
Comment thread internal/commands/server/plan_list.go Outdated
Comment thread internal/commands/server/plan_list.go Outdated
mgajda added a commit to mgajda/upcloud-cli that referenced this pull request Dec 31, 2025
Based on Toni's review on PR UpCloudLtd#633:
- Changed --cost flag to --pricing with zone parameter
- Renamed --duration to --pricing-duration with support for named values (hourly, monthly)
- Made 'monthly' the default pricing duration to align with GUI/marketing
- Simplified header generation - only special cases for hourly/monthly
- Fixed billing calculation to use math.Ceil() for per-hour billing

The command now works like:
  upctl server plans --pricing de-fra1 --pricing-duration monthly
  upctl server plans --pricing de-fra1 --pricing-duration hourly
  upctl server plans --pricing de-fra1 --pricing-duration 168h
@mgajda
Copy link
Copy Markdown
Contributor Author

mgajda commented Dec 31, 2025

Thank you for the PR! Added few comments about the arguments and calculations, didn't yet go through the rest of the getPlanCost function 👀

Thank you! I have addressed the comments and reduced the added code.

Comment thread internal/commands/server/plan_list.go Outdated
Comment thread internal/commands/server/plan_list.go Outdated
Comment thread internal/commands/server/plan_list.go Outdated
mgajda added 8 commits January 4, 2026 19:04
Implements cost calculation features for capacity planning and budgeting.

Features:
- Add --cost flag to display hourly pricing for server plans
- Add --duration flag with standard Go duration format (1h, 24h, 720h)
- Dynamic cost calculation based on requested duration
- Intelligent column headers (per hour/day/week/month/year)
- Fallback to component pricing when specific plan prices unavailable

This helps users with:
- Budget planning for infrastructure costs
- Comparing costs across different plan types
- Capacity planning with cost visibility
- Multi-period cost projections

Examples:
  upctl server plans --cost                  # hourly pricing
  upctl server plans --cost --duration 24h   # daily pricing
  upctl server plans --cost --duration 720h  # monthly (~30 days)

Related to UpCloudLtd#339 (billing/budget visibility)
Based on Toni's review on PR UpCloudLtd#633:
- Changed --cost flag to --pricing with zone parameter
- Renamed --duration to --pricing-duration with support for named values (hourly, monthly)
- Made 'monthly' the default pricing duration to align with GUI/marketing
- Simplified header generation - only special cases for hourly/monthly
- Fixed billing calculation to use math.Ceil() for per-hour billing

The command now works like:
  upctl server plans --pricing de-fra1 --pricing-duration monthly
  upctl server plans --pricing de-fra1 --pricing-duration hourly
  upctl server plans --pricing de-fra1 --pricing-duration 168h
- Remove special "hourly" and "monthly" keywords - use 1h and 1m instead
- Support month-based durations: 1m, 3m, 12m etc.
- Default to 1m (one month) for pricing-duration
- Simplify header formatting: "Price (per N months)" for all month durations
- Keep special cases only for 1h (per hour) and 24h (per day)

This makes the interface more consistent and predictable.
UpCloud bills servers for a maximum of 28 days per month as per their pricing policy.
Updated monthly duration calculations to use 28 days instead of 30 days.

- Changed month calculation from 30 to 28 days per month
- Fixed nil pointer issue when GetPriceZones returns nil
- Added validation that --pricing-duration requires --pricing zone
- Added comprehensive tests for sub-hour duration billing (rounds up to full hour)
- Added tests to verify 6 months = 6*28*24 hours
- Confirmed billing is per hour (rounded up to next full hour)

Addresses review comment from @kangasta
Added support for 'hourly' and 'monthly' keywords in the --pricing-duration flag
as requested by reviewer. These provide more intuitive options for users:
- 'hourly' maps to 1 hour duration
- 'monthly' maps to 28 days (UpCloud billing month)

The existing duration format support (1h, 24h, 1m, 3m, etc.) is retained
for flexibility. Updated tests to cover the new keywords.
- Added constants for 'hourly' and 'monthly' strings (goconst)
- Converted if-else chains to switch statements (gocritic)
- Fixed staticcheck issue with tagged switch in tests

Resolves all golangci-lint errors from CI pipeline.
Comment thread internal/commands/server/plan_list.go
Comment thread internal/commands/server/plan_list.go
Comment thread internal/commands/server/plan_list.go Outdated
Comment thread internal/commands/server/plan_list.go Outdated
Correct the priceField.

Co-authored-by: Toni Kangas <kangasta@users.noreply.github.com>
Comment thread internal/commands/server/plan_list.go Outdated
@kangasta kangasta added the blocked Can not proceed until something else has been resolved. label Jan 9, 2026
Comment thread go.mod Outdated
@kangasta kangasta self-assigned this Jan 13, 2026
@kangasta kangasta changed the title feat: Add budget planning support to server plans command feat: add --pricing flag to server plans command Jan 13, 2026
@kangasta kangasta changed the title feat: add --pricing flag to server plans command feat: add --prices flag to server plans command Jan 13, 2026
Comment thread CHANGELOG.md Outdated
@kangasta kangasta removed the blocked Can not proceed until something else has been resolved. label Jan 14, 2026
@kangasta kangasta merged commit d03b2ce into UpCloudLtd:main Jan 14, 2026
8 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants