Skip to content

Add Terraform Module Registry [RUN ALL RSPEC] [RUN AS-IF-FOSS]

Matt Kasa requested to merge mattkasa/terraform-module-packages into master

What does this MR do?

Adds the Terraform Module Registry

  • Adds service discovery at /.well-known/terraform.json
  • Adds Terraform Module package type
  • Adds API endpoints for Terraform
  • Adds API endpoints for Terraform Module publishing using curl
  • Adds http header token locations to APIAuthentication

Closes #321102 (closed)

Screenshots (strongly suggested)

Terraform Module

Database

Queries

current_package_exists_elsewhere?

Query (https://console.postgres.ai/shared/94381267-b4c8-484a-9498-7a03df3b45cb):

SELECT
    1 AS one
FROM
    "packages_packages"
WHERE
    "packages_packages"."project_id" IN (
        SELECT
            "projects"."id"
        FROM
            "projects"
        WHERE
            "projects"."namespace_id" IN ( WITH RECURSIVE "base_and_descendants" AS ((
                        SELECT
                            "namespaces".*
                        FROM
                            "namespaces"
                        WHERE
                            "namespaces"."type" = 'Group'
                            AND "namespaces"."id" = 110)
                    UNION (
                        SELECT
                            "namespaces".*
                        FROM
                            "namespaces",
                            "base_and_descendants"
                        WHERE
                            "namespaces"."type" = 'Group'
                            AND "namespaces"."parent_id" = "base_and_descendants"."id"))
                    SELECT
                        id
                    FROM
                        "base_and_descendants" AS "namespaces")
                    AND "projects"."id" != 22)
            AND "packages_packages"."package_type" = 11
            AND "packages_packages"."name" = 'gitlab-file/local'
        LIMIT 1

# Explain:
Limit  (cost=1583.94..1618.96 rows=1 width=4) (actual time=6.245..6.247 rows=0 loops=1)
   Buffers: shared read=3
   I/O Timings: read=6.181
   ->  Nested Loop Semi Join  (cost=1583.94..1618.96 rows=1 width=4) (actual time=6.243..6.246 rows=0 loops=1)
         Buffers: shared read=3
         I/O Timings: read=6.181
         ->  Index Scan using package_name_index on public.packages_packages  (cost=0.43..24.72 rows=1 width=4) (actual time=6.242..6.242 rows=0 loops=1)
               Index Cond: ((packages_packages.name)::text = 'gitlab-file/local'::text)
               Filter: (packages_packages.package_type = 11)
               Rows Removed by Filter: 0
               Buffers: shared read=3
               I/O Timings: read=6.181
         ->  Nested Loop Semi Join  (cost=1583.51..1594.22 rows=1 width=4) (actual time=0.000..0.000 rows=0 loops=0)
               ->  Index Scan using idx_projects_on_repository_storage_last_repository_updated_at on public.projects  (cost=0.56..3.58 rows=1 width=8) (actual time=0.000..0.000 rows=0 loops=0)
                     Index Cond: (projects.id = packages_packages.project_id)
                     Filter: (projects.id <> 22)
                     Rows Removed by Filter: 0
               ->  CTE Scan on base_and_descendants namespaces  (cost=1582.95..1586.57 rows=181 width=4) (actual time=0.000..0.000 rows=0 loops=0)
                     CTE base_and_descendants
                       ->  Recursive Union  (cost=0.43..1582.95 rows=181 width=344) (actual time=0.000..0.000 rows=0 loops=0)
                             ->  Index Scan using index_namespaces_on_type_and_id_partial on public.namespaces namespaces_1  (cost=0.43..3.45 rows=1 width=344) (actual time=0.000..0.000 rows=0 loops=0)
                                   Index Cond: (((namespaces_1.type)::text = 'Group'::text) AND (namespaces_1.id = 110))
                             ->  Nested Loop  (cost=0.56..157.59 rows=18 width=344) (actual time=0.000..0.000 rows=0 loops=0)
                                   ->  WorkTable Scan on base_and_descendants  (cost=0.00..0.20 rows=10 width=4) (actual time=0.000..0.000 rows=0 loops=0)
                                   ->  Index Scan using index_namespaces_on_parent_id_and_id on public.namespaces namespaces_2  (cost=0.56..15.72 rows=2 width=344) (actual time=0.000..0.000 rows=0 loops=0)
                                         Index Cond: (namespaces_2.parent_id = base_and_descendants.id)
                                         Filter: ((namespaces_2.type)::text = 'Group'::text)
                                         Rows Removed by Filter: 0

current_package_version_exists?

Query (https://console.postgres.ai/shared/5ca71df3-c316-4015-8c5b-978a48b5662f):

SELECT
    1 AS one
FROM
    "packages_packages"
WHERE
    "packages_packages"."project_id" = 22
    AND "packages_packages"."package_type" = 11
    AND "packages_packages"."name" = 'gitlab-file/local'
    AND "packages_packages"."version" = '1.0.1'
LIMIT 1

# Explain:
Limit  (cost=0.43..3.45 rows=1 width=4) (actual time=3.596..3.597 rows=0 loops=1)
   Buffers: shared hit=3 read=3
   I/O Timings: read=3.509
   ->  Index Scan using index_packages_packages_on_project_id_and_package_type on public.packages_packages  (cost=0.43..3.45 rows=1 width=4) (actual time=3.594..3.594 rows=0 loops=1)
         Index Cond: ((packages_packages.project_id = 22) AND (packages_packages.package_type = 11))
         Filter: (((packages_packages.name)::text = 'gitlab-file/local'::text) AND ((packages_packages.version)::text = '1.0.1'::text))
         Rows Removed by Filter: 0
         Buffers: shared hit=3 read=3
         I/O Timings: read=3.509

Product Intelligence

Adds track_package_event('push_package', :terraform_module):

[{"rawEvent":{"api":{"vendor":"com.snowplowanalytics.snowplow","version":"tp1"},"parameters":{"e":"se","eid":"7b8450d0-a2c8-41fa-b987-71a6e22763fc","cx":"eyJzY2hlbWEiOiJpZ2x1OmNvbS5zbm93cGxvd2FuYWx5dGljcy5zbm93cGxvdy9jb250ZXh0cy9qc29uc2NoZW1hLzEtMC0xIiwiZGF0YSI6W3sic2NoZW1hIjoiaWdsdTpjb20uZ2l0bGFiL2dpdGxhYl9zdGFuZGFyZC9qc29uc2NoZW1hLzEtMC00IiwiZGF0YSI6eyJlbnZpcm9ubWVudCI6ImRldmVsb3BtZW50Iiwic291cmNlIjoiZ2l0bGFiLXJhaWxzIiwiZXh0cmEiOnt9fX1dfQ==","tna":"gl","stm":"1618017365262","tv":"rb-0.6.1","se_ac":"push_package","se_ca":"API::Terraform::Modules::V1::Packages","p":"srv","dtm":"1618017365260"},"contentType":null,"source":{"name":"ssc-2.2.1-stdout$","encoding":"UTF-8","hostname":"localhost"},"context":{"timestamp":"2021-04-10T01:16:05.280Z","ipAddress":"172.17.0.1","useragent":"Ruby","refererUri":null,"headers":["Timeout-Access: <function1>","Accept-Encoding: gzip, deflate;q=0.6, identity;q=0.3","Accept: */*","User-Agent: Ruby","Connection: close","Host: localhost:9090"],"userId":"46852816-5af7-4cab-9142-ffd52c85bffb"}},"eventType":"struct","schema":"iglu:com.google.analytics/event/jsonschema/1-0-0","contexts":["iglu:com.gitlab/gitlab_standard/jsonschema/1-0-4"],"event":{"app_id":null,"platform":"srv","etl_tstamp":"2021-04-10T01:16:05.282Z","collector_tstamp":"2021-04-10T01:16:05.280Z","dvce_created_tstamp":"2021-04-10T01:16:05.260Z","event":"struct","event_id":"7b8450d0-a2c8-41fa-b987-71a6e22763fc","txn_id":null,"name_tracker":"gl","v_tracker":"rb-0.6.1","v_collector":"ssc-2.2.1-stdout$","v_etl":"snowplow-micro-1.1.1-common-1.4.2","user_id":null,"user_ipaddress":"172.17.0.1","user_fingerprint":null,"domain_userid":null,"domain_sessionidx":null,"network_userid":"46852816-5af7-4cab-9142-ffd52c85bffb","geo_country":null,"geo_region":null,"geo_city":null,"geo_zipcode":null,"geo_latitude":null,"geo_longitude":null,"geo_region_name":null,"ip_isp":null,"ip_organization":null,"ip_domain":null,"ip_netspeed":null,"page_url":null,"page_title":null,"page_referrer":null,"page_urlscheme":null,"page_urlhost":null,"page_urlport":null,"page_urlpath":null,"page_urlquery":null,"page_urlfragment":null,"refr_urlscheme":null,"refr_urlhost":null,"refr_urlport":null,"refr_urlpath":null,"refr_urlquery":null,"refr_urlfragment":null,"refr_medium":null,"refr_source":null,"refr_term":null,"mkt_medium":null,"mkt_source":null,"mkt_term":null,"mkt_content":null,"mkt_campaign":null,"contexts":{"schema":"iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-0","data":[{"schema":"iglu:com.gitlab/gitlab_standard/jsonschema/1-0-4","data":{"environment":"development","source":"gitlab-rails","extra":{}}}]},"se_category":"API::Terraform::Modules::V1::Packages","se_action":"push_package","se_label":null,"se_property":null,"se_value":null,"unstruct_event":null,"tr_orderid":null,"tr_affiliation":null,"tr_total":null,"tr_tax":null,"tr_shipping":null,"tr_city":null,"tr_state":null,"tr_country":null,"ti_orderid":null,"ti_sku":null,"ti_name":null,"ti_category":null,"ti_price":null,"ti_quantity":null,"pp_xoffset_min":null,"pp_xoffset_max":null,"pp_yoffset_min":null,"pp_yoffset_max":null,"useragent":"Ruby","br_name":null,"br_family":null,"br_version":null,"br_type":null,"br_renderengine":null,"br_lang":null,"br_features_pdf":null,"br_features_flash":null,"br_features_java":null,"br_features_director":null,"br_features_quicktime":null,"br_features_realplayer":null,"br_features_windowsmedia":null,"br_features_gears":null,"br_features_silverlight":null,"br_cookies":null,"br_colordepth":null,"br_viewwidth":null,"br_viewheight":null,"os_name":null,"os_family":null,"os_manufacturer":null,"os_timezone":null,"dvce_type":null,"dvce_ismobile":null,"dvce_screenwidth":null,"dvce_screenheight":null,"doc_charset":null,"doc_width":null,"doc_height":null,"tr_currency":null,"tr_total_base":null,"tr_tax_base":null,"tr_shipping_base":null,"ti_currency":null,"ti_price_base":null,"base_currency":null,"geo_timezone":null,"mkt_clickid":null,"mkt_network":null,"etl_tags":null,"dvce_sent_tstamp":"2021-04-10T01:16:05.262Z","refr_domain_userid":null,"refr_dvce_tstamp":null,"derived_contexts":{},"domain_sessionid":null,"derived_tstamp":"2021-04-10T01:16:05.278Z","event_vendor":"com.google.analytics","event_name":"event","event_format":"jsonschema","event_version":"1-0-0","event_fingerprint":null,"true_tstamp":null}},{"rawEvent":{"api":{"vendor":"com.snowplowanalytics.snowplow","version":"tp1"},"parameters":{"e":"se","eid":"87c125ba-906e-4421-8e1b-97eba5516c13","cx":"eyJzY2hlbWEiOiJpZ2x1OmNvbS5zbm93cGxvd2FuYWx5dGljcy5zbm93cGxvdy9jb250ZXh0cy9qc29uc2NoZW1hLzEtMC0xIiwiZGF0YSI6W3sic2NoZW1hIjoiaWdsdTpjb20uZ2l0bGFiL2dpdGxhYl9zdGFuZGFyZC9qc29uc2NoZW1hLzEtMC00IiwiZGF0YSI6eyJlbnZpcm9ubWVudCI6ImRldmVsb3BtZW50Iiwic291cmNlIjoiZ2l0bGFiLXJhaWxzIiwiZXh0cmEiOnt9fX1dfQ==","tna":"gl","stm":"1618017357801","tv":"rb-0.6.1","se_ac":"push_package","se_ca":"API::Terraform::Modules::V1::Packages","p":"srv","dtm":"1618017357798"},"contentType":null,"source":{"name":"ssc-2.2.1-stdout$","encoding":"UTF-8","hostname":"localhost"},"context":{"timestamp":"2021-04-10T01:15:57.902Z","ipAddress":"172.17.0.1","useragent":"Ruby","refererUri":null,"headers":["Timeout-Access: <function1>","Accept-Encoding: gzip, deflate;q=0.6, identity;q=0.3","Accept: */*","User-Agent: Ruby","Connection: close","Host: localhost:9090"],"userId":"de64a189-84a9-4672-8e42-6c1fe3814afe"}},"eventType":"struct","schema":"iglu:com.google.analytics/event/jsonschema/1-0-0","contexts":["iglu:com.gitlab/gitlab_standard/jsonschema/1-0-4"],"event":{"app_id":null,"platform":"srv","etl_tstamp":"2021-04-10T01:15:58.098Z","collector_tstamp":"2021-04-10T01:15:57.902Z","dvce_created_tstamp":"2021-04-10T01:15:57.798Z","event":"struct","event_id":"87c125ba-906e-4421-8e1b-97eba5516c13","txn_id":null,"name_tracker":"gl","v_tracker":"rb-0.6.1","v_collector":"ssc-2.2.1-stdout$","v_etl":"snowplow-micro-1.1.1-common-1.4.2","user_id":null,"user_ipaddress":"172.17.0.1","user_fingerprint":null,"domain_userid":null,"domain_sessionidx":null,"network_userid":"de64a189-84a9-4672-8e42-6c1fe3814afe","geo_country":null,"geo_region":null,"geo_city":null,"geo_zipcode":null,"geo_latitude":null,"geo_longitude":null,"geo_region_name":null,"ip_isp":null,"ip_organization":null,"ip_domain":null,"ip_netspeed":null,"page_url":null,"page_title":null,"page_referrer":null,"page_urlscheme":null,"page_urlhost":null,"page_urlport":null,"page_urlpath":null,"page_urlquery":null,"page_urlfragment":null,"refr_urlscheme":null,"refr_urlhost":null,"refr_urlport":null,"refr_urlpath":null,"refr_urlquery":null,"refr_urlfragment":null,"refr_medium":null,"refr_source":null,"refr_term":null,"mkt_medium":null,"mkt_source":null,"mkt_term":null,"mkt_content":null,"mkt_campaign":null,"contexts":{"schema":"iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-0","data":[{"schema":"iglu:com.gitlab/gitlab_standard/jsonschema/1-0-4","data":{"environment":"development","source":"gitlab-rails","extra":{}}}]},"se_category":"API::Terraform::Modules::V1::Packages","se_action":"push_package","se_label":null,"se_property":null,"se_value":null,"unstruct_event":null,"tr_orderid":null,"tr_affiliation":null,"tr_total":null,"tr_tax":null,"tr_shipping":null,"tr_city":null,"tr_state":null,"tr_country":null,"ti_orderid":null,"ti_sku":null,"ti_name":null,"ti_category":null,"ti_price":null,"ti_quantity":null,"pp_xoffset_min":null,"pp_xoffset_max":null,"pp_yoffset_min":null,"pp_yoffset_max":null,"useragent":"Ruby","br_name":null,"br_family":null,"br_version":null,"br_type":null,"br_renderengine":null,"br_lang":null,"br_features_pdf":null,"br_features_flash":null,"br_features_java":null,"br_features_director":null,"br_features_quicktime":null,"br_features_realplayer":null,"br_features_windowsmedia":null,"br_features_gears":null,"br_features_silverlight":null,"br_cookies":null,"br_colordepth":null,"br_viewwidth":null,"br_viewheight":null,"os_name":null,"os_family":null,"os_manufacturer":null,"os_timezone":null,"dvce_type":null,"dvce_ismobile":null,"dvce_screenwidth":null,"dvce_screenheight":null,"doc_charset":null,"doc_width":null,"doc_height":null,"tr_currency":null,"tr_total_base":null,"tr_tax_base":null,"tr_shipping_base":null,"ti_currency":null,"ti_price_base":null,"base_currency":null,"geo_timezone":null,"mkt_clickid":null,"mkt_network":null,"etl_tags":null,"dvce_sent_tstamp":"2021-04-10T01:15:57.801Z","refr_domain_userid":null,"refr_dvce_tstamp":null,"derived_contexts":{},"domain_sessionid":null,"derived_tstamp":"2021-04-10T01:15:57.899Z","event_vendor":"com.google.analytics","event_name":"event","event_format":"jsonschema","event_version":"1-0-0","event_fingerprint":null,"true_tstamp":null}}]

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team
Edited by Matt Kasa

Merge request reports