@@ -11,6 +11,8 @@ import (
1111 "strings"
1212 "testing"
1313 "time"
14+ // For beta tests only
15+ "net/http"
1416
1517 "github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
1618 tpgcompute "github.com/hashicorp/terraform-provider-google-beta/google-beta/services/compute"
@@ -506,7 +508,7 @@ func NewServiceNetworkSettings(options ...func(*ServiceNetworkSettings)) *Servic
506508// That is the reason to use the shared service networking connection for test resources.
507509// https://cloud.google.com/vpc/docs/configure-private-services-access#removing-connection
508510//
509- // testId specifies the test for which a shared network and a gobal address are used/initialized.
511+ // testId specifies the test for which a shared network and a global address are used/initialized.
510512func BootstrapSharedServiceNetworkingConnection (t * testing.T , testId string , params ... func (* ServiceNetworkSettings )) string {
511513 settings := NewServiceNetworkSettings (params ... )
512514 parentService := "services/" + settings .ParentService
@@ -1434,6 +1436,316 @@ func SetupProjectsAndGetAccessToken(org, billing, pid, service string, config *t
14341436 return accessToken , nil
14351437}
14361438
1439+ // For bootstrapping Developer Connect git repository link
1440+ const SharedGitRepositoryLinkIdPrefix = "tf-bootstrap-git-repository-"
1441+
1442+ func BootstrapGitRepository (t * testing.T , gitRepositoryLinkId , location , cloneUri , parentConnectionId string ) string {
1443+ gitRepositoryLinkId = SharedGitRepositoryLinkIdPrefix + gitRepositoryLinkId
1444+
1445+ config := BootstrapConfig (t )
1446+ if config == nil {
1447+ t .Fatal ("Could not bootstrap config." )
1448+ }
1449+
1450+ log .Printf ("[DEBUG] Getting shared git repository link %q" , gitRepositoryLinkId )
1451+
1452+ getURL := fmt .Sprintf ("%sprojects/%s/locations/%s/connections/%s/gitRepositoryLinks/%s" ,
1453+ config .DeveloperConnectBasePath , config .Project , location , parentConnectionId , gitRepositoryLinkId )
1454+
1455+ headers := make (http.Header )
1456+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1457+ Config : config ,
1458+ Method : "GET" ,
1459+ Project : config .Project ,
1460+ RawURL : getURL ,
1461+ UserAgent : config .UserAgent ,
1462+ Headers : headers ,
1463+ })
1464+
1465+ if err != nil && transport_tpg .IsGoogleApiErrorWithCode (err , 404 ) {
1466+ log .Printf ("[DEBUG] Git repository link %q not found, bootstrapping" , gitRepositoryLinkId )
1467+ obj := map [string ]interface {}{
1468+ "clone_uri" : cloneUri ,
1469+ "annotations" : map [string ]string {},
1470+ }
1471+
1472+ postURL := fmt .Sprintf ("%sprojects/%s/locations/%s/connections/%s/gitRepositoryLinks?gitRepositoryLinkId=%s" ,
1473+ config .DeveloperConnectBasePath , config .Project , location , parentConnectionId , gitRepositoryLinkId )
1474+ headers := make (http.Header )
1475+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1476+ Config : config ,
1477+ Method : "POST" ,
1478+ Project : config .Project ,
1479+ RawURL : postURL ,
1480+ UserAgent : config .UserAgent ,
1481+ Body : obj ,
1482+ Timeout : 20 * time .Minute ,
1483+ Headers : headers ,
1484+ })
1485+ if err != nil {
1486+ t .Fatalf ("Error bootstrapping git repository link %q: %s" , gitRepositoryLinkId , err )
1487+ }
1488+
1489+ _ , err = transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1490+ Config : config ,
1491+ Method : "GET" ,
1492+ Project : config .Project ,
1493+ RawURL : getURL ,
1494+ UserAgent : config .UserAgent ,
1495+ Timeout : 20 * time .Minute ,
1496+ Headers : headers ,
1497+ })
1498+ if err != nil {
1499+ t .Fatalf ("Error getting git repository link %q: %s" , gitRepositoryLinkId , err )
1500+ }
1501+ }
1502+
1503+ return gitRepositoryLinkId
1504+ }
1505+
1506+ const SharedConnectionIdPrefix = "tf-bootstrap-developer-connect-connection-"
1507+
1508+ // For bootstrapping Developer Connect connection resources
1509+ func BootstrapDeveloperConnection (t * testing.T , connectionId , location , tokenResource string , appInstallationId int ) string {
1510+ connectionId = SharedConnectionIdPrefix + connectionId
1511+
1512+ config := BootstrapConfig (t )
1513+ if config == nil {
1514+ t .Fatal ("Could not bootstrap config." )
1515+ }
1516+
1517+ log .Printf ("[DEBUG] Getting shared developer connection %q" , connectionId )
1518+
1519+ getURL := fmt .Sprintf ("%sprojects/%s/locations/%s/connections/%s" ,
1520+ config .DeveloperConnectBasePath , config .Project , location , connectionId )
1521+
1522+ headers := make (http.Header )
1523+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1524+ Config : config ,
1525+ Method : "GET" ,
1526+ Project : config .Project ,
1527+ RawURL : getURL ,
1528+ UserAgent : config .UserAgent ,
1529+ Headers : headers ,
1530+ })
1531+
1532+ if err != nil {
1533+ log .Printf ("[DEBUG] Developer connection %q not found, bootstrapping" , connectionId )
1534+ authorizerCredential := map [string ]string {
1535+ "oauth_token_secret_version" : tokenResource ,
1536+ }
1537+ githubConfig := map [string ]interface {}{
1538+ "github_app" : "DEVELOPER_CONNECT" ,
1539+ "app_installation_id" : appInstallationId ,
1540+ "authorizer_credential" : authorizerCredential ,
1541+ }
1542+ obj := map [string ]interface {}{
1543+ "disabled" : false ,
1544+ "github_config" : githubConfig ,
1545+ }
1546+
1547+ postURL := fmt .Sprintf ("%sprojects/%s/locations/%s/connections?connectionId=%s" ,
1548+ config .DeveloperConnectBasePath , config .Project , location , connectionId )
1549+ headers := make (http.Header )
1550+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1551+ Config : config ,
1552+ Method : "POST" ,
1553+ Project : config .Project ,
1554+ RawURL : postURL ,
1555+ UserAgent : config .UserAgent ,
1556+ Body : obj ,
1557+ Timeout : 20 * time .Minute ,
1558+ Headers : headers ,
1559+ })
1560+ if err != nil {
1561+ t .Fatalf ("Error bootstrapping developer connection %q: %s" , connectionId , err )
1562+ }
1563+
1564+ _ , err = transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1565+ Config : config ,
1566+ Method : "GET" ,
1567+ Project : config .Project ,
1568+ RawURL : getURL ,
1569+ UserAgent : config .UserAgent ,
1570+ Timeout : 20 * time .Minute ,
1571+ Headers : headers ,
1572+ })
1573+ if err != nil {
1574+ t .Fatalf ("Error getting developer connection %q: %s" , connectionId , err )
1575+ }
1576+ }
1577+
1578+ return connectionId
1579+ }
1580+
1581+ const SharedRepositoryGroupPrefix = "tf-bootstrap-repo-group-"
1582+
1583+ func BoostrapSharedRepositoryGroup (t * testing.T , repositoryGroupId , location , labels , codeRepositoryIndexId , resource string ) string {
1584+ repositoryGroupId = SharedRepositoryGroupPrefix + repositoryGroupId
1585+
1586+ config := BootstrapConfig (t )
1587+ if config == nil {
1588+ t .Fatal ("Could not bootstrap config." )
1589+ }
1590+
1591+ log .Printf ("[DEBUG] Getting shared repository group %q" , repositoryGroupId )
1592+
1593+ getURL := fmt .Sprintf ("%sprojects/%s/locations/%s/codeRepositoryIndexes/%s/repositoryGroups/%s" ,
1594+ config .GeminiBasePath , config .Project , location , codeRepositoryIndexId , repositoryGroupId )
1595+
1596+ headers := make (http.Header )
1597+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1598+ Config : config ,
1599+ Method : "GET" ,
1600+ Project : config .Project ,
1601+ RawURL : getURL ,
1602+ UserAgent : config .UserAgent ,
1603+ Headers : headers ,
1604+ })
1605+ if err != nil {
1606+ log .Printf ("[DEBUG] Repository group %q not found, bootstrapping" , codeRepositoryIndexId )
1607+ repositories := [1 ]interface {}{map [string ]string {
1608+ "resource" : resource ,
1609+ "branch_pattern" : "main" ,
1610+ }}
1611+ postURL := fmt .Sprintf ("%sprojects/%s/locations/%s/codeRepositoryIndexes/%s/repositoryGroups?repositoryGroupId=%s" ,
1612+ config .GeminiBasePath , config .Project , location , codeRepositoryIndexId , repositoryGroupId )
1613+ obj := map [string ]interface {}{
1614+ "repositories" : repositories ,
1615+ }
1616+ if labels != "" {
1617+ obj ["labels" ] = labels
1618+ }
1619+
1620+ headers := make (http.Header )
1621+ for {
1622+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1623+ Config : config ,
1624+ Method : "POST" ,
1625+ Project : config .Project ,
1626+ RawURL : postURL ,
1627+ UserAgent : config .UserAgent ,
1628+ Body : obj ,
1629+ Timeout : 20 * time .Minute ,
1630+ Headers : headers ,
1631+ })
1632+ if err != nil {
1633+ if transport_tpg .IsGoogleApiErrorWithCode (err , 409 ) {
1634+ errMsg := fmt .Sprintf ("%s" , err )
1635+ if strings .Contains (errMsg , "unable to queue the operation" ) {
1636+ log .Printf ("[DEBUG] Waiting for enqueued operation to finish before creating RepositoryGroup: %#v" , obj )
1637+ time .Sleep (10 * time .Second )
1638+ } else if strings .Contains (errMsg , "parent resource not in ready state" ) {
1639+ log .Printf ("[DEBUG] Waiting for parent resource to become active before creating RepositoryGroup: %#v" , obj )
1640+ time .Sleep (1 * time .Minute )
1641+ } else {
1642+ t .Fatalf ("Error creating RepositoryGroup: %s" , err )
1643+ }
1644+ } else {
1645+ t .Fatalf ("Error creating repository group %q: %s" , repositoryGroupId , err )
1646+ }
1647+ } else {
1648+ break
1649+ }
1650+ }
1651+
1652+ _ , err = transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1653+ Config : config ,
1654+ Method : "GET" ,
1655+ Project : config .Project ,
1656+ RawURL : getURL ,
1657+ UserAgent : config .UserAgent ,
1658+ Timeout : 20 * time .Minute ,
1659+ Headers : headers ,
1660+ })
1661+ if err != nil {
1662+ t .Errorf ("Error getting repository group %q: %s" , repositoryGroupId , err )
1663+ }
1664+ }
1665+
1666+ return repositoryGroupId
1667+ }
1668+
1669+ // BootstrapSharedCodeRepositoryIndex will create a code repository index
1670+ // if it hasn't been created in the test project.
1671+ //
1672+ // BootstrapSharedCodeRepositoryIndex returns a persistent code repository index
1673+ // for a test or set of tests.
1674+ //
1675+ // Deletion of code repository index takes a few minutes, and creation of it
1676+ // currently takes about half an hour.
1677+ // That is the reason to use the shared code repository indexes for test resources.
1678+ const SharedCodeRepositoryIndexPrefix = "tf-bootstrap-cri-"
1679+
1680+ func BootstrapSharedCodeRepositoryIndex (t * testing.T , codeRepositoryIndexId , location , kmsKey string , labels map [string ]string ) string {
1681+ codeRepositoryIndexId = SharedCodeRepositoryIndexPrefix + codeRepositoryIndexId
1682+
1683+ config := BootstrapConfig (t )
1684+ if config == nil {
1685+ t .Fatal ("Could not bootstrap config." )
1686+ }
1687+
1688+ log .Printf ("[DEBUG] Getting shared code repository index %q" , codeRepositoryIndexId )
1689+
1690+ getURL := fmt .Sprintf ("%sprojects/%s/locations/%s/codeRepositoryIndexes/%s" , config .GeminiBasePath , config .Project , location , codeRepositoryIndexId )
1691+
1692+ headers := make (http.Header )
1693+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1694+ Config : config ,
1695+ Method : "GET" ,
1696+ Project : config .Project ,
1697+ RawURL : getURL ,
1698+ UserAgent : config .UserAgent ,
1699+ Timeout : 90 * time .Minute ,
1700+ Headers : headers ,
1701+ })
1702+
1703+ // CRI not found responds with 404 not found
1704+ if err != nil && transport_tpg .IsGoogleApiErrorWithCode (err , 404 ) {
1705+ log .Printf ("[DEBUG] Code repository index %q not found, bootstrapping" , codeRepositoryIndexId )
1706+ postURL := fmt .Sprintf ("%sprojects/%s/locations/%s/codeRepositoryIndexes?codeRepositoryIndexId=%s" , config .GeminiBasePath , config .Project , location , codeRepositoryIndexId )
1707+ obj := make (map [string ]interface {})
1708+ if labels != nil {
1709+ obj ["labels" ] = labels
1710+ }
1711+ if kmsKey != "" {
1712+ obj ["kmsKey" ] = kmsKey
1713+ }
1714+
1715+ headers := make (http.Header )
1716+ _ , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1717+ Config : config ,
1718+ Method : "POST" ,
1719+ Project : config .Project ,
1720+ RawURL : postURL ,
1721+ UserAgent : config .UserAgent ,
1722+ Body : obj ,
1723+ Timeout : 90 * time .Minute ,
1724+ Headers : headers ,
1725+ })
1726+ if err != nil {
1727+ t .Fatalf ("Error creating code repository index %q: %s" , codeRepositoryIndexId , err )
1728+ }
1729+
1730+ _ , err = transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
1731+ Config : config ,
1732+ Method : "GET" ,
1733+ Project : config .Project ,
1734+ RawURL : getURL ,
1735+ UserAgent : config .UserAgent ,
1736+ Timeout : 90 * time .Minute ,
1737+ Headers : headers ,
1738+ })
1739+ if err != nil {
1740+ t .Fatalf ("Error getting code repository index %q: %s" , codeRepositoryIndexId , err )
1741+ }
1742+ } else if err != nil {
1743+ t .Fatalf ("Error getting code repository index %q: %s" , codeRepositoryIndexId , err )
1744+ }
1745+
1746+ return codeRepositoryIndexId
1747+ }
1748+
14371749const sharedTagKeyPrefix = "tf-bootstrap-tagkey"
14381750
14391751func BootstrapSharedTestTagKey (t * testing.T , testId string ) string {
0 commit comments