diff --git a/playbooks/host_vars/static01.opendev.org.yaml b/playbooks/host_vars/static01.opendev.org.yaml index 78ac2841d5..af09a50b53 100644 --- a/playbooks/host_vars/static01.opendev.org.yaml +++ b/playbooks/host_vars/static01.opendev.org.yaml @@ -13,6 +13,14 @@ letsencrypt_certs: - docs.openstack.org static01-docs-starlingx-io: - docs.starlingx.io + static01-git-airshipit-org: + - git.airshipit.org + static01-git-openstack-org: + - git.openstack.org + static01-git-starlingx-io: + - git.starlingx.io + static01-git-zuul-ci-org: + - git.zuul-ci.org static01-governance-openstack-org: - governance.openstack.org static01-service-types-openstack-org: diff --git a/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml b/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml index e1a7b8efc6..6197422e53 100644 --- a/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml +++ b/playbooks/roles/letsencrypt-create-certs/handlers/main.yaml @@ -50,6 +50,18 @@ - name: letsencrypt updated static01-docs-starlingx-io include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml +- name: letsencrypt updated static01-git-airshipit-org + include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml + +- name: letsencrypt updated static01-git-starlingx-io + include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml + +- name: letsencrypt updated static01-git-openstack-org + include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml + +- name: letsencrypt updated static01-git-zuul-ci-org + include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml + - name: letsencrypt updated static01-governance-openstack-org include_tasks: roles/letsencrypt-create-certs/handlers/restart_apache.yaml diff --git a/playbooks/roles/static/tasks/enable_git_site.yaml b/playbooks/roles/static/tasks/enable_git_site.yaml new file mode 100644 index 0000000000..6fb81ffa7c --- /dev/null +++ b/playbooks/roles/static/tasks/enable_git_site.yaml @@ -0,0 +1,14 @@ +- name: 'Add git site {{ hostname }}' + template: + src: '50-git.conf.j2' + dest: '/etc/apache2/sites-available/50-{{ hostname }}.conf' + owner: root + group: root + mode: 0644 + +- name: 'Enable {{ hostname }}' + command: 'a2ensite 50-{{ hostname }}' + args: + creates: '/etc/apache2/sites-enabled/50-{{ hostname }}' + notify: + - Reload apache2 \ No newline at end of file diff --git a/playbooks/roles/static/tasks/main.yaml b/playbooks/roles/static/tasks/main.yaml index 3f499ff926..f8ac22b346 100644 --- a/playbooks/roles/static/tasks/main.yaml +++ b/playbooks/roles/static/tasks/main.yaml @@ -77,3 +77,13 @@ - 50-tarballs.opendev.org - 50-tarballs.openstack.org - 50-zuul-ci.org + +- name: Enable git sites + include_tasks: enable_git_site.yaml + loop: + - git.airshipit.org + - git.openstack.org + - git.starlingx.io + - git.zuul-ci.org + loop_control: + loop_var: hostname \ No newline at end of file diff --git a/playbooks/roles/static/templates/50-git.conf.j2 b/playbooks/roles/static/templates/50-git.conf.j2 new file mode 100755 index 0000000000..731f318dae --- /dev/null +++ b/playbooks/roles/static/templates/50-git.conf.j2 @@ -0,0 +1,42 @@ +# +# This file is generated and managed by Ansible +# + +{% include 'git-redirects.conf.j2' %} + +## +# vhost configuration +## + + + ServerName {{ hostname }} + + Use GitRedirects + + LogLevel warn + ErrorLog /var/log/apache2/{{ hostname }}_error.log + CustomLog /var/log/apache2/{{ hostname }}_access.log combined + ServerSignature Off + + + + + ServerName {{ hostname }} + + SSLCertificateFile /etc/letsencrypt-certs/{{ hostname }}/{{ hostname }}.cer + SSLCertificateKeyFile /etc/letsencrypt-certs/{{ hostname }}/{{ hostname }}.key + SSLCertificateChainFile /etc/letsencrypt-certs/{{ hostname }}/ca.cer + SSLProtocol All -SSLv2 -SSLv3 + # Note: this list should ensure ciphers that provide forward secrecy + SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!AES256:!aNULL:!eNULL:!MD5:!DSS:!PSK:!SRP + SSLHonorCipherOrder on + + Use GitRedirects + + ErrorLog /var/log/apache2/{{ hostname }}_error.log + CustomLog /var/log/apache2/{{ hostname }}_access.log combined + ServerSignature Off + + + +UndefMacro GitRedirects \ No newline at end of file diff --git a/playbooks/roles/static/templates/git-redirects.conf.j2 b/playbooks/roles/static/templates/git-redirects.conf.j2 new file mode 100644 index 0000000000..9dda0b47d5 --- /dev/null +++ b/playbooks/roles/static/templates/git-redirects.conf.j2 @@ -0,0 +1,192 @@ + + +RewriteEngine On + +# Unescape any slashes in the branch portion of the query string so +# that we don't have to worry about whether or not they are encoded +# later. This is a recursive rule to handle multiple slashes. +RewriteCond %{QUERY_STRING} "^(.*)h=([^&]+)%2F([^&]+)(.*)$" +RewriteRule "^/(.*)$" "/$1?%1h=%2/%3%4" [N] + +# Map whitelabeled project git sites with repository prefixes +RewriteCond %{HTTP_HOST} ^git\.airshipit\.org$ [NC] +RewriteRule "^/(cgit/|)(airship-.*)$" "/$1openstack/$2" +RewriteCond %{HTTP_HOST} ^git\.starlingx\.io$ [NC] +RewriteRule "^/(cgit/|)(stx-.*)$" "/$1openstack/$2" +RewriteCond %{HTTP_HOST} ^git\.zuul-ci\.org$ [NC] +RewriteRule "^/(cgit/|)((nodepool|zuul).*)$" "/$1openstack-infra/$2" + +################################### +# summary +# ignore all args + +RewriteRule "^/cgit/([^/]+)/([^/]+)/?$" "https://opendev.org/$1/$2/" [L,QSD] + +################################### +# refs tab -> branches tab +# ignore all args +# The cgit refs tab shows tags+branches, the branches tab in gitea is +# the closest linkable url + +RewriteRule "^/cgit/([^/]+)/([^/]+)/refs/?" "https://opendev.org/$1/$2/branches" [L,QSD] + +################################### +# log tab (with file) -> commits tab +# h= + +RewriteCond %{QUERY_STRING} h=([\w/]+) +RewriteRule "^/cgit/([^/]+)/([^/]+)/log/?(.*)" "https://opendev.org/$1/$2/commits/branch/%1/$3" [L,QSD] + +# no args + +RewriteRule "^/cgit/([^/]+)/([^/]+)/log/?(.*)" "https://opendev.org/$1/$2/commits/branch/master/$3" [L,QSD] + +##################################################### +# tree tab (with file) -> tree tab +# id= +# h=&id= (id) +# if there's a commit, it takes precedence +RewriteCond %{QUERY_STRING} id=([\w]+) +RewriteRule "^/cgit/(.*?)/(.*?)/tree/?(.*)" "https://opendev.org/$1/$2/src/commit/%1/$3" [L,QSD] + +# h= +# we have a commit pointed for a head +RewriteCond %{QUERY_STRING} h=([0-9a-f]{40}) +RewriteRule "^/cgit/(.*?)/(.*?)/tree/?(.*)" "https://opendev.org/$1/$2/src/commit/%1/$3" [L,QSD] + +# h= +# if there's no commit, but a branch: +RewriteCond %{QUERY_STRING} h=([\w/]+) +RewriteRule "^/cgit/(.*?)/(.*?)/tree/?(.*)" "https://opendev.org/$1/$2/src/branch/%1/$3" [L,QSD] + +# if there's no args: +RewriteRule "^/cgit/(.*?)/(.*?)/tree/?(.*)" "https://opendev.org/$1/$2/src/branch/master/$3" [L,QSD] + +##################################################### +# plain link without file -> tree tab +# id= +# h=&id= (id) +# if there's a commit, it takes precedence +RewriteCond %{QUERY_STRING} id=([\w]+) +RewriteRule "^/cgit/(.*?)/(.*?)/plain/?$" "https://opendev.org/$1/$2/src/commit/%1/$3" [L,QSD] + +# h= +# we have a commit pointed for a head +RewriteCond %{QUERY_STRING} h=([0-9a-f]{40}) +RewriteRule "^/cgit/(.*?)/(.*?)/plain/?$" "https://opendev.org/$1/$2/src/commit/%1/$3" [L,QSD] + +# h= +# if there's no commit, but a branch: +RewriteCond %{QUERY_STRING} h=([\w/]+) +RewriteRule "^/cgit/(.*?)/(.*?)/plain/?$" "https://opendev.org/$1/$2/src/branch/%1/$3" [L,QSD] + +# if there's no args: +RewriteRule "^/cgit/(.*?)/(.*?)/plain/?$" "https://opendev.org/$1/$2/src/branch/master/$3" [L,QSD] + +##################################################### +# plain link (with file) -> raw +# same as tree +# id= +# h=&id= (id) +# if there's a commit, it takes precedence +RewriteCond %{QUERY_STRING} id=([\w]+) +RewriteRule "^/cgit/(.*?)/(.*?)/plain/?(.*)" "https://opendev.org/$1/$2/raw/commit/%1/$3" [L,QSD] + +# h= +# we have a commit pointed for a head +RewriteCond %{QUERY_STRING} h=([0-9a-f]{40}) +RewriteRule "^/cgit/(.*?)/(.*?)/plain/?(.*)$" "https://opendev.org/$1/$2/raw/commit/%1/$3" [L,QSD] + +# h= +# if there's no commit, but a branch: +RewriteCond %{QUERY_STRING} h=([\w/]+) +RewriteRule "^/cgit/(.*?)/(.*?)/plain/?(.*)" "https://opendev.org/$1/$2/raw/branch/%1/$3" [L,QSD] + +# if there's no args: +RewriteRule "^cgit/(.*?)/(.*?)/plain/?(.*)" "https://opendev.org/$1/$2/raw/branch/master/$3" [L,QSD] + +###################### +# commit tab (with file) -> commit screen (without file) +# id= +# id=&h= +RewriteCond %{QUERY_STRING} id=([\w]+) +RewriteRule "^/cgit/(.*?)/(.*?)/commit/?(.*)" "https://opendev.org/$1/$2/commit/%1" [L,QSD] + +# h= +# we have a commit pointed for a head +RewriteCond %{QUERY_STRING} h=([0-9a-f]{40}) +RewriteRule "^/cgit/(.*?)/(.*?)/commit/?(.*)" "https://opendev.org/$1/$2/commit/%1" [L,QSD] + +# h= +# The commit tab in cgit will show the branch-tip commit in this case. +# There is not a comprable page in gitea, so we redirect to the branch +# log (which has the branch-tip commit at the top of the list). We +# include the file if it's there to further restrict the list of +# commits +RewriteCond %{QUERY_STRING} h=([\w/]+) +RewriteRule "^/cgit/(.*?)/(.*?)/commit/?(.*)" "https://opendev.org/$1/$2/commits/branch/%1/$3" [L,QSD] + +# no args +# Same, but with master branch +RewriteRule "^/cgit/(.*?)/(.*?)/commit/?(.*)" "https://opendev.org/$1/$2/commits/branch/master/$3" [L,QSD] + +###################### +# diff (with file) -> commit screen (without file) +# Gitea doesn't handle arbitrary diffs, so just show the commit page for id. +# We do the same thing as for the commit tab. +# id=&id2= +# id= +# id=&h= +RewriteCond %{QUERY_STRING} id=([\w]+) +RewriteRule "^/cgit/(.*?)/(.*?)/diff/?(.*)" "https://opendev.org/$1/$2/commit/%1" [L,QSD] + +# h= +# we have a commit pointed for a head +RewriteCond %{QUERY_STRING} h=([0-9a-f]{40}) +RewriteRule "^/cgit/(.*?)/(.*?)/diff/?(.*)" "https://opendev.org/$1/$2/commit/%1" [L,QSD] + +# h= +RewriteCond %{QUERY_STRING} h=([\w/]+) +RewriteRule "^/cgit/(.*?)/(.*?)/diff/?(.*)" "https://opendev.org/$1/$2/commits/branch/%1/$3" [L,QSD] + +# no args +RewriteRule "^/cgit/(.*?)/(.*?)/diff/?(.*)" "https://opendev.org/$1/$2/commits/branch/master/$3" [L,QSD] + +###################### +# patch (with file) +# Gitea doesn't handle generating patch files, so just show the commit page. +# We do the same thing as for the commit tab. +# id= +# id=&h= +RewriteCond %{QUERY_STRING} id=([\w]+) +RewriteRule "^/cgit/(.*?)/(.*?)/patch/?(.*)" "https://opendev.org/$1/$2/commit/%1" [L,QSD] + +# h= +# we have a commit pointed for a head +RewriteCond %{QUERY_STRING} h=([0-9a-f]{40}) +RewriteRule "^/cgit/(.*?)/(.*?)/patch/?(.*)" "https://opendev.org/$1/$2/commit/%1" [L,QSD] + +# h= +RewriteCond %{QUERY_STRING} h=([\w/]+) +RewriteRule "^/cgit/(.*?)/(.*?)/patch/?(.*)" "https://opendev.org/$1/$2/commits/branch/%1/$3" [L,QSD] + +# no args +RewriteRule "^/cgit/(.*?)/(.*?)/patch/?(.*)" "https://opendev.org/$1/$2/commits/branch/master/$3" [L,QSD] + +##################### +# tag +# Gitea doesn't have a dedicated tag page, but if you click a tag in +# gitea, it takes you to the source tree view for that tag, which has +# the tagged commit at the top of the table. +RewriteCond %{QUERY_STRING} h=([\w/\.]+) +RewriteRule "^/cgit/(.*?)/(.*?)/tag/?" "https://opendev.org/$1/$2/src/tag/%1" [L,QSD] + +##################### +# Any other unknown cgit url, redirect to / +RewriteRule "^/cgit" "https://opendev.org/" [L,QSD] + +##################### +# Non cgit URLs +RewriteRule "^/(.*)$" "https://opendev.org/$1" [L] + + diff --git a/testinfra/test_static.py b/testinfra/test_static.py index 0ff6122eb7..f6f08946a8 100644 --- a/testinfra/test_static.py +++ b/testinfra/test_static.py @@ -129,3 +129,28 @@ def test_zuulci_org(host, name): '--resolve %s:443:127.0.0.1 https://%s/ ' % (name, name)) assert 'Zuul is an open source CI tool' in cmd.stdout + +# test redirects as they are. leave http off the first one and we +# test both http/https. +git_redirects = ( + ('git.openstack.org/openstack/nova', 'https://opendev.org/openstack/nova'), + ('git.openstack.org/cgit/openstack/tripleo-ansible/commit/?id=a6f9b1551baf5f680c05f4fa69ac926f8a0a3f81', + 'https://opendev.org/openstack/tripleo-ansible/commit/a6f9b1551baf5f680c05f4fa69ac926f8a0a3f81'), + ('git.starlingx.io/stx-tools', 'https://opendev.org/openstack/stx-tools'), + ('git.zuul-ci.org/zuul', 'https://opendev.org/openstack-infra/zuul'), + ('git.airshipit.org/airship-in-a-bottle', 'https://opendev.org/openstack/airship-in-a-bottle') +) +@pytest.mark.parametrize("url,target", git_redirects) + +def test_git_redirects(host, url, target): + hostname = url.split('/')[0] + + # http should redirect directly (not bounce via https) + cmd = host.run('curl --resolve %s:80:127.0.0.1 http://%s' % (hostname, url)) + assert '302 Found' in cmd.stdout + assert target in cmd.stdout + + cmd = host.run('curl --insecure --resolve %s:443:127.0.0.1 https://%s' % + (hostname, url)) + assert '302 Found' in cmd.stdout + assert target in cmd.stdout