Commit 0af8fa9e authored by Catalin Irimie's avatar Catalin Irimie

Expose internal_url setting for Geo secondaries

This enables admins to set an internal URL for Geo secondaries.

The field already existed in the backend but was intentionally
not exposed to the frontend for simplicity.

This is a pre-requisite to enable the primary to query the
secondaries data directly through this URL.

Changelog: added
EE: true
parent 35ff3879
......@@ -55,14 +55,21 @@ you can increase the values to complete backfill in a shorter time. If it's
under heavy load and backfill reduces its availability for normal requests,
you can decrease them.
## Using a different URL for synchronization
## Set up the internal URLs
> Setting up internal URLs in secondary sites was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77179) in GitLab 14.7.
You can set up a different URL for synchronization between the primary and secondary site.
The **primary** site's Internal URL is used by **secondary** sites to contact it
(to sync repositories, for example). The name Internal URL distinguishes it from
[External URL](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab),
which is used by users. Internal URL does not need to be a private address.
Internal URL defaults to external URL, but you can also customize it:
When [Geo secondary proxying](../../administration/geo/secondary_proxy/index.md) is enabled,
the primary uses the secondary's internal URL to contact it directly.
The internal URL defaults to external URL. To change it:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Geo > Nodes**.
......@@ -70,6 +77,9 @@ Internal URL defaults to external URL, but you can also customize it:
1. Edit the internal URL.
1. Select **Save changes**.
When enabled, the Admin Area for Geo shows replication details for each site directly
from the primary site's UI, and through the Geo secondary proxy, if enabled.
WARNING:
We recommend using an HTTPS connection while configuring the Geo sites. To avoid
breaking communication between **primary** and **secondary** sites when using
......
<script>
import { GlFormGroup, GlFormInput, GlSprintf, GlLink } from '@gitlab/ui';
import { mapActions, mapState } from 'vuex';
import { s__ } from '~/locale';
import {
VALIDATION_FIELD_KEYS,
NODE_NAME_MORE_INFO,
......@@ -24,6 +25,15 @@ export default {
},
computed: {
...mapState(['formErrors']),
internalUrlDescription() {
return this.nodeData.primary
? s__(
'AdminGeo|The URL of the primary site that is used internally by the secondary sites.',
)
: s__(
'AdminGeo|The URL of the secondary site that is used internally by the primary site.',
);
},
},
methods: {
...mapActions(['setError']),
......@@ -126,21 +136,14 @@ export default {
</div>
</gl-form-group>
<gl-form-group
v-if="nodeData.primary"
class="col-12 col-sm-6"
:label="__('Internal URL (optional)')"
label-for="node-internal-url-field"
:description="
__('The URL defined on the primary node that secondary nodes should use to contact it.')
"
:description="internalUrlDescription"
>
<template #description>
<gl-sprintf
:message="
__(
'The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}',
)
"
:message="`${internalUrlDescription} ${__('%{linkStart}Learn more.%{linkEnd}')}`"
>
<template #link="{ content }">
<gl-link
......
......@@ -17,7 +17,7 @@ export const NODE_NAME_MORE_INFO = helpPagePath('user/admin_area/geo_nodes.html'
});
export const NODE_INTERNAL_URL_MORE_INFO = helpPagePath('user/admin_area/geo_nodes.html', {
anchor: 'using-a-different-url-for-synchronization',
anchor: 'set-up-the-internal-urls',
});
export const SELECTIVE_SYNC_MORE_INFO = helpPagePath(
......
......@@ -52,7 +52,7 @@ export default {
<gl-icon name="external-link" class="gl-ml-1" />
</gl-link>
</div>
<div v-if="node.primary" class="gl-display-flex gl-flex-direction-column gl-lg-my-5">
<div class="gl-display-flex gl-flex-direction-column gl-lg-my-5">
<span>{{ $options.i18n.internalUrl }}</span>
<span class="gl-font-weight-bold" data-testid="node-internal-url">{{
node.internalUrl
......
......@@ -95,7 +95,7 @@ RSpec.describe 'admin Geo Nodes', :js, :geo do
end
describe 'node form fields' do
primary_only_fields = %w(node-internal-url-field node-reverification-interval-field)
primary_only_fields = %w(node-reverification-interval-field)
secondary_only_fields = %w(node-selective-synchronization-field node-repository-capacity-field node-file-capacity-field node-object-storage-field)
it 'when primary renders only primary fields' do
......
......@@ -74,10 +74,10 @@ describe('GeoNodeFormCore', () => {
});
describe.each`
primaryNode | showInternalUrl
${true} | ${true}
${false} | ${false}
`(`conditional fields`, ({ primaryNode, showInternalUrl }) => {
primaryNode
${true}
${false}
`('internal URL', ({ primaryNode }) => {
describe(`when node is ${primaryNode ? 'primary' : 'secondary'}`, () => {
beforeEach(() => {
createComponent({
......@@ -85,17 +85,15 @@ describe('GeoNodeFormCore', () => {
});
});
it(`${showInternalUrl ? 'shows' : 'hides'} the Internal URL Field`, () => {
expect(findGeoNodeInternalUrlField().exists()).toBe(showInternalUrl);
it('shows the Internal URL Field', () => {
expect(findGeoNodeInternalUrlField().exists()).toBe(true);
});
it(`${showInternalUrl ? 'shows' : 'hides'} the Internal URL More Information Link`, () => {
expect(findGeoNodeFormInternalUrlMoreInformation().exists()).toBe(showInternalUrl);
if (showInternalUrl) {
expect(findGeoNodeFormInternalUrlMoreInformation().attributes('href')).toBe(
NODE_INTERNAL_URL_MORE_INFO,
);
}
it('shows the Internal URL More Information Link', () => {
expect(findGeoNodeFormInternalUrlMoreInformation().exists()).toBe(true);
expect(findGeoNodeFormInternalUrlMoreInformation().attributes('href')).toBe(
NODE_INTERNAL_URL_MORE_INFO,
);
});
});
});
......
......@@ -67,17 +67,17 @@ describe('GeoNodeCoreDetails', () => {
});
describe.each`
node | showInternalUrl
${MOCK_NODES[0]} | ${true}
${MOCK_NODES[1]} | ${false}
`(`conditionally`, ({ node, showInternalUrl }) => {
node
${MOCK_NODES[0]}
${MOCK_NODES[1]}
`('internal URL', ({ node }) => {
beforeEach(() => {
createComponent(null, { node });
});
describe(`when primary is ${node.primary}`, () => {
it(`does ${showInternalUrl ? '' : 'not '}render node internal url`, () => {
expect(findNodeInternalUrl().exists()).toBe(showInternalUrl);
it(`does render node internal url`, () => {
expect(findNodeInternalUrl().exists()).toBe(true);
});
});
});
......
......@@ -722,6 +722,9 @@ msgstr ""
msgid "%{level_name} is not allowed since the fork source project has lower visibility."
msgstr ""
msgid "%{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "%{link_start}Learn more%{link_end} about roles."
msgstr ""
......@@ -2498,6 +2501,12 @@ msgstr ""
msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr ""
msgid "AdminGeo|The URL of the primary site that is used internally by the secondary sites."
msgstr ""
msgid "AdminGeo|The URL of the secondary site that is used internally by the primary site."
msgstr ""
msgid "AdminLabels|Define your default set of project labels"
msgstr ""
......@@ -35301,12 +35310,6 @@ msgstr ""
msgid "The Snowplow cookie domain."
msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it."
msgstr ""
msgid "The URL defined on the primary node that secondary nodes should use to contact it. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "The URL of the Jenkins server."
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment