Skip to content

Commit 6bbc2e5

Browse files
Merge remote-tracking branch 'couchbase/cheshire-cat'
* 19f6192 MB-46178 Add IP address family option to new cluster wizard * d246283 MB-46980: show "delete group" if user has write permission * 66782e5 MB-46980: show 'move to' if user has write permission * 7af9d40 MB-47499: enable form submission when form is ready * 46edad8 MB-47761: save ephemeral bucket durabilityMinLevel value * f6ea179 MB-35881 Limit DCP connection names to 200 chars max Change-Id: Icd4b07ef23fa44a1d37ffd824227e9c75e2f7933
2 parents 0e74efc + 19f6192 commit 6bbc2e5

14 files changed

+309
-90
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 '../web_modules/@uirouter/angular.js';
1212
import {MnLifeCycleHooksToStream} from './mn.core.js';
1313
import {Component, ChangeDetectionStrategy} from '../web_modules/@angular/core.js';
14-
import {takeUntil, filter, map,
15-
tap, withLatestFrom, first} from '../web_modules/rxjs/operators.js';
16-
import {BehaviorSubject, pipe} from '../web_modules/rxjs.js';
14+
import {map, withLatestFrom, first} from '../web_modules/rxjs/operators.js';
15+
import {pipe} from '../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: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ be governed by the Apache License, Version 2.0, included in the file
88
licenses/APL2.txt.
99
*/
1010

11+
1112
import {FormGroup, FormControl, Validators, FormArray} from "../web_modules/@angular/forms.js";
1213
import {Injectable} from "../web_modules/@angular/core.js";
1314
import {HttpClient, HttpParams} from '../web_modules/@angular/common/http.js';
1415
import _ from '../web_modules/lodash.js';
15-
import {BehaviorSubject, Subject, combineLatest} from '../web_modules/rxjs.js';
16-
import {switchMap, shareReplay, withLatestFrom, first, map, pluck} from '../web_modules/rxjs/operators.js';
16+
import {BehaviorSubject, combineLatest} from '../web_modules/rxjs.js';
17+
import {switchMap, shareReplay, map, pluck} from '../web_modules/rxjs/operators.js';
1718
import {MnHelperService} from './mn.helper.service.js';
1819
import {MnAdminService} from './mn.admin.service.js';
1920
import {MnPoolsService} from './mn.pools.service.js';
@@ -24,7 +25,7 @@ export {MnWizardService};
2425
var clusterStorage = new FormGroup({
2526
hostname: new FormControl(null, [Validators.required]),
2627
hostConfig: new FormGroup({
27-
afamily: new FormControl(),
28+
addressFamilyUI: new FormControl(),
2829
nodeEncryption: new FormControl()
2930
}),
3031
storage: new FormGroup({
@@ -212,6 +213,10 @@ class MnWizardService {
212213
// }, []);
213214
}
214215

216+
getAddressFamilyUI(config) {
217+
return config.addressFamily + (config.addressFamilyOnly ? "Only" : "");
218+
}
219+
215220
setSelfConfig(selfConfig) {
216221
var hostname = selfConfig.configuredHostname;
217222

@@ -232,7 +237,7 @@ class MnWizardService {
232237
wizardForm.newClusterConfig.get("clusterStorage.hostname").setValue(hostname);
233238
wizardForm.joinCluster.get("clusterStorage.hostname").setValue(hostname);
234239
wizardForm.newClusterConfig.get("clusterStorage.hostConfig").patchValue({
235-
afamily: selfConfig.addressFamily == "inet6",
240+
addressFamilyUI: this.getAddressFamilyUI(selfConfig),
236241
nodeEncryption: selfConfig.nodeEncryption
237242
});
238243
this.initialValues.hostname = hostname;

priv/public/ui/app/mn_admin/mn_buckets_details_dialog_service.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ function mnBucketsDetailsDialogServiceFactory($http, $q, mnBytesToMBFilter, mnCo
6767
}
6868
}
6969
if (isMembase) {
70-
copyProperties(["autoCompactionDefined", "evictionPolicy", "durabilityMinLevel"]);
70+
copyProperties(["autoCompactionDefined", "evictionPolicy"]);
7171
}
7272
if (bucketConf.bucketType === "ephemeral") {
7373
copyProperties(["purgeInterval", "durabilityMinLevel"]);
7474
conf["evictionPolicy"] = bucketConf["evictionPolicyEphemeral"];
7575
}
7676

7777
if (isMembase || bucketConf.bucketType === "ephemeral") {
78-
copyProperties(["threadsNumber", "replicaNumber"]);
78+
copyProperties(["threadsNumber", "replicaNumber", "durabilityMinLevel"]);
7979
if (pools.isEnterprise && poolDefault.compat.atLeast55) {
8080
copyProperty("compressionMode");
8181
if (!bucketConf.enableMaxTTL) {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ <h4 class="ellipsis">{{group.name}}&nbsp;
8282
</span>
8383
<span class="cbui-table-cell wrap text-right">
8484
<div uib-dropdown ng-show="!server.toGroupPending && groupsCtl.state.groups.length > 1" class="mn-dropdown-menu">
85-
<div uib-dropdown-toggle class="menu-toggle">move to <span class="icon fa-caret-down"></span></div>
85+
<div
86+
ng-show="rbac.cluster.server_groups.write"
87+
uib-dropdown-toggle class="menu-toggle">move to
88+
<span class="icon fa-caret-down"></span>
89+
</div>
8690
<div uib-dropdown-menu class="dropdown-menu-select-like">
8791
<a
8892
ng-show="groupNew.name !== group.name"
@@ -110,6 +114,7 @@ <h4 class="ellipsis">{{group.name}}&nbsp;
110114
This group is empty.
111115
<a
112116
ng-click="groupsCtl.deleteGroup(group)"
117+
ng-show="rbac.cluster.server_groups.write"
113118
class="indent-1">
114119
delete group
115120
</a>

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>

priv/public/ui/app/mn_admin/mn_settings_auto_failover_controller.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,15 @@ function mnSettingsAutoFailoverController($scope, $q, mnPromiseHelper, mnSetting
3232
var vm = this;
3333

3434
mnSettingsClusterService.registerSubmitCallback(submit);
35+
mnSettingsClusterService.registerInitChecker(() => (!!vm.autoFailoverSettings &&
36+
!!vm.reprovisionSettings));
3537

3638
activate();
3739

3840
function getAutoFailoverSettings() {
41+
if (!vm.autoFailoverSettings) {
42+
return;
43+
}
3944
var settings = {
4045
enabled: vm.autoFailoverSettings.enabled,
4146
timeout: vm.autoFailoverSettings.timeout

0 commit comments

Comments
 (0)