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:
Tyler Wendlandt 2022-11-30 11:42:36 -07:00 committed by GitHub
parent a8411976a8
commit 4a7fe5625a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 161 additions and 130 deletions

3
.changelog/15555.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:feature
ui: Add field for fallback server addresses to peer token generation form
```

View File

@ -1,38 +1,54 @@
<div
class={{class-map
'consul-peer-form-generate-fieldsets'
}}
...attributes
>
<div class={{class-map "consul-peer-form-generate-fieldsets"}} ...attributes>
<StateMachine
@src={{require '/machines/validate.xstate' from="/components/consul/peer/form/generate/fieldsets"}}
as |fsm|>
@src={{require
"/machines/validate.xstate"
from="/components/consul/peer/form/generate/fieldsets"
}}
as |fsm|
>
{{#let
(hash
help=(concat
(t 'common.validations.dns-hostname.help')
(t 'common.validations.immutable.help')
(t "common.validations.dns-hostname.help")
(t "common.validations.immutable.help")
)
Name=(array
(hash
test=(t 'common.validations.dns-hostname.test')
error=(t 'common.validations.dns-hostname.error' name="Name")
test=(t "common.validations.dns-hostname.test")
error=(t "common.validations.dns-hostname.error" name="Name")
)
)
)
as |Name|}}
as |Name|
}}
<fieldset>
<TextInput
@label="Name of peer"
@label={{t "components.consul.peer.generate.name"}}
@name="Name"
@item={{@item}}
@validations={{Name}}
@chart={{fsm}}
@oninput={{pick 'target.value' (set @item 'Name')}}
@oninput={{pick "target.value" (set @item "Name")}}
/>
{{yield (hash
valid=(not (state-matches fsm.state 'error'))
)}}
{{yield (hash 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>
{{/let}}

View File

@ -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;
}
}

View File

@ -1,88 +1,81 @@
<div
class={{class-map
'consul-peer-form-generate'
}}
...attributes
>
<div class={{class-map "consul-peer-form-generate"}} ...attributes>
<StateMachine
@src={{require './chart.xstate' from="/components/consul/peer/form/generate"}}
@initial={{if @regenerate 'loading' 'idle'}}
as |fsm|>
@src={{require
"./chart.xstate"
from="/components/consul/peer/form/generate"
}}
@initial={{if @regenerate "loading" "idle"}}
as |fsm|
>
{{#let
(unique-id)
as |id reset|}}
<form
{{on 'submit' (fn fsm.dispatch 'LOAD')}}
id={{id}}
>
{{#let (unique-id) as |id reset|}}
<form {{on "submit" (fn fsm.dispatch "LOAD")}} id={{id}}>
<fsm.State @matches={{array 'idle' 'error'}}>
<fsm.State @matches={{'error'}}>
<Notice
@type="error"
role="alert"
as |notice|>
<notice.Body>
<p>
<strong>Error</strong><br />
{{fsm.state.context.error.message}}
</p>
</notice.Body>
</Notice>
</fsm.State>
{{yield (hash
Fieldsets=(component "consul/peer/form/generate/fieldsets"
item=@item
)
Actions=(component "consul/peer/form/generate/actions"
item=@item
id=id
)
)}}
</fsm.State>
<fsm.State @matches={{'loading'}}>
<DataSource
@src={{uri '/${partition}/${nspace}/${dc}/peering/token-for/${name}'
<fsm.State @matches={{array "idle" "error"}}>
<fsm.State @matches={{"error"}}>
<Notice @type="error" role="alert" as |notice|>
<notice.Body>
<p>
<strong>Error</strong><br />
{{fsm.state.context.error.message}}
</p>
</notice.Body>
</Notice>
</fsm.State>
{{yield
(hash
partition=@item.Partition
nspace=''
dc=@item.Datacenter
name=@item.Name
Fieldsets=(component
"consul/peer/form/generate/fieldsets" item=@item
)
Actions=(component
"consul/peer/form/generate/actions" item=@item id=id
)
)
}}
@onchange={{queue
@onchange
(pick 'data' (fn fsm.dispatch 'SUCCESS'))
}}
@onerror={{queue
(fn fsm.dispatch 'ERROR')
}}
/>
</fsm.State>
</fsm.State>
<fsm.State @matches={{'success'}}>
{{yield (hash
Fieldsets=(component "consul/peer/form/token/fieldsets"
item=@item
token=fsm.state.context.PeeringToken
regenerate=@regenerate
onclick=(queue
(set @item 'Name' '')
(fn fsm.dispatch 'RESET')
<fsm.State @matches={{"loading"}}>
<DataSource
@src={{uri
"/${partition}/${nspace}/${dc}/peering/token-for/${name}/${externalAddresses}"
(hash
partition=@item.Partition
nspace=""
dc=@item.Datacenter
name=@item.Name
externalAddresses=@item.ServerExternalAddresses
)
}}
@onchange={{queue
@onchange
(pick "data" (fn fsm.dispatch "SUCCESS"))
}}
@onerror={{queue (fn fsm.dispatch "ERROR")}}
/>
</fsm.State>
<fsm.State @matches={{"success"}}>
{{yield
(hash
Fieldsets=(component
"consul/peer/form/token/fieldsets"
item=@item
token=fsm.state.context.PeeringToken
regenerate=@regenerate
onclick=(queue (set @item "Name" "") (fn fsm.dispatch "RESET"))
)
Actions=(component
"consul/peer/form/token/actions"
token=fsm.state.context.PeeringToken
item=@item
id=id
)
)
)
Actions=(component "consul/peer/form/token/actions"
token=fsm.state.context.PeeringToken
item=@item
id=id
)
)}}
</fsm.State>
}}
</fsm.State>
</form>
{{/let}}
</form>
{{/let}}
</StateMachine>
</div>

View File

@ -1,42 +1,34 @@
<div
class={{class-map
'consul-peer-form'
}}
...attributes
>
<div class={{class-map "consul-peer-form"}} ...attributes>
<StateMachine
@src={{require './chart.xstate' from='/components/consul/peer/form'}}
as |fsm|>
@src={{require "./chart.xstate" from="/components/consul/peer/form"}}
as |fsm|
>
<TabNav
@items={{array
(hash
label='Generate token'
selected=(state-matches fsm.state 'generate')
label=(t "components.consul.peer.form.generate-label")
selected=(state-matches fsm.state "generate")
state="GENERATE"
)
(hash
label='Establish peering'
selected=(state-matches fsm.state 'initiate')
label=(t "components.consul.peer.form.establish-label")
selected=(state-matches fsm.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
@src={{uri '/${partition}/${nspace}/${dc}/peer-generate/'
@params
@src={{uri "/${partition}/${nspace}/${dc}/peer-generate/" @params}}
as |source|
>
{{yield
(hash Form=(component "consul/peer/form/generate" item=source.data))
}}
as |source|>
{{yield (hash
Form=(component 'consul/peer/form/generate'
item=source.data
)
)
}}
</DataSource>
</fsm.State>
@ -44,20 +36,15 @@
<fsm.State @matches="initiate">
<DataSource
@src={{uri '/${partition}/${nspace}/${dc}/peer-initiate/'
@params
@src={{uri "/${partition}/${nspace}/${dc}/peer-initiate/" @params}}
as |source|
>
{{yield
(hash Form=(component "consul/peer/form/initiate" item=source.data))
}}
as |source|>
{{yield (hash
Form=(component 'consul/peer/form/initiate'
item=source.data
)
)
}}
</DataSource>
</fsm.State>
</StateMachine>
</div>

View File

@ -17,6 +17,8 @@ export default class Peer extends Model {
@attr('string') Name;
@attr('string') State;
@attr('string') ID;
@attr('string') ServerExternalAddresses;
@nullValue([]) @attr() ServerExternalAddresses;
// only the side that establishes will hold this property
@attr('string') PeerID;

View File

@ -44,8 +44,11 @@ export default class PeerService extends RepositoryService {
});
}
@dataSource('/:partition/:ns/:dc/peering/token-for/:name')
async fetchToken({ dc, ns, partition, name }, configuration, request) {
@dataSource('/:partition/:ns/:dc/peering/token-for/:name/:externalAddresses')
async fetchToken({ dc, ns, partition, name, externalAddresses }, configuration, request) {
const ServerExternalAddresses =
externalAddresses?.length > 0 ? externalAddresses.split(',') : [];
return (
await request`
POST /v1/peering/token
@ -53,6 +56,7 @@ export default class PeerService extends RepositoryService {
${{
PeerName: name,
Partition: partition || undefined,
ServerExternalAddresses,
}}
`
)((headers, body, cache) => body);

View File

@ -22,6 +22,7 @@ Feature: dc / peers / create: Peer Create Token
---
body:
PeerName: new-peer
ServerExternalAddresses: []
---
Then I see the text "an-encoded-token" in ".consul-peer-form-generate code"
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
---
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"
Then a POST request was made to "/v1/peering/token" from yaml
---
body:
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"

View File

@ -81,4 +81,6 @@ validations:
error: "{name} must be a valid DNS hostname."
immutable:
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.

View File

@ -14,6 +14,12 @@ peer:
name: Status
asc: Pending to Deleting
desc: Deleting to Pending
form:
generate-label: Generate token
establish-label: Establish peering
generate:
name: 'Name of peer'
addresses: 'Server address(es)'
service:
search-bar:
kind: Service Type