Introduce ORCHARD_LICENSE_TIER environment variable (#111)

* Introduce ORCHARD_LICENSE_TIER environment variable

* Only parse ORCHARD_LICENSE_TIER if it was provided
This commit is contained in:
Nikolay Edigaryev 2023-07-26 17:28:38 +04:00 committed by GitHub
parent a52c205c34
commit fd88ce5890
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 6 deletions

View File

@ -72,8 +72,9 @@ Orchard Controller instance is secured by default and all API calls are authenti
In addition to controlling the Orchard via the CLI arguments, there are environment variables that may be beneficial both when automating Orchard and in daily use:
| Variable name | Description |
|---------------------------------|----------------------------------------------------------------------------------------------------------------------|
|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ORCHARD_HOME` | Override Orchard's home directory. Useful when running multiple Orchard instances on the same host and when testing. |
| `ORCHARD_LICENSE_TIER` | The default license limit only allows connecting 4 Orchard Workers to the Orchard Controller. If you've purchased a [Gold Tier License](https://tart.run/licensing/), set this variable to `gold` to increase the limit to 20 Orchard Workers. And if you've purchased a [Platinum Tier License](https://tart.run/licensing/), set this variable to `platinum` to increase the limit to 200 Orchard Workers. |
| `ORCHARD_SERVICE_ACCOUNT_NAME` | Override service account name (used for controller API auth) on per-command basis |
| `ORCHARD_SERVICE_ACCOUNT_TOKEN` | Override service account token (used for controller API auth) on per-command basis |
| `ORCHARD_URL` | Override controller URL on per-command basis |

View File

@ -44,6 +44,19 @@ func (controller *Controller) createWorker(ctx *gin.Context) responder.Responder
NewErrorResponse("this worker is managed from a different machine ID, "+
"delete this worker first to be able to re-create it"))
}
if errors.Is(err, storepkg.ErrNotFound) {
// We will be adding a new worker, check if the license capacity allows that
workers, err := txn.ListWorkers()
if err != nil {
return responder.Code(http.StatusInternalServerError)
}
if uint(len(workers)+1) > controller.maxWorkersPerLicense {
return responder.JSON(http.StatusConflict, NewErrorResponse("cannot register a new worker "+
"because the license capacity of %d workers has been reached, "+
"consider upgrading at https://tart.run/licensing/", controller.maxWorkersPerLicense))
}
}
if err := txn.SetWorker(worker); err != nil {
return responder.Error(err)

View File

@ -20,6 +20,7 @@ import (
"google.golang.org/grpc/keepalive"
"net"
"net/http"
"os"
"strings"
"time"
)
@ -29,6 +30,12 @@ var (
ErrAdminTaskFailed = errors.New("controller administrative task failed")
)
const (
maxWorkersPerDefaultLicense = 4
maxWorkersPerGoldLicense = 20
maxWorkersPerPlatinumLicense = 200
)
type Controller struct {
dataDir *DataDir
listenAddr string
@ -44,6 +51,7 @@ type Controller struct {
proxy *proxy.Proxy
enableSwaggerDocs bool
workerOfflineTimeout time.Duration
maxWorkersPerLicense uint
rpc.UnimplementedControllerServer
}
@ -53,6 +61,7 @@ func New(opts ...Option) (*Controller, error) {
workerNotifier: notifier.NewNotifier(),
proxy: proxy.NewProxy(),
workerOfflineTimeout: 3 * time.Minute,
maxWorkersPerLicense: maxWorkersPerDefaultLicense,
}
// Apply options
@ -60,6 +69,20 @@ func New(opts ...Option) (*Controller, error) {
opt(controller)
}
// Apply environment variables
orchardLicenseTier, ok := os.LookupEnv("ORCHARD_LICENSE_TIER")
if ok {
switch orchardLicenseTier {
case "gold":
controller.maxWorkersPerLicense = maxWorkersPerGoldLicense
case "platinum":
controller.maxWorkersPerLicense = maxWorkersPerPlatinumLicense
default:
return nil, fmt.Errorf("%w: invalid ORCHARD_LICENSE_TIER value: %q",
ErrInitFailed, orchardLicenseTier)
}
}
// Apply defaults
if controller.dataDir == nil {
return nil, fmt.Errorf("%w: please specify the data directory path with WithDataDir()",