mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-24 06:59:40 -05:00
misc: skip message about community license with marketplace image
This commit is contained in:
parent
1c8a7e4c22
commit
f94c6ca0d4
@ -40,7 +40,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
"github.com/edgelesssys/constellation/v2/internal/kms/uri"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/semver"
|
"github.com/edgelesssys/constellation/v2/internal/semver"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||||
"github.com/samber/slog-multi"
|
slogmulti "github.com/samber/slog-multi"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@ -365,7 +365,7 @@ func (a *applyCmd) apply(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check license
|
// Check license
|
||||||
a.checkLicenseFile(cmd, conf.GetProvider())
|
a.checkLicenseFile(cmd, conf.GetProvider(), conf.UseMarketplaceImage())
|
||||||
|
|
||||||
// Now start actually running the apply command
|
// Now start actually running the apply command
|
||||||
|
|
||||||
|
@ -22,18 +22,22 @@ import (
|
|||||||
// with the license server. If no license file is present or if errors
|
// with the license server. If no license file is present or if errors
|
||||||
// occur during the check, the user is informed and the community license
|
// occur during the check, the user is informed and the community license
|
||||||
// is used. It is a no-op in the open source version of Constellation.
|
// is used. It is a no-op in the open source version of Constellation.
|
||||||
func (a *applyCmd) checkLicenseFile(cmd *cobra.Command, csp cloudprovider.Provider) {
|
func (a *applyCmd) checkLicenseFile(cmd *cobra.Command, csp cloudprovider.Provider, useMarketplaceImage bool) {
|
||||||
var licenseID string
|
var licenseID string
|
||||||
a.log.Debug("Running license check")
|
a.log.Debug("Running license check")
|
||||||
|
|
||||||
readBytes, err := a.fileHandler.Read(constants.LicenseFilename)
|
readBytes, err := a.fileHandler.Read(constants.LicenseFilename)
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
switch {
|
||||||
cmd.Printf("Using community license.\n")
|
case useMarketplaceImage:
|
||||||
|
cmd.Println("Using marketplace image billing.")
|
||||||
|
licenseID = license.MarketplaceLicense
|
||||||
|
case errors.Is(err, fs.ErrNotExist):
|
||||||
|
cmd.Println("Using community license.")
|
||||||
licenseID = license.CommunityLicense
|
licenseID = license.CommunityLicense
|
||||||
} else if err != nil {
|
case err != nil:
|
||||||
cmd.Printf("Error: %v\nContinuing with community license.\n", err)
|
cmd.Printf("Error: %v\nContinuing with community license.\n", err)
|
||||||
licenseID = license.CommunityLicense
|
licenseID = license.CommunityLicense
|
||||||
} else {
|
default:
|
||||||
cmd.Printf("Constellation license found!\n")
|
cmd.Printf("Constellation license found!\n")
|
||||||
licenseID, err = license.FromBytes(readBytes)
|
licenseID, err = license.FromBytes(readBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -43,9 +47,11 @@ func (a *applyCmd) checkLicenseFile(cmd *cobra.Command, csp cloudprovider.Provid
|
|||||||
}
|
}
|
||||||
|
|
||||||
quota, err := a.applier.CheckLicense(cmd.Context(), csp, !a.flags.skipPhases.contains(skipInitPhase), licenseID)
|
quota, err := a.applier.CheckLicense(cmd.Context(), csp, !a.flags.skipPhases.contains(skipInitPhase), licenseID)
|
||||||
if err != nil {
|
if err != nil && !useMarketplaceImage {
|
||||||
cmd.Printf("Unable to contact license server.\n")
|
cmd.Printf("Unable to contact license server.\n")
|
||||||
cmd.Printf("Please keep your vCPU quota in mind.\n")
|
cmd.Printf("Please keep your vCPU quota in mind.\n")
|
||||||
|
} else if licenseID == license.MarketplaceLicense {
|
||||||
|
// Do nothing. Billing is handled by the marketplace.
|
||||||
} else if licenseID == license.CommunityLicense {
|
} else if licenseID == license.CommunityLicense {
|
||||||
cmd.Printf("For details, see https://docs.edgeless.systems/constellation/overview/license\n")
|
cmd.Printf("For details, see https://docs.edgeless.systems/constellation/overview/license\n")
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,4 +17,4 @@ import (
|
|||||||
// with the license server. If no license file is present or if errors
|
// with the license server. If no license file is present or if errors
|
||||||
// occur during the check, the user is informed and the community license
|
// occur during the check, the user is informed and the community license
|
||||||
// is used. It is a no-op in the open source version of Constellation.
|
// is used. It is a no-op in the open source version of Constellation.
|
||||||
func (a *applyCmd) checkLicenseFile(*cobra.Command, cloudprovider.Provider) {}
|
func (a *applyCmd) checkLicenseFile(*cobra.Command, cloudprovider.Provider, bool) {}
|
||||||
|
@ -720,7 +720,8 @@ func (c *Config) DeployYawolLoadBalancer() bool {
|
|||||||
func (c *Config) UseMarketplaceImage() bool {
|
func (c *Config) UseMarketplaceImage() bool {
|
||||||
return (c.Provider.Azure != nil && c.Provider.Azure.UseMarketplaceImage != nil && *c.Provider.Azure.UseMarketplaceImage) ||
|
return (c.Provider.Azure != nil && c.Provider.Azure.UseMarketplaceImage != nil && *c.Provider.Azure.UseMarketplaceImage) ||
|
||||||
(c.Provider.GCP != nil && c.Provider.GCP.UseMarketplaceImage != nil && *c.Provider.GCP.UseMarketplaceImage) ||
|
(c.Provider.GCP != nil && c.Provider.GCP.UseMarketplaceImage != nil && *c.Provider.GCP.UseMarketplaceImage) ||
|
||||||
(c.Provider.AWS != nil && c.Provider.AWS.UseMarketplaceImage != nil && *c.Provider.AWS.UseMarketplaceImage)
|
(c.Provider.AWS != nil && c.Provider.AWS.UseMarketplaceImage != nil && *c.Provider.AWS.UseMarketplaceImage) ||
|
||||||
|
(c.Provider.OpenStack != nil && c.Provider.OpenStack.Cloud == "stackit")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate checks the config values and returns validation errors.
|
// Validate checks the config values and returns validation errors.
|
||||||
|
@ -131,6 +131,9 @@ func buildMarketplaceImage(payload marketplaceImagePayload) (string, error) {
|
|||||||
case cloudprovider.AWS:
|
case cloudprovider.AWS:
|
||||||
// For AWS, we use the AMI alias, which just needs the version and infers the rest transparently.
|
// For AWS, we use the AMI alias, which just needs the version and infers the rest transparently.
|
||||||
return fmt.Sprintf("resolve:ssm:/aws/service/marketplace/prod-77ylkenlkgufs/%s", payload.imgInfo.Version), nil
|
return fmt.Sprintf("resolve:ssm:/aws/service/marketplace/prod-77ylkenlkgufs/%s", payload.imgInfo.Version), nil
|
||||||
|
case cloudprovider.OpenStack:
|
||||||
|
// For OpenStack / STACKIT, we use the image reference directly.
|
||||||
|
return getReferenceFromImageInfo(payload.provider, payload.attestationVariant.String(), payload.imgInfo, payload.filters...)
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("marketplace images are not supported for csp %s", payload.provider.String())
|
return "", fmt.Errorf("marketplace images are not supported for csp %s", payload.provider.String())
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ type Action string
|
|||||||
const (
|
const (
|
||||||
// CommunityLicense is used by everyone who has not bought an enterprise license.
|
// CommunityLicense is used by everyone who has not bought an enterprise license.
|
||||||
CommunityLicense = "00000000-0000-0000-0000-000000000000"
|
CommunityLicense = "00000000-0000-0000-0000-000000000000"
|
||||||
|
// MarketplaceLicense is used by everyone who uses a marketplace image.
|
||||||
|
MarketplaceLicense = "11111111-1111-1111-1111-111111111111"
|
||||||
|
|
||||||
// Init action denotes the initialization of a Constellation cluster.
|
// Init action denotes the initialization of a Constellation cluster.
|
||||||
Init Action = "init"
|
Init Action = "init"
|
||||||
|
@ -58,6 +58,10 @@ Required:
|
|||||||
- `$SEMANTIC_VERSION` is the semantic version of the image, e.g. `vX.Y.Z` or `vX.Y.Z-pre...`.
|
- `$SEMANTIC_VERSION` is the semantic version of the image, e.g. `vX.Y.Z` or `vX.Y.Z-pre...`.
|
||||||
- `version` (String) Semantic version of the image.
|
- `version` (String) Semantic version of the image.
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- `marketplace_image` (Boolean) Whether a marketplace image should be used.
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--attestation"></a>
|
<a id="nestedatt--attestation"></a>
|
||||||
### Nested Schema for `attestation`
|
### Nested Schema for `attestation`
|
||||||
|
@ -49,6 +49,10 @@ The Constellation OS image must be [replicated to the region](https://docs.edgel
|
|||||||
<a id="nestedatt--image"></a>
|
<a id="nestedatt--image"></a>
|
||||||
### Nested Schema for `image`
|
### Nested Schema for `image`
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- `marketplace_image` (Boolean) Whether a marketplace image should be used.
|
||||||
|
|
||||||
Read-Only:
|
Read-Only:
|
||||||
|
|
||||||
- `reference` (String) CSP-specific unique reference to the image. The format differs per CSP.
|
- `reference` (String) CSP-specific unique reference to the image. The format differs per CSP.
|
||||||
|
@ -162,6 +162,10 @@ Required:
|
|||||||
- `$SEMANTIC_VERSION` is the semantic version of the image, e.g. `vX.Y.Z` or `vX.Y.Z-pre...`.
|
- `$SEMANTIC_VERSION` is the semantic version of the image, e.g. `vX.Y.Z` or `vX.Y.Z-pre...`.
|
||||||
- `version` (String) Semantic version of the image.
|
- `version` (String) Semantic version of the image.
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- `marketplace_image` (Boolean) Whether a marketplace image should be used.
|
||||||
|
|
||||||
|
|
||||||
<a id="nestedatt--network_config"></a>
|
<a id="nestedatt--network_config"></a>
|
||||||
### Nested Schema for `network_config`
|
### Nested Schema for `network_config`
|
||||||
|
@ -447,28 +447,31 @@ func (r *ClusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPla
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
licenseID := plannedState.LicenseID.ValueString()
|
|
||||||
if licenseID == "" {
|
|
||||||
resp.Diagnostics.AddWarning("Constellation license ID not set.",
|
|
||||||
"Continuing with community license.")
|
|
||||||
}
|
|
||||||
if licenseID == license.CommunityLicense {
|
|
||||||
resp.Diagnostics.AddWarning("Using community license.",
|
|
||||||
"For details, see https://docs.edgeless.systems/constellation/overview/license")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate during plan. Must be done in ModifyPlan to read provider data.
|
// Validate during plan. Must be done in ModifyPlan to read provider data.
|
||||||
// See https://developer.hashicorp.com/terraform/plugin/framework/resources/configure#define-resource-configure-method.
|
// See https://developer.hashicorp.com/terraform/plugin/framework/resources/configure#define-resource-configure-method.
|
||||||
_, diags := r.getMicroserviceVersion(&plannedState)
|
_, diags := r.getMicroserviceVersion(&plannedState)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
_, _, diags = r.getImageVersion(ctx, &plannedState)
|
var image imageAttribute
|
||||||
|
image, _, diags = r.getImageVersion(ctx, &plannedState)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
licenseID := plannedState.LicenseID.ValueString()
|
||||||
|
switch {
|
||||||
|
case image.MarketplaceImage != nil && *image.MarketplaceImage:
|
||||||
|
// Marketplace images do not require a license.
|
||||||
|
case licenseID == "":
|
||||||
|
resp.Diagnostics.AddWarning("Constellation license ID not set.",
|
||||||
|
"Continuing with community license.")
|
||||||
|
case licenseID == license.CommunityLicense:
|
||||||
|
resp.Diagnostics.AddWarning("Using community license.",
|
||||||
|
"For details, see https://docs.edgeless.systems/constellation/overview/license")
|
||||||
|
}
|
||||||
|
|
||||||
// Checks running on updates to the resource. (i.e. state and plan != nil)
|
// Checks running on updates to the resource. (i.e. state and plan != nil)
|
||||||
if !req.State.Raw.IsNull() {
|
if !req.State.Raw.IsNull() {
|
||||||
// Read currentState supplied by Terraform runtime into the model
|
// Read currentState supplied by Terraform runtime into the model
|
||||||
@ -759,9 +762,13 @@ func (r *ClusterResource) apply(ctx context.Context, data *ClusterResourceModel,
|
|||||||
|
|
||||||
// parse license ID
|
// parse license ID
|
||||||
licenseID := data.LicenseID.ValueString()
|
licenseID := data.LicenseID.ValueString()
|
||||||
if licenseID == "" {
|
switch {
|
||||||
|
case image.MarketplaceImage != nil && *image.MarketplaceImage:
|
||||||
|
licenseID = license.MarketplaceLicense
|
||||||
|
case licenseID == "":
|
||||||
licenseID = license.CommunityLicense
|
licenseID = license.CommunityLicense
|
||||||
}
|
}
|
||||||
|
|
||||||
// license ID can be base64-encoded
|
// license ID can be base64-encoded
|
||||||
licenseIDFromB64, err := base64.StdEncoding.DecodeString(licenseID)
|
licenseIDFromB64, err := base64.StdEncoding.DecodeString(licenseID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -97,9 +97,10 @@ func TestViolatedImageConstraint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input, diags := basetypes.NewObjectValueFrom(context.Background(), map[string]attr.Type{
|
input, diags := basetypes.NewObjectValueFrom(context.Background(), map[string]attr.Type{
|
||||||
"version": basetypes.StringType{},
|
"version": basetypes.StringType{},
|
||||||
"reference": basetypes.StringType{},
|
"reference": basetypes.StringType{},
|
||||||
"short_path": basetypes.StringType{},
|
"short_path": basetypes.StringType{},
|
||||||
|
"marketplace_image": basetypes.BoolType{},
|
||||||
}, img)
|
}, img)
|
||||||
require.Equal(t, 0, diags.ErrorsCount())
|
require.Equal(t, 0, diags.ErrorsCount())
|
||||||
_, _, diags2 := sut.getImageVersion(context.Background(), &ClusterResourceModel{
|
_, _, diags2 := sut.getImageVersion(context.Background(), &ClusterResourceModel{
|
||||||
|
@ -229,13 +229,19 @@ func newImageAttributeSchema(t attributeType) schema.Attribute {
|
|||||||
Computed: !isInput,
|
Computed: !isInput,
|
||||||
Required: isInput,
|
Required: isInput,
|
||||||
},
|
},
|
||||||
|
"marketplace_image": schema.BoolAttribute{
|
||||||
|
Description: "Whether a marketplace image should be used.",
|
||||||
|
MarkdownDescription: "Whether a marketplace image should be used.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// imageAttribute is the image attribute's data model.
|
// imageAttribute is the image attribute's data model.
|
||||||
type imageAttribute struct {
|
type imageAttribute struct {
|
||||||
Reference string `tfsdk:"reference"`
|
Reference string `tfsdk:"reference"`
|
||||||
Version string `tfsdk:"version"`
|
Version string `tfsdk:"version"`
|
||||||
ShortPath string `tfsdk:"short_path"`
|
ShortPath string `tfsdk:"short_path"`
|
||||||
|
MarketplaceImage *bool `tfsdk:"marketplace_image"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user