mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-02 12:06:09 -04:00
gcp: support projects with no default permissions (#3656)
* helm/gcp: use service account in operator and joinservice * helm: format operator testdata * terraform/iam: create additional service account for VMs This service account is used in the following commits and is attached to the VMs * config: pass VM service account from iam create to cluster create via config * cli/iamcreate: limit name prefix length * docs: add minimal gcp IAM permissions
This commit is contained in:
parent
83e08e3e37
commit
66815a4a47
42 changed files with 771 additions and 466 deletions
|
@ -103,9 +103,18 @@ func (c *Client) ShowIAM(ctx context.Context, provider cloudprovider.Provider) (
|
|||
if !ok {
|
||||
return IAMOutput{}, errors.New("invalid type in service_account_key output: not a string")
|
||||
}
|
||||
IAMServiceAccountVMOutputRaw, ok := tfState.Values.Outputs["service_account_mail_vm"]
|
||||
if !ok {
|
||||
return IAMOutput{}, errors.New("no service_account_mail_vm output found")
|
||||
}
|
||||
IAMServiceAccountVMOutput, ok := IAMServiceAccountVMOutputRaw.Value.(string)
|
||||
if !ok {
|
||||
return IAMOutput{}, errors.New("invalid type in service_account_mail_vm output: not a string")
|
||||
}
|
||||
return IAMOutput{
|
||||
GCP: GCPIAMOutput{
|
||||
SaKey: saKeyOutput,
|
||||
SaKey: saKeyOutput,
|
||||
ServiceAccountVMMailAddress: IAMServiceAccountVMOutput,
|
||||
},
|
||||
}, nil
|
||||
case cloudprovider.Azure:
|
||||
|
@ -539,7 +548,8 @@ type IAMOutput struct {
|
|||
|
||||
// GCPIAMOutput contains the output information of the Terraform IAM operation on GCP.
|
||||
type GCPIAMOutput struct {
|
||||
SaKey string
|
||||
SaKey string
|
||||
ServiceAccountVMMailAddress string
|
||||
}
|
||||
|
||||
// AzureIAMOutput contains the output information of the Terraform IAM operation on Microsoft Azure.
|
||||
|
|
|
@ -120,6 +120,7 @@ func TestPrepareIAM(t *testing.T) {
|
|||
Region: "europe-west1",
|
||||
Zone: "europe-west1-a",
|
||||
ServiceAccountID: "const-test-case",
|
||||
NamePrefix: "test_iam",
|
||||
}
|
||||
azureVars := &AzureIAMVariables{
|
||||
Location: "westus",
|
||||
|
@ -509,6 +510,9 @@ func TestCreateIAM(t *testing.T) {
|
|||
"service_account_key": {
|
||||
Value: "12345678_abcdefg",
|
||||
},
|
||||
"service_account_mail_vm": {
|
||||
Value: "test_iam_service_account_vm",
|
||||
},
|
||||
"subscription_id": {
|
||||
Value: "test_subscription_id",
|
||||
},
|
||||
|
@ -581,7 +585,7 @@ func TestCreateIAM(t *testing.T) {
|
|||
vars: gcpVars,
|
||||
tf: &stubTerraform{showState: newTestState()},
|
||||
fs: afero.NewMemMapFs(),
|
||||
want: IAMOutput{GCP: GCPIAMOutput{SaKey: "12345678_abcdefg"}},
|
||||
want: IAMOutput{GCP: GCPIAMOutput{SaKey: "12345678_abcdefg", ServiceAccountVMMailAddress: "test_iam_service_account_vm"}},
|
||||
},
|
||||
"gcp init fails": {
|
||||
pathBase: path.Join(constants.TerraformEmbeddedDir, "iam"),
|
||||
|
@ -614,7 +618,25 @@ func TestCreateIAM(t *testing.T) {
|
|||
tf: &stubTerraform{
|
||||
showState: &tfjson.State{
|
||||
Values: &tfjson.StateValues{
|
||||
Outputs: map[string]*tfjson.StateOutput{},
|
||||
Outputs: map[string]*tfjson.StateOutput{
|
||||
"service_account_mail_vm": {Value: "test_iam_service_account_vm"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fs: afero.NewMemMapFs(),
|
||||
wantErr: true,
|
||||
},
|
||||
"gcp no service_account_mail_vm": {
|
||||
pathBase: path.Join(constants.TerraformEmbeddedDir, "iam"),
|
||||
provider: cloudprovider.GCP,
|
||||
vars: gcpVars,
|
||||
tf: &stubTerraform{
|
||||
showState: &tfjson.State{
|
||||
Values: &tfjson.StateValues{
|
||||
Outputs: map[string]*tfjson.StateOutput{
|
||||
"service_account_key": {Value: "12345678_abcdefg"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1129,7 +1151,8 @@ func TestShowIAM(t *testing.T) {
|
|||
"GCP success": {
|
||||
tf: &stubTerraform{
|
||||
showState: getTfjsonState(map[string]any{
|
||||
"service_account_key": "key",
|
||||
"service_account_key": "key",
|
||||
"service_account_mail_vm": "example@example.com",
|
||||
}),
|
||||
},
|
||||
csp: cloudprovider.GCP,
|
||||
|
@ -1137,7 +1160,8 @@ func TestShowIAM(t *testing.T) {
|
|||
"GCP wrong data type": {
|
||||
tf: &stubTerraform{
|
||||
showState: getTfjsonState(map[string]any{
|
||||
"service_account_key": map[string]any{},
|
||||
"service_account_key": map[string]any{},
|
||||
"service_account_mail_vm": "example@example.com",
|
||||
}),
|
||||
},
|
||||
csp: cloudprovider.GCP,
|
||||
|
@ -1145,7 +1169,9 @@ func TestShowIAM(t *testing.T) {
|
|||
},
|
||||
"GCP missing key": {
|
||||
tf: &stubTerraform{
|
||||
showState: getTfjsonState(map[string]any{}),
|
||||
showState: getTfjsonState(map[string]any{
|
||||
"service_account_mail_vm": "example@example.com",
|
||||
}),
|
||||
},
|
||||
csp: cloudprovider.GCP,
|
||||
wantErr: true,
|
||||
|
|
|
@ -141,6 +141,8 @@ type GCPClusterVariables struct {
|
|||
InternalLoadBalancer bool `hcl:"internal_load_balancer" cty:"internal_load_balancer"`
|
||||
// CCTechnology is the confidential computing technology to use on the VMs. (`SEV` or `SEV_SNP`)
|
||||
CCTechnology string `hcl:"cc_technology" cty:"cc_technology"`
|
||||
// IAMServiceAccountControlPlane is the IAM service account mail address to attach to VMs.
|
||||
IAMServiceAccountVM string `hcl:"iam_service_account_vm" cty:"iam_service_account_vm"`
|
||||
// AdditionalLables are (optional) additional labels that should be applied to created resources.
|
||||
AdditionalLabels cloudprovider.Tags `hcl:"additional_labels" cty:"additional_labels"`
|
||||
}
|
||||
|
@ -182,6 +184,9 @@ type GCPIAMVariables struct {
|
|||
Zone string `hcl:"zone" cty:"zone"`
|
||||
// ServiceAccountID is the ID of the service account to use.
|
||||
ServiceAccountID string `hcl:"service_account_id" cty:"service_account_id"`
|
||||
// IAMServiceAccountVM is the ID of the service account to attach to VMs.
|
||||
// TODO(@3u13r): Eventually remove this field after v2.22 has been released.
|
||||
NamePrefix string `hcl:"name_prefix,optional" cty:"name_prefix"`
|
||||
}
|
||||
|
||||
// String returns a string representation of the IAM-specific variables, formatted as Terraform variables.
|
||||
|
|
|
@ -122,8 +122,9 @@ func TestGCPClusterVariables(t *testing.T) {
|
|||
DiskType: "pd-ssd",
|
||||
},
|
||||
},
|
||||
CustomEndpoint: "example.com",
|
||||
CCTechnology: "SEV_SNP",
|
||||
CustomEndpoint: "example.com",
|
||||
CCTechnology: "SEV_SNP",
|
||||
IAMServiceAccountVM: "example@example.com",
|
||||
}
|
||||
|
||||
// test that the variables are correctly rendered
|
||||
|
@ -151,10 +152,11 @@ node_groups = {
|
|||
zone = "eu-central-1b"
|
||||
}
|
||||
}
|
||||
custom_endpoint = "example.com"
|
||||
internal_load_balancer = false
|
||||
cc_technology = "SEV_SNP"
|
||||
additional_labels = null
|
||||
custom_endpoint = "example.com"
|
||||
internal_load_balancer = false
|
||||
cc_technology = "SEV_SNP"
|
||||
iam_service_account_vm = "example@example.com"
|
||||
additional_labels = null
|
||||
`
|
||||
got := vars.String()
|
||||
assert.Equal(t, strings.Fields(want), strings.Fields(got)) // to ignore whitespace differences
|
||||
|
@ -173,9 +175,27 @@ func TestGCPIAMVariables(t *testing.T) {
|
|||
region = "eu-central-1"
|
||||
zone = "eu-central-1a"
|
||||
service_account_id = "my-service-account"
|
||||
name_prefix = ""
|
||||
`
|
||||
got := vars.String()
|
||||
assert.Equal(t, strings.Fields(want), strings.Fields(got)) // to ignore whitespace differences
|
||||
|
||||
vars = GCPIAMVariables{
|
||||
Project: "my-project",
|
||||
Region: "eu-central-1",
|
||||
Zone: "eu-central-1a",
|
||||
NamePrefix: "my-prefix",
|
||||
}
|
||||
|
||||
// test that the variables are correctly rendered
|
||||
want = `project_id = "my-project"
|
||||
region = "eu-central-1"
|
||||
zone = "eu-central-1a"
|
||||
service_account_id = ""
|
||||
name_prefix = "my-prefix"
|
||||
`
|
||||
got = vars.String()
|
||||
assert.Equal(t, strings.Fields(want), strings.Fields(got)) // to ignore whitespace differences
|
||||
}
|
||||
|
||||
func TestAzureClusterVariables(t *testing.T) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue