Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui: Allow ${ } interpolation for UI Dashboard template URLs #11328

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions ui/packages/consul-ui/app/helpers/render-template.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';

// simple mustache regexp `/{{item.Name}}/`
const templateRe = /{{([A-Za-z.0-9_-]+)}}/g;
// regexp that matches {{item.Name}} or ${item.Name}
// what this regex does
// (?:\$|\{) - Match either $ or {
// \{ - Match {
// ([a-z.0-9_-]+) - Capturing group
// (?:(?<=\$\{[^{]+) - Use a positive lookbehind to assert that ${ was matched previously
// |\} ) - or match a }
// \} - Match }
const templateRe = /(?:\$|\{)\{([a-z.0-9_-]+)(?:(?<=\$\{[^{]+)|\})\}/gi;
let render;
export default class RenderTemplateHelper extends Helper {
@service('encoder') encoder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,133 @@ module('Integration | Helper | render-template', function(hooks) {
result: 'http://localhost/?=%23Na%2Fme',
},
].forEach(item => {
test('it renders', async function(assert) {
test('it renders {{}} style interpolation`', async function(assert) {
this.set('template', item.href);
this.set('vars', item.vars);

await render(hbs`{{render-template template vars}}`);

assert.equal(this.element.textContent.trim(), item.result);
});
});

[
{
href: 'http://localhost/?=${Name}/${ID}',
vars: {
Name: 'name',
ID: 'id',
},
result: 'http://localhost/?=name/id',
},
{
href: 'http://localhost/?=${Name}/${ID}',
vars: {
Name: '{{Name}}',
ID: '{{ID}}',
},
result: 'http://localhost/?=%7B%7BName%7D%7D/%7B%7BID%7D%7D',
},
{
href: 'http://localhost/?=${deep.Name}/${deep.ID}',
vars: {
deep: {
Name: '{{Name}}',
ID: '{{ID}}',
},
},
result: 'http://localhost/?=%7B%7BName%7D%7D/%7B%7BID%7D%7D',
},
{
href: 'http://localhost/?=${}/${}',
vars: {
Name: 'name',
ID: 'id',
},
// If you don't pass actual variables then nothing
// gets replaced and nothing is URL encoded
result: 'http://localhost/?=${}/${}',
},
{
href: 'http://localhost/?=${Service_Name}/${Meta-Key}',
vars: {
Service_Name: 'name',
['Meta-Key']: 'id',
},
result: 'http://localhost/?=name/id',
},
{
href: 'http://localhost/?=${Service_Name}/${Meta-Key}',
vars: {
WrongPropertyName: 'name',
['Meta-Key']: 'id',
},
result: 'http://localhost/?=/id',
},
{
href: 'http://localhost/?=${.Name}',
vars: {
['.Name']: 'name',
},
result: 'http://localhost/?=',
},
{
href: 'http://localhost/?=${.}',
vars: {
['.']: 'name',
},
result: 'http://localhost/?=',
},
{
href: 'http://localhost/?=${deep..Name}',
vars: {
deep: {
Name: 'Name',
ID: 'ID',
},
},
result: 'http://localhost/?=',
},
{
href: 'http://localhost/?=${deep.Name}',
vars: {
deep: {
Name: '#Na/me',
ID: 'ID',
},
},
result: 'http://localhost/?=%23Na%2Fme',
},
].forEach(item => {
test('it renders ${} style interpolation', async function(assert) {
this.set('template', item.href);
this.set('vars', item.vars);

await render(hbs`{{render-template template vars}}`);

assert.equal(this.element.textContent.trim(), item.result);
});
});

[
{
href: 'http://localhost/?=${Name}/{{ID}}',
vars: {
Name: 'name',
ID: 'id',
},
result: 'http://localhost/?=name/id',
},
{
href: 'http://localhost/?=${Name}}/{{ID}',
vars: {
Name: 'name',
ID: 'id',
},
result: 'http://localhost/?=name}/{{ID}',
},
].forEach(item => {
test('it renders both styles of interpolation when used together', async function(assert) {
this.set('template', item.href);
this.set('vars', item.vars);

Expand Down
8 changes: 5 additions & 3 deletions website/content/docs/agent/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2174,9 +2174,11 @@ bind_addr = "{{ GetPrivateInterfaces | include \"network\" \"10.0.0.0/8\" | attr

The placeholders available are:

- `{{Service.Name}}` - Replaced with the current service's name.
- `{{Service.Namespace}}` - Replaced with the current service's namespace or empty if namespaces are not enabled.
- `{{Datacenter}}` - Replaced with the current service's datacenter.
- `{{Service.Name}}` or `${Service.Name}` - Replaced with the current service's name.
- `{{Service.Namespace}}` or `${Service.Namespace}` - Replaced with the current service's namespace or empty if namespaces are not enabled.
- `{{Datacenter}}` or `${Datacenter}` - Replaced with the current service's datacenter.

~> **Note:** The `${}` style interpolation is only available from Consul TBD.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkirschner-hashicorp Should we add here something about that folks should probably prefer the style ${} to avoid any issues with helm? Or something to that effect?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johncowen: if we recommend ${ }, the ${ } option should be given first in the listing above, e.g.,:

`${Service.Name}` or `{{Service.Name}}` - Replaced with ...

Additionally, I agree that this sentence can be expanded to explain why ${ } is preferred (in version in which it is available). Speaking of versions... would this be in version 1.11.0+?

@johncowen : I'm actually not very familiar with configuring consul-k8s - are all things configurable for Consul also configurable through the Helm chart? (I don't see this option on the Helm docs page).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @jkirschner-hashicorp ,

Some more info here #10510 (comment) and hashicorp/consul-helm#1006.

Maybe we should get a changelog added here and then we can either ask @radiantly here to amend the ordering or we can merge and decide on the docs things ourselves from there. Up to you, pinging @david-yu also to see if he can help any of us further, he might have some info on the helm question.

Thanks all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'd be happy to amend the ordering and add a note on the style preference

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johncowen: once merged, would this be in the next 1.10 release (1.10.4)? Or 1.11.0+?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@radiantly : can you add a .changelog\11328.txt file with the content below (describing the change)?

```release-note:improvement
config: <brief description of the improvement you made here>
```

I thought the process of writing a changelog entry was already in the contributor docs, but I can't seem to find it... so that's something I'll fix!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the changelog note and amended the docs - I hope it is fine?


- `ui_dir` - **This field is deprecated in Consul 1.9.0. See the [`ui_config.dir`](#ui_config_dir) field instead.**
Equivalent to the [`-ui-dir`](#_ui_dir) command-line
Expand Down