Skip to content

Commit 19f6192

Browse files
Matthew Dawberpavel-blagodov
authored andcommitted
MB-46178 Add IP address family option to new cluster wizard
The former 'use IPv6 addresses' has been changed to four radio buttons, labelled 'IPv4', 'IPv4 only', 'IPv6', 'IPv6 only'. When setting up a new node, the form will default to 'IPv4'. These options come under the new label of 'IP Family Preference', which includes a tooltip and a short description of the options. Change-Id: I0cc56d4751319e98e496efc65555b89247bc0918 Reviewed-on: http://review.couchbase.org/c/ns_server/+/158999 Well-Formed: Build Bot <[email protected]> Tested-by: Matthew <[email protected]> Reviewed-by: Pavel Blagodov <[email protected]>
1 parent d246283 commit 19f6192

File tree

6 files changed

+137
-63
lines changed

6 files changed

+137
-63
lines changed

priv/public/ui/app/mn.hostname.config.component.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,16 @@ class MnHostnameConfigComponent extends MnLifeCycleHooksToStream {
4949
return;
5050
}
5151
this.group.valueChanges
52-
.pipe(pluck("hostConfig", "afamily"),
52+
.pipe(pluck("hostConfig", "addressFamilyUI"),
5353
distinctUntilChanged(),
5454
takeUntil(this.mnOnDestroy))
55-
.subscribe((afamily) => {
56-
var hostname = this.group.get("hostname").value;
57-
if (afamily && hostname == "127.0.0.1") {
55+
.subscribe(option => {
56+
let hostname = this.group.get("hostname").value;
57+
58+
if ((option == "inet6" || option == "inet6Only") && hostname == "127.0.0.1") {
5859
this.group.get("hostname").setValue("::1");
5960
}
60-
if (!afamily && hostname == "::1") {
61+
if ((option == "inet" || option == "inetOnly") && hostname == "::1") {
6162
this.group.get("hostname").setValue("127.0.0.1");
6263
}
6364
});
Lines changed: 88 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<!--
2-
Copyright 2020-Present Couchbase, Inc.
2+
Copyright 2020-Present Couchbase, Inc.
33
4-
Use of this software is governed by the Business Source License included in
5-
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
6-
file, in accordance with the Business Source License, use of this software will
7-
be governed by the Apache License, Version 2.0, included in the file
8-
licenses/APL2.txt.
4+
Use of this software is governed by the Business Source License included in
5+
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
6+
file, in accordance with the Business Source License, use of this software will
7+
be governed by the Apache License, Version 2.0, included in the file
8+
licenses/APL2.txt.
99
-->
1010

1111
<div [formGroup]="group">
@@ -31,46 +31,92 @@
3131
</div>
3232
</div>
3333

34-
<div class="formrow form-inline"
34+
<div
3535
formGroupName="hostConfig"
3636
*ngIf="isHostCfgEnabled && (isEnterprise | async)">
37-
<input
38-
type="checkbox"
39-
formControlName="afamily"
40-
id="for-use-ipv6-addresses">
41-
<label for="for-use-ipv6-addresses">
42-
use IPv6 addresses
43-
</label>
44-
<input
45-
type="checkbox"
46-
id="for-node-encryption"
47-
formControlName="nodeEncryption">
48-
<label for="for-node-encryption">
49-
enable node-to-node encryption
50-
</label>
51-
<div
52-
class="error error-form"
53-
[hidden]="!(enableExternalListenerHttp.error | async)?.errors.afamily">
54-
{{(enableExternalListenerHttp.error | async)?.errors.afamily}}
37+
<div class="formrow">
38+
<input
39+
type="checkbox"
40+
id="for-node-encryption"
41+
formControlName="nodeEncryption">
42+
<label for="for-node-encryption">
43+
enable node-to-node encryption
44+
</label>
45+
<div
46+
class="error error-form"
47+
[hidden]="!(setupNetConfigHttp.error | async)?.errors.nodeEncryption">
48+
{{(setupNetConfigHttp.error | async)?.errors.nodeEncryption}}
49+
</div>
50+
<div
51+
class="error error-form"
52+
[hidden]="!(enableExternalListenerHttp.error | async)?.errors._">
53+
{{(enableExternalListenerHttp.error | async)?.errors._}}
54+
</div>
55+
<div
56+
class="error error-form"
57+
[hidden]="!(setupNetConfigHttp.error | async)?.errors._">
58+
{{(setupNetConfigHttp.error | async)?.errors._}}
59+
</div>
5560
</div>
56-
<div
57-
class="error error-form"
58-
[hidden]="!(enableExternalListenerHttp.error | async)?.errors._">
59-
{{(enableExternalListenerHttp.error | async)?.errors._}}
61+
<div class="form-inline">
62+
<label>IP Family Preference</label>
63+
<span
64+
class="fa-stack icon-info"
65+
ngbTooltip="Selecting IPv4 will instruct services in the cluster to listen on IPv4
66+
addresses, though as a convenience some services will also listen on IPv6.
67+
If IPv6 is selected, it's vice-versa. Selecting &quot;IPv4-only&quot; will
68+
instruct services to only listen on IPv4 addresses and again, it's vice-versa
69+
if you select &quot;IPv6-only&quot;."
70+
placement="right">
71+
<span class="icon fa-circle-thin fa-stack-2x"></span>
72+
<span class="icon fa-info fa-stack-1x"></span>
73+
</span>
6074
</div>
61-
<div
62-
class="error error-form"
63-
[hidden]="!(setupNetConfigHttp.error | async)?.errors.afamily">
64-
{{(setupNetConfigHttp.error | async)?.errors.afamily}}
65-
</div>
66-
<div
67-
class="error error-form"
68-
[hidden]="!(setupNetConfigHttp.error | async)?.errors.nodeEncryption">
69-
{{(setupNetConfigHttp.error | async)?.errors.nodeEncryption}}
75+
<div class="formrow">
76+
<div class="form-inline">
77+
<input
78+
type="radio"
79+
formControlName="addressFamilyUI"
80+
value="inet"
81+
id="for-use-ipv4">
82+
<label for="for-use-ipv4">
83+
IPv4
84+
</label>
85+
<input
86+
type="radio"
87+
formControlName="addressFamilyUI"
88+
value="inet6"
89+
id="for-use-ipv6">
90+
<label for="for-use-ipv6">
91+
IPv6
92+
</label>
93+
<input
94+
type="radio"
95+
formControlName="addressFamilyUI"
96+
value="inetOnly"
97+
id="for-use-ipv4-only">
98+
<label for="for-use-ipv4-only">
99+
IPv4-only
100+
</label>
101+
<input
102+
type="radio"
103+
formControlName="addressFamilyUI"
104+
value="inet6Only"
105+
id="for-use-ipv6-only">
106+
<label for="for-use-ipv6-only">
107+
IPv6-only
108+
</label>
109+
</div>
110+
<div
111+
class="error error-form"
112+
[hidden]="!(enableExternalListenerHttp.error | async)?.errors.afamily">
113+
{{(enableExternalListenerHttp.error | async)?.errors.afamily}}
114+
</div>
115+
<div
116+
class="error error-form"
117+
[hidden]="!(setupNetConfigHttp.error | async)?.errors.afamily">
118+
{{(setupNetConfigHttp.error | async)?.errors.afamily}}
119+
</div>
70120
</div>
71-
<div
72-
class="error error-form"
73-
[hidden]="!(setupNetConfigHttp.error | async)?.errors._">
74-
{{(setupNetConfigHttp.error | async)?.errors._}}
75121
</div>
76122
</div>

priv/public/ui/app/mn.wizard.join.cluster.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,12 @@ <h2>Couchbase &gt; Join Cluster</h2>
9696
class="formrow disclosure"
9797
(click)="toggleConfigurationSection = !toggleConfigurationSection"
9898
[ngClass]="{'disclosed': toggleConfigurationSection}">
99-
Configure Services & Settings For This Node
99+
Configure Services &amp; Settings For This Node
100100
</div>
101101

102102
<div *ngIf="toggleConfigurationSection">
103103
<mn-hostname-config
104-
[group]="joinClusterForm.get('clusterStorage')">
104+
[group]="joinClusterForm.get('clusterStorage')">
105105
</mn-hostname-config>
106106
<mn-services-config
107107
[group]="joinClusterForm.get('services')">

priv/public/ui/app/mn.wizard.new.cluster.config.component.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ licenses/APL2.txt.
1111
import {UIRouter} from '/ui/web_modules/@uirouter/angular.js';
1212
import {MnLifeCycleHooksToStream} from './mn.core.js';
1313
import {Component, ChangeDetectionStrategy} from '/ui/web_modules/@angular/core.js';
14-
import {takeUntil, filter, map,
15-
tap, withLatestFrom, first} from '/ui/web_modules/rxjs/operators.js';
16-
import {BehaviorSubject, pipe} from '/ui/web_modules/rxjs.js';
14+
import {map, withLatestFrom, first} from '/ui/web_modules/rxjs/operators.js';
15+
import {pipe} from '/ui/web_modules/rxjs.js';
1716
import {MnWizardService} from './mn.wizard.service.js';
1817
import {MnPoolsService} from './mn.pools.service.js';
1918
import {MnFormService} from "./mn.form.service.js";
@@ -117,15 +116,37 @@ class MnWizardNewClusterConfigComponent extends MnLifeCycleHooksToStream {
117116
});
118117
}
119118

119+
getAddressFamily(addressFamilyUI) {
120+
switch(addressFamilyUI) {
121+
case "inet":
122+
case "inetOnly": return "ipv4";
123+
case "inet6":
124+
case "inet6Only": return "ipv6";
125+
default: return "ipv4";
126+
}
127+
}
128+
129+
getAddressFamilyOnly(addressFamilyUI) {
130+
switch(addressFamilyUI) {
131+
case "inet":
132+
case "inet6": return false;
133+
case "inetOnly":
134+
case "inet6Only": return true;
135+
default: return false;
136+
}
137+
}
138+
120139
getHostConfig() {
121-
var clusterStor = this.wizardForm.newClusterConfig.get("clusterStorage");
140+
let clusterStore = this.wizardForm.newClusterConfig.get("clusterStorage");
141+
122142
return {
123-
afamily: clusterStor.get("hostConfig.afamily").value ? "ipv6" : "ipv4",
124-
nodeEncryption: clusterStor.get("hostConfig.nodeEncryption").value ? 'on' : 'off'
143+
afamily: this.getAddressFamily(clusterStore.get("hostConfig.addressFamilyUI").value),
144+
afamilyOnly: this.getAddressFamilyOnly(clusterStore.get("hostConfig.addressFamilyUI").value),
145+
nodeEncryption: clusterStore.get("hostConfig.nodeEncryption").value ? 'on' : 'off'
125146
};
126147
}
127148

128-
getFinalConfig(isEnterprise) {
149+
getFinalConfig() {
129150
var rv = new Map();
130151
rv.set("authHttp", [this.wizardForm.newCluster.value.user, false]);
131152

@@ -139,15 +160,16 @@ class MnWizardNewClusterConfigComponent extends MnLifeCycleHooksToStream {
139160

140161
getNodeInitConfig([_, isEnterprise]) {
141162
let rv = {};
142-
var nodeStorage = this.wizardForm.newClusterConfig.get("clusterStorage");
163+
let nodeStorage = this.wizardForm.newClusterConfig.get("clusterStorage");
164+
let addressFamilyUI = nodeStorage.get("hostConfig.addressFamilyUI").value;
143165
rv.hostname = nodeStorage.get("hostname").value;
144166
rv.dataPath = nodeStorage.get("storage.path").value;
145167
rv.indexPath = nodeStorage.get("storage.index_path").value;
146168
rv.eventingPath = nodeStorage.get("storage.eventing_path").value;
147169
rv.javaHome = nodeStorage.get("storage.java_home").value;
148170

149171
if (isEnterprise) {
150-
rv.afamily = nodeStorage.get("hostConfig.afamily").value ? "ipv6" : "ipv4";
172+
rv.afamily = this.getAddressFamily(addressFamilyUI);
151173
rv.analyticsPath = nodeStorage.get("storage.cbas_path").value;
152174
}
153175
return rv;

priv/public/ui/app/mn.wizard.service.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {FormGroup, FormControl, Validators, FormArray} from "/ui/web_modules/@an
1212
import {Injectable} from "/ui/web_modules/@angular/core.js";
1313
import {HttpClient, HttpParams} from '/ui/web_modules/@angular/common/http.js';
1414
import _ from '/ui/web_modules/lodash.js';
15-
import {BehaviorSubject, Subject, combineLatest} from '/ui/web_modules/rxjs.js';
16-
import {switchMap, shareReplay, withLatestFrom, first, map, pluck} from '/ui/web_modules/rxjs/operators.js';
15+
import {BehaviorSubject, combineLatest} from '/ui/web_modules/rxjs.js';
16+
import {switchMap, shareReplay, map, pluck} from '/ui/web_modules/rxjs/operators.js';
1717
import {MnHelperService} from './mn.helper.service.js';
1818
import {MnAdminService} from './mn.admin.service.js';
1919
import {MnPoolsService} from './mn.pools.service.js';
@@ -24,7 +24,7 @@ export {MnWizardService};
2424
var clusterStorage = new FormGroup({
2525
hostname: new FormControl(null, [Validators.required]),
2626
hostConfig: new FormGroup({
27-
afamily: new FormControl(),
27+
addressFamilyUI: new FormControl(),
2828
nodeEncryption: new FormControl()
2929
}),
3030
storage: new FormGroup({
@@ -212,6 +212,10 @@ class MnWizardService {
212212
// }, []);
213213
}
214214

215+
getAddressFamilyUI(config) {
216+
return config.addressFamily + (config.addressFamilyOnly ? "Only" : "");
217+
}
218+
215219
setSelfConfig(selfConfig) {
216220
var hostname = selfConfig.configuredHostname;
217221

@@ -232,7 +236,7 @@ class MnWizardService {
232236
wizardForm.newClusterConfig.get("clusterStorage.hostname").setValue(hostname);
233237
wizardForm.joinCluster.get("clusterStorage.hostname").setValue(hostname);
234238
wizardForm.newClusterConfig.get("clusterStorage.hostConfig").patchValue({
235-
afamily: selfConfig.addressFamily == "inet6",
239+
addressFamilyUI: this.getAddressFamilyUI(selfConfig),
236240
nodeEncryption: selfConfig.nodeEncryption
237241
});
238242
this.initialValues.hostname = hostname;

priv/public/ui/app/mn_admin/mn_servers_list_item_details.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
</span>
2121
</div>
2222
<div ng-if="node.hasOwnProperty('addressFamily')">
23-
<strong>Address Family:</strong> <span ng-if="node.addressFamily == 'inet6'">IPv6</span><span ng-if="node.addressFamily == 'inet'">IPv4</span>
23+
<strong>Address Family:</strong>
24+
<span ng-if="node.addressFamily == 'inet6'">IPv6</span><span ng-if="node.addressFamily == 'inet'">IPv4</span><span ng-if="node.addressFamilyOnly">-only</span>
2425
</div>
2526
<div>
2627
<strong>Node-to-Node Encryption:</strong> <span ng-if="node.nodeEncryption">enabled</span><span ng-if="!node.nodeEncryption">off</span>

0 commit comments

Comments
 (0)