ui: Add ServerExternalAddresses to peer token create form (#15555)
* ui: Add ServerExternalAddresses field to token generation * Add test for ServerExternalAddresses on peer token create * Add changelog entry * Update translations * Format hbs files * Update translations
This commit is contained in:
parent
a8411976a8
commit
4a7fe5625a
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:feature
|
||||||
|
ui: Add field for fallback server addresses to peer token generation form
|
||||||
|
```
|
|
@ -1,38 +1,54 @@
|
||||||
<div
|
<div class={{class-map "consul-peer-form-generate-fieldsets"}} ...attributes>
|
||||||
class={{class-map
|
|
||||||
'consul-peer-form-generate-fieldsets'
|
|
||||||
}}
|
|
||||||
...attributes
|
|
||||||
>
|
|
||||||
<StateMachine
|
<StateMachine
|
||||||
@src={{require '/machines/validate.xstate' from="/components/consul/peer/form/generate/fieldsets"}}
|
@src={{require
|
||||||
as |fsm|>
|
"/machines/validate.xstate"
|
||||||
|
from="/components/consul/peer/form/generate/fieldsets"
|
||||||
|
}}
|
||||||
|
as |fsm|
|
||||||
|
>
|
||||||
{{#let
|
{{#let
|
||||||
(hash
|
(hash
|
||||||
help=(concat
|
help=(concat
|
||||||
(t 'common.validations.dns-hostname.help')
|
(t "common.validations.dns-hostname.help")
|
||||||
(t 'common.validations.immutable.help')
|
(t "common.validations.immutable.help")
|
||||||
)
|
)
|
||||||
Name=(array
|
Name=(array
|
||||||
(hash
|
(hash
|
||||||
test=(t 'common.validations.dns-hostname.test')
|
test=(t "common.validations.dns-hostname.test")
|
||||||
error=(t 'common.validations.dns-hostname.error' name="Name")
|
error=(t "common.validations.dns-hostname.error" name="Name")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
as |Name|}}
|
as |Name|
|
||||||
|
}}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<TextInput
|
<TextInput
|
||||||
@label="Name of peer"
|
@label={{t "components.consul.peer.generate.name"}}
|
||||||
@name="Name"
|
@name="Name"
|
||||||
@item={{@item}}
|
@item={{@item}}
|
||||||
@validations={{Name}}
|
@validations={{Name}}
|
||||||
@chart={{fsm}}
|
@chart={{fsm}}
|
||||||
@oninput={{pick 'target.value' (set @item 'Name')}}
|
@oninput={{pick "target.value" (set @item "Name")}}
|
||||||
/>
|
/>
|
||||||
{{yield (hash
|
{{yield (hash valid=(not (state-matches fsm.state "error")))}}
|
||||||
valid=(not (state-matches fsm.state 'error'))
|
</fieldset>
|
||||||
)}}
|
|
||||||
|
{{/let}}
|
||||||
|
|
||||||
|
{{#let
|
||||||
|
(hash help=(t "common.validations.server-external-addresses.help"))
|
||||||
|
as |ServerExternalAddresses|
|
||||||
|
}}
|
||||||
|
<fieldset>
|
||||||
|
<TextInput
|
||||||
|
@label={{t "components.consul.peer.generate.addresses"}}
|
||||||
|
@name="ServerExternalAddresses"
|
||||||
|
@item={{@item}}
|
||||||
|
@chart={{fsm}}
|
||||||
|
@validations={{ServerExternalAddresses}}
|
||||||
|
@oninput={{pick "target.value" this.onInput}}
|
||||||
|
/>
|
||||||
|
{{yield (hash valid=(not (state-matches fsm.state "error")))}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
{{/let}}
|
{{/let}}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import Component from '@glimmer/component';
|
||||||
|
import { action } from '@ember/object';
|
||||||
|
|
||||||
|
export default class PeerGenerateFieldSets extends Component {
|
||||||
|
@action
|
||||||
|
onInput(addresses) {
|
||||||
|
if (addresses) {
|
||||||
|
addresses = addresses.split(',').map(address => address.trim());
|
||||||
|
} else {
|
||||||
|
addresses = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.args.item.ServerExternalAddresses = addresses;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +1,19 @@
|
||||||
<div
|
<div class={{class-map "consul-peer-form-generate"}} ...attributes>
|
||||||
class={{class-map
|
|
||||||
'consul-peer-form-generate'
|
|
||||||
}}
|
|
||||||
...attributes
|
|
||||||
>
|
|
||||||
<StateMachine
|
<StateMachine
|
||||||
@src={{require './chart.xstate' from="/components/consul/peer/form/generate"}}
|
@src={{require
|
||||||
@initial={{if @regenerate 'loading' 'idle'}}
|
"./chart.xstate"
|
||||||
as |fsm|>
|
from="/components/consul/peer/form/generate"
|
||||||
|
}}
|
||||||
{{#let
|
@initial={{if @regenerate "loading" "idle"}}
|
||||||
(unique-id)
|
as |fsm|
|
||||||
as |id reset|}}
|
|
||||||
<form
|
|
||||||
{{on 'submit' (fn fsm.dispatch 'LOAD')}}
|
|
||||||
id={{id}}
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<fsm.State @matches={{array 'idle' 'error'}}>
|
{{#let (unique-id) as |id reset|}}
|
||||||
<fsm.State @matches={{'error'}}>
|
<form {{on "submit" (fn fsm.dispatch "LOAD")}} id={{id}}>
|
||||||
<Notice
|
|
||||||
@type="error"
|
<fsm.State @matches={{array "idle" "error"}}>
|
||||||
role="alert"
|
<fsm.State @matches={{"error"}}>
|
||||||
as |notice|>
|
<Notice @type="error" role="alert" as |notice|>
|
||||||
<notice.Body>
|
<notice.Body>
|
||||||
<p>
|
<p>
|
||||||
<strong>Error</strong><br />
|
<strong>Error</strong><br />
|
||||||
|
@ -31,54 +22,56 @@
|
||||||
</notice.Body>
|
</notice.Body>
|
||||||
</Notice>
|
</Notice>
|
||||||
</fsm.State>
|
</fsm.State>
|
||||||
{{yield (hash
|
{{yield
|
||||||
Fieldsets=(component "consul/peer/form/generate/fieldsets"
|
(hash
|
||||||
item=@item
|
Fieldsets=(component
|
||||||
|
"consul/peer/form/generate/fieldsets" item=@item
|
||||||
)
|
)
|
||||||
Actions=(component "consul/peer/form/generate/actions"
|
Actions=(component
|
||||||
item=@item
|
"consul/peer/form/generate/actions" item=@item id=id
|
||||||
id=id
|
|
||||||
)
|
)
|
||||||
)}}
|
)
|
||||||
|
}}
|
||||||
</fsm.State>
|
</fsm.State>
|
||||||
|
|
||||||
<fsm.State @matches={{'loading'}}>
|
<fsm.State @matches={{"loading"}}>
|
||||||
<DataSource
|
<DataSource
|
||||||
@src={{uri '/${partition}/${nspace}/${dc}/peering/token-for/${name}'
|
@src={{uri
|
||||||
|
"/${partition}/${nspace}/${dc}/peering/token-for/${name}/${externalAddresses}"
|
||||||
(hash
|
(hash
|
||||||
partition=@item.Partition
|
partition=@item.Partition
|
||||||
nspace=''
|
nspace=""
|
||||||
dc=@item.Datacenter
|
dc=@item.Datacenter
|
||||||
name=@item.Name
|
name=@item.Name
|
||||||
|
externalAddresses=@item.ServerExternalAddresses
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@onchange={{queue
|
@onchange={{queue
|
||||||
@onchange
|
@onchange
|
||||||
(pick 'data' (fn fsm.dispatch 'SUCCESS'))
|
(pick "data" (fn fsm.dispatch "SUCCESS"))
|
||||||
}}
|
|
||||||
@onerror={{queue
|
|
||||||
(fn fsm.dispatch 'ERROR')
|
|
||||||
}}
|
}}
|
||||||
|
@onerror={{queue (fn fsm.dispatch "ERROR")}}
|
||||||
/>
|
/>
|
||||||
</fsm.State>
|
</fsm.State>
|
||||||
|
|
||||||
<fsm.State @matches={{'success'}}>
|
<fsm.State @matches={{"success"}}>
|
||||||
{{yield (hash
|
{{yield
|
||||||
Fieldsets=(component "consul/peer/form/token/fieldsets"
|
(hash
|
||||||
|
Fieldsets=(component
|
||||||
|
"consul/peer/form/token/fieldsets"
|
||||||
item=@item
|
item=@item
|
||||||
token=fsm.state.context.PeeringToken
|
token=fsm.state.context.PeeringToken
|
||||||
regenerate=@regenerate
|
regenerate=@regenerate
|
||||||
onclick=(queue
|
onclick=(queue (set @item "Name" "") (fn fsm.dispatch "RESET"))
|
||||||
(set @item 'Name' '')
|
|
||||||
(fn fsm.dispatch 'RESET')
|
|
||||||
)
|
)
|
||||||
)
|
Actions=(component
|
||||||
Actions=(component "consul/peer/form/token/actions"
|
"consul/peer/form/token/actions"
|
||||||
token=fsm.state.context.PeeringToken
|
token=fsm.state.context.PeeringToken
|
||||||
item=@item
|
item=@item
|
||||||
id=id
|
id=id
|
||||||
)
|
)
|
||||||
)}}
|
)
|
||||||
|
}}
|
||||||
</fsm.State>
|
</fsm.State>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,41 +1,33 @@
|
||||||
<div
|
<div class={{class-map "consul-peer-form"}} ...attributes>
|
||||||
class={{class-map
|
|
||||||
'consul-peer-form'
|
|
||||||
}}
|
|
||||||
...attributes
|
|
||||||
>
|
|
||||||
<StateMachine
|
<StateMachine
|
||||||
@src={{require './chart.xstate' from='/components/consul/peer/form'}}
|
@src={{require "./chart.xstate" from="/components/consul/peer/form"}}
|
||||||
as |fsm|>
|
as |fsm|
|
||||||
|
>
|
||||||
|
|
||||||
<TabNav
|
<TabNav
|
||||||
@items={{array
|
@items={{array
|
||||||
(hash
|
(hash
|
||||||
label='Generate token'
|
label=(t "components.consul.peer.form.generate-label")
|
||||||
selected=(state-matches fsm.state 'generate')
|
selected=(state-matches fsm.state "generate")
|
||||||
state="GENERATE"
|
state="GENERATE"
|
||||||
)
|
)
|
||||||
(hash
|
(hash
|
||||||
label='Establish peering'
|
label=(t "components.consul.peer.form.establish-label")
|
||||||
selected=(state-matches fsm.state 'initiate')
|
selected=(state-matches fsm.state "initiate")
|
||||||
state="INITIATE"
|
state="INITIATE"
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@onTabClicked={{pick 'state' fsm.dispatch}}
|
@onTabClicked={{pick "state" fsm.dispatch}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<fsm.State @matches={{array 'generate'}}>
|
<fsm.State @matches={{array "generate"}}>
|
||||||
|
|
||||||
<DataSource
|
<DataSource
|
||||||
@src={{uri '/${partition}/${nspace}/${dc}/peer-generate/'
|
@src={{uri "/${partition}/${nspace}/${dc}/peer-generate/" @params}}
|
||||||
@params
|
as |source|
|
||||||
}}
|
>
|
||||||
as |source|>
|
{{yield
|
||||||
{{yield (hash
|
(hash Form=(component "consul/peer/form/generate" item=source.data))
|
||||||
Form=(component 'consul/peer/form/generate'
|
|
||||||
item=source.data
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
</DataSource>
|
</DataSource>
|
||||||
|
|
||||||
|
@ -44,20 +36,15 @@
|
||||||
<fsm.State @matches="initiate">
|
<fsm.State @matches="initiate">
|
||||||
|
|
||||||
<DataSource
|
<DataSource
|
||||||
@src={{uri '/${partition}/${nspace}/${dc}/peer-initiate/'
|
@src={{uri "/${partition}/${nspace}/${dc}/peer-initiate/" @params}}
|
||||||
@params
|
as |source|
|
||||||
}}
|
>
|
||||||
as |source|>
|
{{yield
|
||||||
{{yield (hash
|
(hash Form=(component "consul/peer/form/initiate" item=source.data))
|
||||||
Form=(component 'consul/peer/form/initiate'
|
|
||||||
item=source.data
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
</DataSource>
|
</DataSource>
|
||||||
|
|
||||||
</fsm.State>
|
</fsm.State>
|
||||||
|
|
||||||
|
|
||||||
</StateMachine>
|
</StateMachine>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,8 @@ export default class Peer extends Model {
|
||||||
@attr('string') Name;
|
@attr('string') Name;
|
||||||
@attr('string') State;
|
@attr('string') State;
|
||||||
@attr('string') ID;
|
@attr('string') ID;
|
||||||
|
@attr('string') ServerExternalAddresses;
|
||||||
|
@nullValue([]) @attr() ServerExternalAddresses;
|
||||||
|
|
||||||
// only the side that establishes will hold this property
|
// only the side that establishes will hold this property
|
||||||
@attr('string') PeerID;
|
@attr('string') PeerID;
|
||||||
|
|
|
@ -44,8 +44,11 @@ export default class PeerService extends RepositoryService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@dataSource('/:partition/:ns/:dc/peering/token-for/:name')
|
@dataSource('/:partition/:ns/:dc/peering/token-for/:name/:externalAddresses')
|
||||||
async fetchToken({ dc, ns, partition, name }, configuration, request) {
|
async fetchToken({ dc, ns, partition, name, externalAddresses }, configuration, request) {
|
||||||
|
const ServerExternalAddresses =
|
||||||
|
externalAddresses?.length > 0 ? externalAddresses.split(',') : [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
await request`
|
await request`
|
||||||
POST /v1/peering/token
|
POST /v1/peering/token
|
||||||
|
@ -53,6 +56,7 @@ export default class PeerService extends RepositoryService {
|
||||||
${{
|
${{
|
||||||
PeerName: name,
|
PeerName: name,
|
||||||
Partition: partition || undefined,
|
Partition: partition || undefined,
|
||||||
|
ServerExternalAddresses,
|
||||||
}}
|
}}
|
||||||
`
|
`
|
||||||
)((headers, body, cache) => body);
|
)((headers, body, cache) => body);
|
||||||
|
|
|
@ -22,6 +22,7 @@ Feature: dc / peers / create: Peer Create Token
|
||||||
---
|
---
|
||||||
body:
|
body:
|
||||||
PeerName: new-peer
|
PeerName: new-peer
|
||||||
|
ServerExternalAddresses: []
|
||||||
---
|
---
|
||||||
Then I see the text "an-encoded-token" in ".consul-peer-form-generate code"
|
Then I see the text "an-encoded-token" in ".consul-peer-form-generate code"
|
||||||
When I click ".consul-peer-form-generate button[type=reset]"
|
When I click ".consul-peer-form-generate button[type=reset]"
|
||||||
|
@ -33,11 +34,13 @@ Feature: dc / peers / create: Peer Create Token
|
||||||
Then I fill in with yaml
|
Then I fill in with yaml
|
||||||
---
|
---
|
||||||
Name: another-new-peer
|
Name: another-new-peer
|
||||||
|
ServerExternalAddresses: "1.1.1.1:123,1.2.3.4:3202"
|
||||||
---
|
---
|
||||||
When I click ".peer-create-modal .modal-dialog-footer button"
|
When I click ".peer-create-modal .modal-dialog-footer button"
|
||||||
Then a POST request was made to "/v1/peering/token" from yaml
|
Then a POST request was made to "/v1/peering/token" from yaml
|
||||||
---
|
---
|
||||||
body:
|
body:
|
||||||
PeerName: another-new-peer
|
PeerName: another-new-peer
|
||||||
|
ServerExternalAddresses: ["1.1.1.1:123","1.2.3.4:3202"]
|
||||||
---
|
---
|
||||||
Then I see the text "another-encoded-token" in ".consul-peer-form-generate code"
|
Then I see the text "another-encoded-token" in ".consul-peer-form-generate code"
|
||||||
|
|
|
@ -81,4 +81,6 @@ validations:
|
||||||
error: "{name} must be a valid DNS hostname."
|
error: "{name} must be a valid DNS hostname."
|
||||||
immutable:
|
immutable:
|
||||||
help: Once created, this cannot be changed.
|
help: Once created, this cannot be changed.
|
||||||
|
server-external-addresses:
|
||||||
|
help: |
|
||||||
|
Enter a comma separated list of this peer's fallback server address(es) to be used in the event of failed automatic updates. This field is required for HCP-managed clusters.
|
||||||
|
|
|
@ -14,6 +14,12 @@ peer:
|
||||||
name: Status
|
name: Status
|
||||||
asc: Pending to Deleting
|
asc: Pending to Deleting
|
||||||
desc: Deleting to Pending
|
desc: Deleting to Pending
|
||||||
|
form:
|
||||||
|
generate-label: Generate token
|
||||||
|
establish-label: Establish peering
|
||||||
|
generate:
|
||||||
|
name: 'Name of peer'
|
||||||
|
addresses: 'Server address(es)'
|
||||||
service:
|
service:
|
||||||
search-bar:
|
search-bar:
|
||||||
kind: Service Type
|
kind: Service Type
|
||||||
|
|
Loading…
Reference in New Issue