API: create project for user with `use_custom_template` and `template_name` fails

Summary

initially raised by customer in ticket (internal only)

The API endpoint to create a project for a user documentation states that the following values can be sent to create a project based on custom templates:

template_name
use_custom_template
group_with_project_templates_id

In all cases, project creation fails with "'template-name' is unknown or invalid" unless template_name is that of a built-in template name.

This happens due to the @params in EE::Projects::CreateFromTemplateService receiving only the following values from the API:

{:name=>"create from api", :path=>"create-from-api", :namespace_id=>1}

possibly a few others that I didn't test, but certainly never template_name or use_custom_template. Due to use_custom_template not being present, EE::Projects::CreateFromTemplateService.execute returns a super back to the parent class.

https://gitlab.com/gitlab-org/gitlab/blob/14eb7a47fc434c7ac1dbb5fa0a1cf7d605a67c9d/ee/app/services/ee/projects/create_from_template_service.rb#L21

The parent class only looks for template names from within the built-in template names defined in TEMPLATES_TABLE.

I'm not aware of a workaround, although creating from the GUI works fine.

Steps to reproduce

Add a custom instance-level template and then attempt to use the API to create a project for a user with that template. In my example, the template is called public-templates and I am creating for myself, the admin user:

$ curl --header "Private-Token: <my_token>" https://gitlab/api/v4/projects/user/1 -s -d "name=create from api" -d "use_custom_template=true" -d "template_name=pubic-templates" -s|jq .
{
  "message": {
    "template_name": [
      "'pubic-templates' is unknown or invalid"
    ]
  }
}

template available in the GUI:

screenshot-2019-11-21-16_21

What is the current bug behavior?

Using a custom template name while creating a project for a user always fails

What is the expected correct behavior?

The API should create a project using the specified custom template.

Relevant logs and/or screenshots

api_log:

{"time":"2019-11-21T21:22:15.393Z","severity":"INFO","duration":19.82,"db":2.06,"view":17.76,"status":400,"method":"POST","path":"/api/v4/projects/user/1","params":[{"key":"name","value":"create from api"},{"key":"use_custom_template","value":"true"},{"key":"template_name","value":"pubic-templates"}],"host":"gitlab","remote_ip":"x.x.x.x, x.x.x.x","ua":"curl/7.58.0","route":"/api/:version/projects/user/:user_id","user_id":1,"username":"root","queue_duration":31.12,"correlation_id":"ymXK5Kq53l3"}

production:

Started POST "/api/v4/projects/user/1" for 52.144.39.157 at 2019-11-21 16:22:15 -0500
My object: {:name=>"create from api"}

for comparison, production log when a successful create from template happens from GUI:

  Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "project"=>{"template_name"=>"public-templates", "use_custom_template"=>"true", "group_with_project_templates_id"=>"", "ci_cd_only"=>"false", "name"=>"create from gui2", "namespace_id"=>"1", "path"=>"create-from-gui2", "description"=>"[FILTERED]", "visibility_level"=>"20"}}
Completed 200 OK in 1ms (ActiveRecord: 0.0ms | Elasticsearch: 0.0ms)
Processing by ProjectsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "project"=>{"template_name"=>"public-templates", "use_custom_template"=>"true", "group_with_project_templates_id"=>"", "ci_cd_only"=>"false", "name"=>"create from gui2", "namespace_id"=>"1", "path"=>"create-from-gui2", "description"=>"[FILTERED]", "visibility_level"=>"20"}}
My object: {"description"=>"", "name"=>"create from gui2", "path"=>"create-from-gui2", "visibility_level"=>"20", "use_custom_template"=>"true", "group_with_project_templates_id"=>"", "namespace_id"=>"1"}

("My object" is simply the output of @params.inspect inside of EE::Projects::CreateFromTemplateService.initialize)

Results of GitLab environment info

Expand for output related to GitLab environment info

System information System: Ubuntu 18.04 Proxy: no Current User: git Using RVM: no Ruby Version: 2.6.3p62 Gem Version: 2.7.9 Bundler Version:1.17.3 Rake Version: 12.3.3 Redis Version: 3.2.12 Git Version: 2.22.0 Sidekiq Version:5.2.7 Go Version: unknown

GitLab information Version: 12.4.1-ee Revision: 8953eae82c8 Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 10.9 URL: https://gitlab HTTP Clone URL: https://gitlab/some-group/some-project.git SSH Clone URL: git@gitlab:some-group/some-project.git Elasticsearch: yes Geo: yes Geo node: Primary Using LDAP: no Using Omniauth: yes Omniauth Providers:

GitLab Shell Version: 10.2.0 Repository storage paths: default: /var/opt/gitlab/git-data/repositories GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell Git: /opt/gitlab/embedded/bin/git

Possible fixes

I linked pretty much all of the lines of code that seem to cause the problem; I'm not certain why the API is failing to pass the params back as expected tho.