Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v13] Add GCP Join Method #26165

Merged
merged 2 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/testplan.md
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ connectors are accepted, invalid are rejected with sensible error messages.
[Docs](https://goteleport.com/docs/management/guides/joining-nodes-azure/)
- [ ] Join a Teleport node running in an Azure VM

### GCP Node Joining
- [ ] Join a Teleport node running in a GCP VM.

### Cloud Labels
- [ ] Create an EC2 instance with [tags in instance metadata enabled](https://goteleport.com/docs/management/guides/ec2-tags/)
and with tag `foo`: `bar`. Verify that a node running on the instance has label
Expand Down
22 changes: 22 additions & 0 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,8 @@ message ProvisionTokenSpecV2 {
ProvisionTokenSpecV2Azure Azure = 11 [(gogoproto.jsontag) = "azure,omitempty"];
// GitLab allows the configuration of options specific to the "gitlab" join method.
ProvisionTokenSpecV2GitLab GitLab = 12 [(gogoproto.jsontag) = "gitlab,omitempty"];
// GCP allows the configuration of options specific to the "gcp" join method.
ProvisionTokenSpecV2GCP GCP = 13 [(gogoproto.jsontag) = "gcp,omitempty"];
}

// ProvisionTokenSpecV2Github contains the GitHub-specific part of the
Expand Down Expand Up @@ -1281,6 +1283,26 @@ message ProvisionTokenSpecV2Azure {
repeated Rule Allow = 1 [(gogoproto.jsontag) = "allow,omitempty"];
}

// ProvisionTokenSpecV2GCP contains the GCP-specific part of the
// ProvisionTokenSpecV2.
message ProvisionTokenSpecV2GCP {
// Rule is a set of properties the GCP-ussued token might have to be allowed
// to use this ProvisionToken.
message Rule {
// ProjectIDs is a list of project IDs (e.g. "<example-id-123456>").
repeated string ProjectIDs = 1 [(gogoproto.jsontag) = "project_ids,omitempty"];
// Locations is a list of regions (e.g. "us-west1") and/or zones (e.g.
// "us-west1-b").
repeated string Locations = 2 [(gogoproto.jsontag) = "locations,omitempty"];
// ServiceAccounts is a list of service account emails (e.g.
// "<project-number>-compute@developer.gserviceaccount.com").
repeated string ServiceAccounts = 3 [(gogoproto.jsontag) = "service_accounts,omitempty"];
}
// Allow is a list of Rules, nodes using this token must match one
// allow rule to use this token.
repeated Rule Allow = 1 [(gogoproto.jsontag) = "allow,omitempty"];
}

// StaticTokensV2 implements the StaticTokens interface.
message StaticTokensV2 {
option (gogoproto.goproto_stringer) = false;
Expand Down
30 changes: 30 additions & 0 deletions api/types/provisioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ const (
// join method. Documentation regarding implementation of this
// can be found in lib/gitlab
JoinMethodGitLab JoinMethod = "gitlab"
// JoinMethodGCP indicates that the node will join with the GCP join method.
// Documentation regarding implementation of this can be found in lib/gcp.
JoinMethodGCP JoinMethod = "gcp"
)

var JoinMethods = []JoinMethod{
Expand All @@ -70,6 +73,7 @@ var JoinMethods = []JoinMethod{
JoinMethodKubernetes,
JoinMethodAzure,
JoinMethodGitLab,
JoinMethodGCP,
}

func ValidateJoinMethod(method JoinMethod) error {
Expand Down Expand Up @@ -283,6 +287,17 @@ func (p *ProvisionTokenV2) CheckAndSetDefaults() error {
if err := providerCfg.checkAndSetDefaults(); err != nil {
return trace.Wrap(err)
}
case JoinMethodGCP:
providerCfg := p.Spec.GCP
if providerCfg == nil {
return trace.BadParameter(
`"gcp" configuration must be provided for the join method %q`,
JoinMethodGCP,
)
}
if err := providerCfg.checkAndSetDefaults(); err != nil {
return trace.Wrap(err)
}
default:
return trace.BadParameter("unknown join method %q", p.Spec.JoinMethod)
}
Expand Down Expand Up @@ -613,3 +628,18 @@ func (a *ProvisionTokenSpecV2GitLab) checkAndSetDefaults() error {
}
return nil
}

func (a *ProvisionTokenSpecV2GCP) checkAndSetDefaults() error {
if len(a.Allow) == 0 {
return trace.BadParameter("the %q join method requires at least one token allow rule", JoinMethodGCP)
}
for _, allowRule := range a.Allow {
if len(allowRule.ProjectIDs) == 0 {
return trace.BadParameter(
"the %q join method requires gcp allow rules with at least one project ID",
JoinMethodGCP,
)
}
}
return nil
}
60 changes: 60 additions & 0 deletions api/types/provisioning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,66 @@ func TestProvisionTokenV2_CheckAndSetDefaults(t *testing.T) {
},
expectedErr: &trace.BadParameterError{},
},
{
desc: "gcp method",
token: &ProvisionTokenV2{
Metadata: Metadata{
Name: "test",
},
Spec: ProvisionTokenSpecV2{
Roles: []SystemRole{RoleNode},
JoinMethod: "gcp",
GCP: &ProvisionTokenSpecV2GCP{
Allow: []*ProvisionTokenSpecV2GCP_Rule{
{
ProjectIDs: []string{"p1"},
Locations: []string{"us-west1-b"},
},
},
},
},
},
expected: &ProvisionTokenV2{
Kind: "token",
Version: "v2",
Metadata: Metadata{
Name: "test",
Namespace: "default",
},
Spec: ProvisionTokenSpecV2{
Roles: []SystemRole{RoleNode},
JoinMethod: "gcp",
GCP: &ProvisionTokenSpecV2GCP{
Allow: []*ProvisionTokenSpecV2GCP_Rule{
{
ProjectIDs: []string{"p1"},
Locations: []string{"us-west1-b"},
},
},
},
},
},
},
{
desc: "gcp method no project ids",
token: &ProvisionTokenV2{
Metadata: Metadata{
Name: "test",
},
Spec: ProvisionTokenSpecV2{
Roles: []SystemRole{RoleNode},
JoinMethod: "gcp",
GCP: &ProvisionTokenSpecV2GCP{
Allow: []*ProvisionTokenSpecV2GCP_Rule{
{
Locations: []string{"us-west1-b"},
},
},
},
},
},
expectedErr: &trace.BadParameterError{},
},
}

for _, tc := range testcases {
Expand Down