Skip to content

Commit

Permalink
simplified parsing target_link for the hvn route resource
Browse files Browse the repository at this point in the history
  • Loading branch information
smaant committed May 20, 2021
1 parent 4bd2115 commit 0c9c24e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
15 changes: 12 additions & 3 deletions internal/provider/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,27 @@ func linkURL(l *sharedmodels.HashicorpCloudLocationLink) (string, error) {
// parseLinkURL parses a link URL into a link. If the URL is malformed, an
// error is returned.
//
// If `expectedType` is provided it will be matched against the resource from
// the URL and if they don't much function returns an error. If `expectedType`
// is an empty string then the resource type just will be inferred from the URL
// as is.
//
// The resulting link location does not include an organization, which is
// typically required for requests. If organization is needed, use
// `buildLinkFromURL()`.
func parseLinkURL(urn string, resourceType string) (*sharedmodels.HashicorpCloudLocationLink, error) {
pattern := fmt.Sprintf("^/project/[^/]+/%s/[^/]+$", resourceType)
func parseLinkURL(urn string, expectedType string) (*sharedmodels.HashicorpCloudLocationLink, error) {
pattern := "^/project/[^/]+/[^/]+/[^/]+$"
match, _ := regexp.MatchString(pattern, urn)
if !match {
return nil, fmt.Errorf("url %q is not in the correct format: /project/{project_id}/%s/{id}", urn, resourceType)
return nil, fmt.Errorf("url %q is not in the correct format: /project/{project_id}/{resource_type}/{id}", urn)
}

components := strings.Split(urn, "/")

if expectedType != "" && expectedType != components[3] {
return nil, fmt.Errorf("url %q is not in the correct format: /project/{project_id}/%s/{id}", urn, expectedType)
}

return &sharedmodels.HashicorpCloudLocationLink{
Type: components[3],
ID: components[4],
Expand Down
14 changes: 14 additions & 0 deletions internal/provider/link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@ func Test_parseLinkURL(t *testing.T) {
require.Equal(t, id, l.ID)
})

t.Run("extracting type from the URL", func(t *testing.T) {
urn := fmt.Sprintf("/project/%s/%s/%s",
projID,
svcType,
id)

l, err := parseLinkURL(urn, "")
require.NoError(t, err)

require.Equal(t, projID, l.Location.ProjectID)
require.Equal(t, svcType, l.Type)
require.Equal(t, id, l.ID)
})

t.Run("missing project ID", func(t *testing.T) {
urn := fmt.Sprintf("/project/%s/%s/%s",
"",
Expand Down
11 changes: 3 additions & 8 deletions internal/provider/resource_hvn_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,11 @@ func resourceHvnRouteCreate(ctx context.Context, d *schema.ResourceData, meta in
}

target := d.Get("target_link").(string)
var targetLink *sharedmodels.HashicorpCloudLocationLink
// If target type is neither a peering nor a TGW attachment, we will return an error.
// Currently create HVN route will only support these two resource types.
targetLink, err = buildLinkFromURL(target, PeeringResourceType, loc.OrganizationID)
targetLink, err := parseLinkURL(target, "")
if err != nil {
targetLink, err = buildLinkFromURL(target, TgwAttachmentResourceType, loc.OrganizationID)
if err != nil {
return diag.Errorf("unable to parse target_link for HVN (%s) route with destination CIDR of %s: %v; target must be of either %s or %s", hvnLink.ID, destination, err, PeeringResourceType, TgwAttachmentResourceType)
}
return diag.Errorf("unable to parse target_link for HVN route (%s): %v", hvnRouteID, destination, err)
}
targetLink.Location.OrganizationID = loc.OrganizationID

// Check for an existing HVN.
retrievedHvn, err := clients.GetHvnByID(ctx, client, loc, hvnLink.ID)
Expand Down

0 comments on commit 0c9c24e

Please sign in to comment.