From b65642564a311f07b572ce2e1d63e4b83cb20903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 8 Oct 2016 10:06:47 +0200 Subject: [PATCH 001/179] poc for new metric segment --- .../form_dropdown/form_dropdown.html | 13 ++ .../components/form_dropdown/form_dropdown.ts | 182 ++++++++++++++++++ public/app/core/core.ts | 2 + public/app/core/directives/metric_segment.js | 2 - .../elasticsearch/partials/bucket_agg.html | 3 +- .../elasticsearch/partials/metric_agg.html | 6 +- 6 files changed, 202 insertions(+), 6 deletions(-) create mode 100644 public/app/core/components/form_dropdown/form_dropdown.html create mode 100644 public/app/core/components/form_dropdown/form_dropdown.ts diff --git a/public/app/core/components/form_dropdown/form_dropdown.html b/public/app/core/components/form_dropdown/form_dropdown.html new file mode 100644 index 00000000000..34737eab27e --- /dev/null +++ b/public/app/core/components/form_dropdown/form_dropdown.html @@ -0,0 +1,13 @@ + + + + diff --git a/public/app/core/components/form_dropdown/form_dropdown.ts b/public/app/core/components/form_dropdown/form_dropdown.ts new file mode 100644 index 00000000000..fd363d3b75e --- /dev/null +++ b/public/app/core/components/form_dropdown/form_dropdown.ts @@ -0,0 +1,182 @@ +/// + +import config from 'app/core/config'; +import _ from 'lodash'; +import $ from 'jquery'; +import coreModule from '../../core_module'; + +function typeaheadMatcher(item) { + var str = this.query; + if (str[0] === '/') { str = str.substring(1); } + if (str[str.length - 1] === '/') { str = str.substring(0, str.length-1); } + return item.toLowerCase().match(str.toLowerCase()); +} + +export class FormDropdownCtrl { + inputElement: any; + linkElement: any; + value: any; + text: any; + display: any; + options: any; + cssClass: any; + allowCustom: any; + linkMode: boolean; + cancelBlur: any; + onChange: any; + + constructor(private $scope, $element, private $sce, private templateSrv) { + this.inputElement = $element.find('input').first(); + this.linkElement = $element.find('a').first(); + this.linkMode = true; + this.cancelBlur = null; + + if (this.options) { + var item = _.find(this.options, {value: this.value}); + this.updateDisplay(item ? item.text : this.value); + } + + this.inputElement.attr('data-provide', 'typeahead'); + this.inputElement.typeahead({ + source: this.typeaheadSource.bind(this), + minLength: 0, + items: 10000, + updater: this.typeaheadUpdater.bind(this), + matcher: typeaheadMatcher, + }); + + // modify typeahead lookup + // this = typeahead + var typeahead = this.inputElement.data('typeahead'); + typeahead.lookup = function () { + this.query = this.$element.val() || ''; + var items = this.source(this.query, $.proxy(this.process, this)); + return items ? this.process(items) : items; + }; + + this.linkElement.keydown(evt => { + // trigger typeahead on down arrow or enter key + if (evt.keyCode === 40 || evt.keyCode === 13) { + this.linkElement.click(); + } + }); + + this.inputElement.blur(this.inputBlur.bind(this)); + } + + typeaheadSource(query, callback) { + if (this.options) { + var typeaheadOptions = _.map(this.options, 'text'); + + // add current custom value + if (this.allowCustom) { + if (_.indexOf(typeaheadOptions, this.text) === -1) { + typeaheadOptions.unshift(this.text); + } + } + + callback(typeaheadOptions); + } + } + + typeaheadUpdater(text) { + if (text === this.text) { + clearTimeout(this.cancelBlur); + this.inputElement.focus(); + return text; + } + + this.inputElement.val(text); + this.switchToLink(true); + return text; + } + + switchToLink(fromClick) { + if (this.linkMode && !fromClick) { return; } + + clearTimeout(this.cancelBlur); + this.cancelBlur = null; + this.linkMode = true; + this.inputElement.hide(); + this.linkElement.show(); + this.updateValue(this.inputElement.val()); + } + + inputBlur() { + // happens long before the click event on the typeahead options + // need to have long delay because the blur + this.cancelBlur = setTimeout(this.switchToLink.bind(this), 200); + } + + updateValue(text) { + if (text === '' || this.text === text) { + return; + } + + this.$scope.$apply(() => { + var option = _.find(this.options, {text: text}); + + if (option) { + this.value = option.value; + this.updateDisplay(option.text); + } else if (this.allowCustom) { + this.value = text; + this.updateDisplay(text); + } + + // needs to call this after digest so + // property is synced with outerscope + this.$scope.$$postDigest(() => { + this.$scope.$apply(() => { + this.onChange(); + }); + }); + + }); + } + + updateDisplay(text) { + this.text = text; + this.display = this.$sce.trustAsHtml(this.templateSrv.highlightVariablesAsHtml(text)); + } + + open() { + this.inputElement.show(); + + this.inputElement.css('width', (Math.max(this.linkElement.width(), 80) + 16) + 'px'); + this.inputElement.focus(); + + this.linkElement.hide(); + this.linkMode = false; + + var typeahead = this.inputElement.data('typeahead'); + if (typeahead) { + this.inputElement.val(''); + typeahead.lookup(); + } + } +} + + + +export function formDropdownDirective() { + return { + restrict: 'E', + templateUrl: 'public/app/core/components/form_dropdown/form_dropdown.html', + controller: FormDropdownCtrl, + bindToController: true, + controllerAs: 'ctrl', + scope: { + value: "=", + options: "=", + getOptions: "&", + onChange: "&", + cssClass: "@", + allowCustom: "@", + }, + link: function() { + } + }; +} + +coreModule.directive('gfFormDropdown', formDropdownDirective); diff --git a/public/app/core/core.ts b/public/app/core/core.ts index d44cbf4dbfb..ea55c22be8f 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -35,6 +35,7 @@ import {switchDirective} from './components/switch'; import {dashboardSelector} from './components/dashboard_selector'; import {queryPartEditorDirective} from './components/query_part/query_part_editor'; import {WizardFlow} from './components/wizard/wizard'; +import {formDropdownDirective} from './components/form_dropdown/form_dropdown'; import 'app/core/controllers/all'; import 'app/core/services/all'; import 'app/core/routes/routes'; @@ -62,4 +63,5 @@ export { queryPartEditorDirective, WizardFlow, colors, + formDropdownDirective, }; diff --git a/public/app/core/directives/metric_segment.js b/public/app/core/directives/metric_segment.js index 2001073ed80..62805161155 100644 --- a/public/app/core/directives/metric_segment.js +++ b/public/app/core/directives/metric_segment.js @@ -143,7 +143,6 @@ function (_, $, coreModule) { $input.focus(); linkMode = false; - var typeahead = $input.data('typeahead'); if (typeahead) { $input.val(''); @@ -152,7 +151,6 @@ function (_, $, coreModule) { }); $input.blur($scope.inputBlur); - $compile(elem.contents())($scope); } }; diff --git a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html index 36e914d06e0..2b674a9fdf9 100644 --- a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html +++ b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html @@ -5,7 +5,8 @@ Then by - + + diff --git a/public/app/plugins/datasource/elasticsearch/partials/metric_agg.html b/public/app/plugins/datasource/elasticsearch/partials/metric_agg.html index faa12b5693d..472cfca37fa 100644 --- a/public/app/plugins/datasource/elasticsearch/partials/metric_agg.html +++ b/public/app/plugins/datasource/elasticsearch/partials/metric_agg.html @@ -11,9 +11,9 @@
- - - + + +
From 86ce3d5e45e823b4763ca1350b1a45f4bc558eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 17 May 2017 17:02:50 +0200 Subject: [PATCH 002/179] feat: in app query request & response troubleshooting --- public/app/core/services/backend_srv.ts | 8 ++- .../app/features/panel/metrics_ds_selector.ts | 53 +++++++++++++++++-- .../app/features/panel/metrics_panel_ctrl.ts | 2 +- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 16edc364340..85cc63d057f 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -4,6 +4,7 @@ import angular from 'angular'; import _ from 'lodash'; import config from 'app/core/config'; import coreModule from 'app/core/core_module'; +import appEvents from 'app/core/app_events'; export class BackendSrv { inFlightRequests = {}; @@ -150,7 +151,10 @@ export class BackendSrv { } } - return this.$http(options).catch(err => { + return this.$http(options).then(response => { + appEvents.emit('ds-request-response', response); + return response; + }).catch(err => { if (err.status === this.HTTP_REQUEST_CANCELLED) { throw {err, cancelled: true}; } @@ -179,7 +183,9 @@ export class BackendSrv { err.data.message = err.data.error; } + appEvents.emit('ds-request-error', err); throw err; + }).finally(() => { // clean up if (options.requestId) { diff --git a/public/app/features/panel/metrics_ds_selector.ts b/public/app/features/panel/metrics_ds_selector.ts index 7c4bc0ef495..67619837e30 100644 --- a/public/app/features/panel/metrics_ds_selector.ts +++ b/public/app/features/panel/metrics_ds_selector.ts @@ -2,10 +2,24 @@ import angular from 'angular'; import _ from 'lodash'; +import appEvents from 'app/core/app_events'; var module = angular.module('grafana.directives'); var template = ` + +
+
+
{{ctrl.lastError}}
+
+
+ +
+
+
{{ctrl.lastResponse}}
+
+
+
@@ -22,9 +36,9 @@ var template = `
-
+ +
+ +
+
`; @@ -45,9 +67,12 @@ export class MetricsDsSelectorCtrl { panelCtrl: any; datasources: any[]; current: any; + lastResponse: any; + lastError: any; + showResponse: boolean; /** @ngInject */ - constructor(private uiSegmentSrv, datasourceSrv) { + constructor($scope, private uiSegmentSrv, datasourceSrv) { this.datasources = datasourceSrv.getMetricSources(); var dsValue = this.panelCtrl.panel.datasource || null; @@ -63,7 +88,25 @@ export class MetricsDsSelectorCtrl { } this.dsSegment = uiSegmentSrv.newSegment({value: this.current.name, selectMode: true}); - this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add query', selectMode: true}); + this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true}); + + appEvents.on('ds-request-response', this.onRequestResponse.bind(this), $scope); + appEvents.on('ds-request-error', this.onRequestError.bind(this), $scope); + } + + onRequestResponse(data) { + console.log(data); + this.lastResponse = JSON.stringify(data, null, 2); + this.lastError = null; + } + + toggleShowResponse() { + this.showResponse = !this.showResponse; + } + + onRequestError(err) { + console.log(err); + this.lastError = JSON.stringify(err, null, 2); } getOptions(includeBuiltin) { @@ -79,6 +122,8 @@ export class MetricsDsSelectorCtrl { if (ds) { this.current = ds; this.panelCtrl.setDatasource(ds); + this.lastError = null; + this.lastResponse = null; } } diff --git a/public/app/features/panel/metrics_panel_ctrl.ts b/public/app/features/panel/metrics_panel_ctrl.ts index af9d06d8742..000705d74d5 100644 --- a/public/app/features/panel/metrics_panel_ctrl.ts +++ b/public/app/features/panel/metrics_panel_ctrl.ts @@ -256,7 +256,7 @@ class MetricsPanelCtrl extends PanelCtrl { result = {data: []}; } - return this.events.emit('data-received', result.data); + this.events.emit('data-received', result.data); } handleDataStream(stream) { From 78dbb4dc13975cd9c6c1813f3be2597d258b74c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 18 May 2017 14:19:39 +0200 Subject: [PATCH 003/179] config: removed trace level from config comment --- conf/sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/sample.ini b/conf/sample.ini index 84328e7d537..766dd8075f4 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -298,7 +298,7 @@ # Use space to separate multiple modes, e.g. "console file" ;mode = console file -# Either "trace", "debug", "info", "warn", "error", "critical", default is "info" +# Either "debug", "info", "warn", "error", "critical", default is "info" ;level = info # optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug From f65878c21d5ce92068cd58ec0d041965f6a713b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 18 May 2017 17:04:31 +0200 Subject: [PATCH 004/179] ux: working on query troubleshooting --- package.json | 1 + .../app/core/components/jsonview/helpers.ts | 110 +++++ .../app/core/components/jsonview/jsonview.ts | 453 ++++++++++++++++++ public/app/core/components/response_viewer.ts | 63 +++ public/app/core/core.ts | 3 +- .../app/features/panel/metrics_ds_selector.ts | 31 +- public/app/headers/common.d.ts | 5 + public/app/system.conf.js | 3 +- public/sass/_grafana.scss | 1 + public/sass/components/_response_viewer.scss | 6 + public/test/test-main.js | 3 +- tasks/options/copy.js | 1 + yarn.lock | 20 +- 13 files changed, 669 insertions(+), 31 deletions(-) create mode 100644 public/app/core/components/jsonview/helpers.ts create mode 100644 public/app/core/components/jsonview/jsonview.ts create mode 100644 public/app/core/components/response_viewer.ts create mode 100644 public/sass/components/_response_viewer.scss diff --git a/package.json b/package.json index 47102820d58..19e91a31ffe 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "grunt-jscs": "3.0.1", "grunt-sass-lint": "^0.2.2", "grunt-sync": "^0.6.2", + "json-formatter-js": "^2.2.0", "karma-sinon": "^1.0.5", "lodash": "^4.17.2", "mousetrap": "^1.6.0", diff --git a/public/app/core/components/jsonview/helpers.ts b/public/app/core/components/jsonview/helpers.ts new file mode 100644 index 00000000000..3ab36a19a7d --- /dev/null +++ b/public/app/core/components/jsonview/helpers.ts @@ -0,0 +1,110 @@ +// #<{(| +// * Escapes `"` charachters from string +// |)}># +// function escapeString(str: string): string { +// return str.replace('"', '\"'); +// } +// +// #<{(| +// * Determines if a value is an object +// |)}># +// export function isObject(value: any): boolean { +// var type = typeof value; +// return !!value && (type === 'object'); +// } +// +// #<{(| +// * Gets constructor name of an object. +// * From http://stackoverflow.com/a/332429 +// * +// |)}># +// export function getObjectName(object: Object): string { +// if (object === undefined) { +// return ''; +// } +// if (object === null) { +// return 'Object'; +// } +// if (typeof object === 'object' && !object.constructor) { +// return 'Object'; +// } +// +// const funcNameRegex = /function ([^(]*)/; +// const results = (funcNameRegex).exec((object).constructor.toString()); +// if (results && results.length > 1) { +// return results[1]; +// } else { +// return ''; +// } +// } +// +// #<{(| +// * Gets type of an object. Returns "null" for null objects +// |)}># +// export function getType(object: Object): string { +// if (object === null) { return 'null'; } +// return typeof object; +// } +// +// #<{(| +// * Generates inline preview for a JavaScript object based on a value +// |)}># +// export function getValuePreview (object: Object, value: string): string { +// var type = getType(object); +// +// if (type === 'null' || type === 'undefined') { return type; } +// +// if (type === 'string') { +// value = '"' + escapeString(value) + '"'; +// } +// if (type === 'function'){ +// +// // Remove content of the function +// return object.toString() +// .replace(/[\r\n]/g, '') +// .replace(/\{.*\}/, '') + '{…}'; +// } +// return value; +// } +// +// #<{(| +// * Generates inline preview for a JavaScript object +// |)}># +// export function getPreview(object: string): string { +// let value = ''; +// if (isObject(object)) { +// value = getObjectName(object); +// if (Array.isArray(object)) { +// value += '[' + object.length + ']'; +// } +// } else { +// value = getValuePreview(object, object); +// } +// return value; +// } +// +// #<{(| +// * Generates a prefixed CSS class name +// |)}># +// export function cssClass(className: string): string { +// return `json-formatter-${className}`; +// } +// +// #<{(| +// * Creates a new DOM element wiht given type and class +// * TODO: move me to helpers +// |)}># +// export function createElement(type: string, className?: string, content?: Element|string): Element { +// const el = document.createElement(type); +// if (className) { +// el.classList.add(cssClass(className)); +// } +// if (content !== undefined) { +// if (content instanceof Node) { +// el.appendChild(content); +// } else { +// el.appendChild(document.createTextNode(String(content))); +// } +// } +// return el; +// } diff --git a/public/app/core/components/jsonview/jsonview.ts b/public/app/core/components/jsonview/jsonview.ts new file mode 100644 index 00000000000..71994ceef59 --- /dev/null +++ b/public/app/core/components/jsonview/jsonview.ts @@ -0,0 +1,453 @@ +// import { +// isObject, +// getObjectName, +// getType, +// getValuePreview, +// getPreview, +// cssClass, +// createElement +// } from './helpers'; +// +// import './style.less'; +// +// const DATE_STRING_REGEX = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/; +// const PARTIAL_DATE_REGEX = /\d{2}:\d{2}:\d{2} GMT-\d{4}/; +// const JSON_DATE_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/; +// +// // When toggleing, don't animated removal or addition of more than a few items +// const MAX_ANIMATED_TOGGLE_ITEMS = 10; +// +// const requestAnimationFrame = window.requestAnimationFrame || function(cb: ()=>void) { cb(); return 0; }; +// +// export interface JSONFormatterConfiguration { +// hoverPreviewEnabled?: boolean; +// hoverPreviewArrayCount?: number; +// hoverPreviewFieldCount?: number; +// animateOpen?: boolean; +// animateClose?: boolean; +// theme?: string; +// }; +// +// const _defaultConfig: JSONFormatterConfiguration = { +// hoverPreviewEnabled: false, +// hoverPreviewArrayCount: 100, +// hoverPreviewFieldCount: 5, +// animateOpen: true, +// animateClose: true, +// theme: null +// }; +// +// +// #<{(|* +// * @class JSONFormatter +// * +// * JSONFormatter allows you to render JSON objects in HTML with a +// * **collapsible** navigation. +// |)}># +// export default class JSONFormatter { +// +// // Hold the open state after the toggler is used +// private _isOpen: boolean = null; +// +// // A reference to the element that we render to +// private element: Element; +// +// #<{(|* +// * @param {object} json The JSON object you want to render. It has to be an +// * object or array. Do NOT pass raw JSON string. +// * +// * @param {number} [open=1] his number indicates up to how many levels the +// * rendered tree should expand. Set it to `0` to make the whole tree collapsed +// * or set it to `Infinity` to expand the tree deeply +// * +// * @param {object} [config=defaultConfig] - +// * defaultConfig = { +// * hoverPreviewEnabled: false, +// * hoverPreviewArrayCount: 100, +// * hoverPreviewFieldCount: 5 +// * } +// * +// * Available configurations: +// * #####Hover Preview +// * * `hoverPreviewEnabled`: enable preview on hover +// * * `hoverPreviewArrayCount`: number of array items to show in preview Any +// * array larger than this number will be shown as `Array[XXX]` where `XXX` +// * is length of the array. +// * * `hoverPreviewFieldCount`: number of object properties to show for object +// * preview. Any object with more properties that thin number will be +// * truncated. +// * +// * @param {string} [key=undefined] The key that this object in it's parent +// * context +// |)}># +// constructor(public json: any, private open = 1, private config: JSONFormatterConfiguration = _defaultConfig, private key?: string) { +// +// // Setting default values for config object +// if (this.config.hoverPreviewEnabled === undefined) { +// this.config.hoverPreviewEnabled = _defaultConfig.hoverPreviewEnabled; +// } +// if (this.config.hoverPreviewArrayCount === undefined) { +// this.config.hoverPreviewArrayCount = _defaultConfig.hoverPreviewArrayCount; +// } +// if (this.config.hoverPreviewFieldCount === undefined) { +// this.config.hoverPreviewFieldCount = _defaultConfig.hoverPreviewFieldCount; +// } +// } +// +// #<{(| +// * is formatter open? +// |)}># +// private get isOpen(): boolean { +// if (this._isOpen !== null) { +// return this._isOpen; +// } else { +// return this.open > 0; +// } +// } +// +// #<{(| +// * set open state (from toggler) +// |)}># +// private set isOpen(value: boolean) { +// this._isOpen = value; +// } +// +// #<{(| +// * is this a date string? +// |)}># +// private get isDate(): boolean { +// return (this.type === 'string') && +// (DATE_STRING_REGEX.test(this.json) || +// JSON_DATE_REGEX.test(this.json) || +// PARTIAL_DATE_REGEX.test(this.json)); +// } +// +// #<{(| +// * is this a URL string? +// |)}># +// private get isUrl(): boolean { +// return this.type === 'string' && (this.json.indexOf('http') === 0); +// } +// +// #<{(| +// * is this an array? +// |)}># +// private get isArray(): boolean { +// return Array.isArray(this.json); +// } +// +// #<{(| +// * is this an object? +// * Note: In this context arrays are object as well +// |)}># +// private get isObject(): boolean { +// return isObject(this.json); +// } +// +// #<{(| +// * is this an empty object with no properties? +// |)}># +// private get isEmptyObject(): boolean { +// return !this.keys.length && !this.isArray; +// } +// +// #<{(| +// * is this an empty object or array? +// |)}># +// private get isEmpty(): boolean { +// return this.isEmptyObject || (this.keys && !this.keys.length && this.isArray); +// } +// +// #<{(| +// * did we recieve a key argument? +// * This means that the formatter was called as a sub formatter of a parent formatter +// |)}># +// private get hasKey(): boolean { +// return typeof this.key !== 'undefined'; +// } +// +// #<{(| +// * if this is an object, get constructor function name +// |)}># +// private get constructorName(): string { +// return getObjectName(this.json); +// } +// +// #<{(| +// * get type of this value +// * Possible values: all JavaScript primitive types plus "array" and "null" +// |)}># +// private get type(): string { +// return getType(this.json); +// } +// +// #<{(| +// * get object keys +// * If there is an empty key we pad it wit quotes to make it visible +// |)}># +// private get keys(): string[] { +// if (this.isObject) { +// return Object.keys(this.json).map((key)=> key ? key : '""'); +// } else { +// return []; +// } +// } +// +// #<{(|* +// * Toggles `isOpen` state +// * +// |)}># +// toggleOpen() { +// this.isOpen = !this.isOpen; +// +// if (this.element) { +// if (this.isOpen) { +// this.appendChildren(this.config.animateOpen); +// } else{ +// this.removeChildren(this.config.animateClose); +// } +// this.element.classList.toggle(cssClass('open')); +// } +// } +// +// #<{(|* +// * Open all children up to a certain depth. +// * Allows actions such as expand all/collapse all +// * +// |)}># +// openAtDepth(depth = 1) { +// if (depth < 0) { +// return; +// } +// +// this.open = depth; +// this.isOpen = (depth !== 0); +// +// if (this.element) { +// this.removeChildren(false); +// +// if (depth === 0) { +// this.element.classList.remove(cssClass('open')); +// } else { +// this.appendChildren(this.config.animateOpen); +// this.element.classList.add(cssClass('open')); +// } +// } +// } +// +// #<{(|* +// * Generates inline preview +// * +// * @returns {string} +// |)}># +// getInlinepreview() { +// if (this.isArray) { +// +// // if array length is greater then 100 it shows "Array[101]" +// if (this.json.length > this.config.hoverPreviewArrayCount) { +// return `Array[${this.json.length}]`; +// } else { +// return `[${this.json.map(getPreview).join(', ')}]`; +// } +// } else { +// +// const keys = this.keys; +// +// // the first five keys (like Chrome Developer Tool) +// const narrowKeys = keys.slice(0, this.config.hoverPreviewFieldCount); +// +// // json value schematic information +// const kvs = narrowKeys.map(key => `${key}:${getPreview(this.json[key])}`); +// +// // if keys count greater then 5 then show ellipsis +// const ellipsis = keys.length >= this.config.hoverPreviewFieldCount ? '…' : ''; +// +// return `{${kvs.join(', ')}${ellipsis}}`; +// } +// } +// +// +// #<{(|* +// * Renders an HTML element and installs event listeners +// * +// * @returns {HTMLDivElement} +// |)}># +// render(): HTMLDivElement { +// +// // construct the root element and assign it to this.element +// this.element = createElement('div', 'row'); +// +// // construct the toggler link +// const togglerLink = createElement('a', 'toggler-link'); +// +// // if this is an object we need a wrapper span (toggler) +// if (this.isObject) { +// togglerLink.appendChild(createElement('span', 'toggler')); +// } +// +// // if this is child of a parent formatter we need to append the key +// if (this.hasKey) { +// togglerLink.appendChild(createElement('span', 'key', `${this.key}:`)); +// } +// +// // Value for objects and arrays +// if (this.isObject) { +// +// // construct the value holder element +// const value = createElement('span', 'value'); +// +// // we need a wrapper span for objects +// const objectWrapperSpan = createElement('span'); +// +// // get constructor name and append it to wrapper span +// var constructorName = createElement('span', 'constructor-name', this.constructorName); +// objectWrapperSpan.appendChild(constructorName); +// +// // if it's an array append the array specific elements like brackets and length +// if (this.isArray) { +// const arrayWrapperSpan = createElement('span'); +// arrayWrapperSpan.appendChild(createElement('span', 'bracket', '[')); +// arrayWrapperSpan.appendChild(createElement('span', 'number', (this.json.length))); +// arrayWrapperSpan.appendChild(createElement('span', 'bracket', ']')); +// objectWrapperSpan.appendChild(arrayWrapperSpan); +// } +// +// // append object wrapper span to toggler link +// value.appendChild(objectWrapperSpan); +// togglerLink.appendChild(value); +// +// // Primitive values +// } else { +// +// // make a value holder element +// const value = this.isUrl ? createElement('a') : createElement('span'); +// +// // add type and other type related CSS classes +// value.classList.add(cssClass(this.type)); +// if (this.isDate) { +// value.classList.add(cssClass('date')); +// } +// if (this.isUrl) { +// value.classList.add(cssClass('url')); +// value.setAttribute('href', this.json); +// } +// +// // Append value content to value element +// const valuePreview = getValuePreview(this.json, this.json); +// value.appendChild(document.createTextNode(valuePreview)); +// +// // append the value element to toggler link +// togglerLink.appendChild(value); +// } +// +// // if hover preview is enabled, append the inline preview element +// if (this.isObject && this.config.hoverPreviewEnabled) { +// const preview = createElement('span', 'preview-text'); +// preview.appendChild(document.createTextNode(this.getInlinepreview())); +// togglerLink.appendChild(preview); +// } +// +// // construct a children element +// const children = createElement('div', 'children'); +// +// // set CSS classes for children +// if (this.isObject) { +// children.classList.add(cssClass('object')); +// } +// if (this.isArray) { +// children.classList.add(cssClass('array')); +// } +// if (this.isEmpty) { +// children.classList.add(cssClass('empty')); +// } +// +// // set CSS classes for root element +// if (this.config && this.config.theme) { +// this.element.classList.add(cssClass(this.config.theme)); +// } +// if (this.isOpen) { +// this.element.classList.add(cssClass('open')); +// } +// +// // append toggler and children elements to root element +// this.element.appendChild(togglerLink); +// this.element.appendChild(children); +// +// // if formatter is set to be open call appendChildren +// if (this.isObject && this.isOpen) { +// this.appendChildren(); +// } +// +// // add event listener for toggling +// if (this.isObject) { +// togglerLink.addEventListener('click', this.toggleOpen.bind(this)); +// } +// +// return this.element as HTMLDivElement; +// } +// +// #<{(|* +// * Appends all the children to children element +// * Animated option is used when user triggers this via a click +// |)}># +// appendChildren(animated = false) { +// const children = this.element.querySelector(`div.${cssClass('children')}`); +// +// if (!children || this.isEmpty) { return; } +// +// if (animated) { +// let index = 0; +// const addAChild = ()=> { +// const key = this.keys[index]; +// const formatter = new JSONFormatter(this.json[key], this.open - 1, this.config, key); +// children.appendChild(formatter.render()); +// +// index += 1; +// +// if (index < this.keys.length) { +// if (index > MAX_ANIMATED_TOGGLE_ITEMS) { +// addAChild(); +// } else { +// requestAnimationFrame(addAChild); +// } +// } +// }; +// +// requestAnimationFrame(addAChild); +// +// } else { +// this.keys.forEach(key => { +// const formatter = new JSONFormatter(this.json[key], this.open - 1, this.config, key); +// children.appendChild(formatter.render()); +// }); +// } +// } +// +// #<{(|* +// * Removes all the children from children element +// * Animated option is used when user triggers this via a click +// |)}># +// removeChildren(animated = false) { +// const childrenElement = this.element.querySelector(`div.${cssClass('children')}`) as HTMLDivElement; +// +// if (animated) { +// let childrenRemoved = 0; +// const removeAChild = ()=> { +// if (childrenElement && childrenElement.children.length) { +// childrenElement.removeChild(childrenElement.children[0]); +// childrenRemoved += 1; +// if (childrenRemoved > MAX_ANIMATED_TOGGLE_ITEMS) { +// removeAChild(); +// } else { +// requestAnimationFrame(removeAChild); +// } +// } +// }; +// requestAnimationFrame(removeAChild); +// } else { +// if (childrenElement) { +// childrenElement.innerHTML = ''; +// } +// } +// } +// } diff --git a/public/app/core/components/response_viewer.ts b/public/app/core/components/response_viewer.ts new file mode 100644 index 00000000000..5861e010fb3 --- /dev/null +++ b/public/app/core/components/response_viewer.ts @@ -0,0 +1,63 @@ +/// + +import coreModule from 'app/core/core_module'; +import JsonFormatter from 'json-formatter-js'; + + +const template = ` +
+
+
+`; + +export function responseViewer() { + return { + restrict: 'E', + template: template, + scope: {response: "="}, + link: function(scope, elem) { + var jsonElem = elem.find('.response-viewer-json'); + + scope.$watch("response", newVal => { + if (!newVal) { + elem.empty(); + return; + } + + if (scope.response.headers) { + delete scope.response.headers; + } + + if (scope.response.data) { + scope.response.response = scope.response.data; + delete scope.response.data; + } + + if (scope.response.config) { + scope.response.request = scope.response.config; + delete scope.response.config; + delete scope.response.request.transformRequest; + delete scope.response.request.transformResponse; + delete scope.response.request.paramSerializer; + delete scope.response.request.jsonpCallbackParam; + delete scope.response.request.headers; + delete scope.response.request.requestId; + delete scope.response.request.inspect; + delete scope.response.request.retry; + delete scope.response.request.timeout; + } + + + const formatter = new JsonFormatter(scope.response, 2, { + theme: 'dark', + }); + + const html = formatter.render(); + jsonElem.html(html); + }); + + } + }; +} + +coreModule.directive('responseViewer', responseViewer); diff --git a/public/app/core/core.ts b/public/app/core/core.ts index 4aa2e7eb64a..4c5fa429677 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -45,7 +45,7 @@ import {assignModelProperties} from './utils/model_utils'; import {contextSrv} from './services/context_srv'; import {KeybindingSrv} from './services/keybindingSrv'; import {helpModal} from './components/help/help'; - +import {responseViewer} from './components/response_viewer'; export { arrayJoin, @@ -69,4 +69,5 @@ export { contextSrv, KeybindingSrv, helpModal, + responseViewer, }; diff --git a/public/app/features/panel/metrics_ds_selector.ts b/public/app/features/panel/metrics_ds_selector.ts index 67619837e30..6b7fa8da6f5 100644 --- a/public/app/features/panel/metrics_ds_selector.ts +++ b/public/app/features/panel/metrics_ds_selector.ts @@ -8,16 +8,8 @@ var module = angular.module('grafana.directives'); var template = ` -
-
-
{{ctrl.lastError}}
-
-
-
-
-
{{ctrl.lastResponse}}
-
+
@@ -49,9 +41,9 @@ var template = `
-
@@ -68,7 +60,7 @@ export class MetricsDsSelectorCtrl { datasources: any[]; current: any; lastResponse: any; - lastError: any; + responseData: any; showResponse: boolean; /** @ngInject */ @@ -95,9 +87,8 @@ export class MetricsDsSelectorCtrl { } onRequestResponse(data) { - console.log(data); - this.lastResponse = JSON.stringify(data, null, 2); - this.lastError = null; + this.responseData = data; + this.showResponse = true; } toggleShowResponse() { @@ -105,8 +96,9 @@ export class MetricsDsSelectorCtrl { } onRequestError(err) { - console.log(err); - this.lastError = JSON.stringify(err, null, 2); + this.responseData = err; + this.responseData.isError = true; + this.showResponse = true; } getOptions(includeBuiltin) { @@ -122,8 +114,7 @@ export class MetricsDsSelectorCtrl { if (ds) { this.current = ds; this.panelCtrl.setDatasource(ds); - this.lastError = null; - this.lastResponse = null; + this.responseData = null; } } diff --git a/public/app/headers/common.d.ts b/public/app/headers/common.d.ts index 9ea5e96654d..b1d064b8036 100644 --- a/public/app/headers/common.d.ts +++ b/public/app/headers/common.d.ts @@ -72,3 +72,8 @@ declare module 'd3' { var d3: any; export default d3; } + +declare module 'json-formatter-js' { + var JSONFormatter: any; + export default JSONFormatter; +} diff --git a/public/app/system.conf.js b/public/app/system.conf.js index ae8e93a726a..9354a708785 100644 --- a/public/app/system.conf.js +++ b/public/app/system.conf.js @@ -32,7 +32,8 @@ System.config({ "jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow", "jquery.flot.gauge": "vendor/flot/jquery.flot.gauge", "d3": "vendor/d3/d3.js", - "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes" + "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes", + "json-formatter-js": "vendor/npm/json-formatter-js/dist/json-formatter" }, packages: { diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 6266bd9c98f..6128a9c47a8 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -75,6 +75,7 @@ @import "components/jsontree"; @import "components/edit_sidemenu.scss"; @import "components/row.scss"; +@import "components/response_viewer.scss"; // PAGES @import "pages/login"; diff --git a/public/sass/components/_response_viewer.scss b/public/sass/components/_response_viewer.scss new file mode 100644 index 00000000000..f554f98e382 --- /dev/null +++ b/public/sass/components/_response_viewer.scss @@ -0,0 +1,6 @@ +.response-viewer { + background: $card-background; + box-shadow: $card-shadow; + padding: 1rem; + border-radius: 4px; +} diff --git a/public/test/test-main.js b/public/test/test-main.js index 50553b7c8b3..6cdf19c5372 100644 --- a/public/test/test-main.js +++ b/public/test/test-main.js @@ -40,7 +40,8 @@ "jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow", "jquery.flot.gauge": "vendor/flot/jquery.flot.gauge", "d3": "vendor/d3/d3.js", - "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes" + "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes", + "json-formatter-js": "vendor/npm/json-formatter-js/dist/json-formatter" }, packages: { diff --git a/tasks/options/copy.js b/tasks/options/copy.js index 59921576da3..6a902c7188b 100644 --- a/tasks/options/copy.js +++ b/tasks/options/copy.js @@ -34,6 +34,7 @@ module.exports = function(config) { 'remarkable/dist/*', 'virtual-scroll/**/*', 'mousetrap/**/*', + 'json-formatter-js/dist/*.js', ], dest: '<%= srcDir %>/vendor/npm' } diff --git a/yarn.lock b/yarn.lock index 74cad3c2407..cb45e85d1fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1663,9 +1663,9 @@ glob@7.0.5: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.0.0: - version "7.0.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" +glob@^7.0.0, glob@^7.1.1, glob@~7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1674,9 +1674,9 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.0.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.1, glob@~7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" +glob@^7.0.3, glob@^7.0.5, glob@~7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2561,6 +2561,10 @@ jshint@~2.9.4: shelljs "0.3.x" strip-json-comments "1.0.x" +json-formatter-js@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json-formatter-js/-/json-formatter-js-2.2.0.tgz#1ed987223ef2f1d945304597faae78b580a8212b" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -3807,11 +3811,11 @@ resolve-pkg@^0.1.0: dependencies: resolve-from "^2.0.0" -resolve@1.1.x, resolve@^1.1.6, resolve@~1.1.0: +resolve@1.1.x, resolve@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.3.2: +resolve@^1.1.6, resolve@^1.3.2: version "1.3.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" dependencies: From f7a6c9a1e66123d69b8075254f3f0d8f93e8aeae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 18 May 2017 17:05:15 +0200 Subject: [PATCH 005/179] ux: minor change --- public/app/features/panel/metrics_ds_selector.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/public/app/features/panel/metrics_ds_selector.ts b/public/app/features/panel/metrics_ds_selector.ts index 6b7fa8da6f5..2a9137e6aa5 100644 --- a/public/app/features/panel/metrics_ds_selector.ts +++ b/public/app/features/panel/metrics_ds_selector.ts @@ -88,7 +88,6 @@ export class MetricsDsSelectorCtrl { onRequestResponse(data) { this.responseData = data; - this.showResponse = true; } toggleShowResponse() { From 5513d3c9d10ca9764e3295433f978bc87d92ba95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 19 May 2017 13:16:05 +0200 Subject: [PATCH 006/179] feat: moved json-formatter-js into core grafana to be able to make changes --- package.json | 1 - .../core/components/json_explorer/helpers.ts | 113 +++++ .../components/json_explorer/json_explorer.ts | 454 ++++++++++++++++++ .../app/core/components/jsonview/helpers.ts | 110 ----- .../app/core/components/jsonview/jsonview.ts | 453 ----------------- public/app/core/components/response_viewer.ts | 4 +- public/app/system.conf.js | 1 - public/sass/_grafana.scss | 1 + public/sass/components/_json_explorer.scss | 128 +++++ public/test/test-main.js | 1 - tasks/options/copy.js | 1 - yarn.lock | 4 - 12 files changed, 698 insertions(+), 573 deletions(-) create mode 100644 public/app/core/components/json_explorer/helpers.ts create mode 100644 public/app/core/components/json_explorer/json_explorer.ts delete mode 100644 public/app/core/components/jsonview/helpers.ts delete mode 100644 public/app/core/components/jsonview/jsonview.ts create mode 100644 public/sass/components/_json_explorer.scss diff --git a/package.json b/package.json index 19e91a31ffe..47102820d58 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,6 @@ "grunt-jscs": "3.0.1", "grunt-sass-lint": "^0.2.2", "grunt-sync": "^0.6.2", - "json-formatter-js": "^2.2.0", "karma-sinon": "^1.0.5", "lodash": "^4.17.2", "mousetrap": "^1.6.0", diff --git a/public/app/core/components/json_explorer/helpers.ts b/public/app/core/components/json_explorer/helpers.ts new file mode 100644 index 00000000000..2f2b80e73ea --- /dev/null +++ b/public/app/core/components/json_explorer/helpers.ts @@ -0,0 +1,113 @@ +// Based on work https://github.com/mohsen1/json-formatter-js +// Licence MIT, Copyright (c) 2015 Mohsen Azimi + +/* + * Escapes `"` charachters from string +*/ +function escapeString(str: string): string { + return str.replace('"', '\"'); +} + +/* + * Determines if a value is an object +*/ +export function isObject(value: any): boolean { + var type = typeof value; + return !!value && (type === 'object'); +} + +/* + * Gets constructor name of an object. + * From http://stackoverflow.com/a/332429 + * +*/ +export function getObjectName(object: Object): string { + if (object === undefined) { + return ''; + } + if (object === null) { + return 'Object'; + } + if (typeof object === 'object' && !object.constructor) { + return 'Object'; + } + + const funcNameRegex = /function ([^(]*)/; + const results = (funcNameRegex).exec((object).constructor.toString()); + if (results && results.length > 1) { + return results[1]; + } else { + return ''; + } +} + +/* + * Gets type of an object. Returns "null" for null objects +*/ +export function getType(object: Object): string { + if (object === null) { return 'null'; } + return typeof object; +} + +/* + * Generates inline preview for a JavaScript object based on a value +*/ +export function getValuePreview (object: Object, value: string): string { + var type = getType(object); + + if (type === 'null' || type === 'undefined') { return type; } + + if (type === 'string') { + value = '"' + escapeString(value) + '"'; + } + if (type === 'function'){ + + // Remove content of the function + return object.toString() + .replace(/[\r\n]/g, '') + .replace(/\{.*\}/, '') + '{…}'; + } + return value; +} + +/* + * Generates inline preview for a JavaScript object +*/ +export function getPreview(object: string): string { + let value = ''; + if (isObject(object)) { + value = getObjectName(object); + if (Array.isArray(object)) { + value += '[' + object.length + ']'; + } + } else { + value = getValuePreview(object, object); + } + return value; +} + +/* + * Generates a prefixed CSS class name +*/ +export function cssClass(className: string): string { + return `json-formatter-${className}`; +} + +/* + * Creates a new DOM element wiht given type and class + * TODO: move me to helpers +*/ +export function createElement(type: string, className?: string, content?: Element|string): Element { + const el = document.createElement(type); + if (className) { + el.classList.add(cssClass(className)); + } + if (content !== undefined) { + if (content instanceof Node) { + el.appendChild(content); + } else { + el.appendChild(document.createTextNode(String(content))); + } + } + return el; +} diff --git a/public/app/core/components/json_explorer/json_explorer.ts b/public/app/core/components/json_explorer/json_explorer.ts new file mode 100644 index 00000000000..3f460968b77 --- /dev/null +++ b/public/app/core/components/json_explorer/json_explorer.ts @@ -0,0 +1,454 @@ +// Based on work https://github.com/mohsen1/json-formatter-js +// Licence MIT, Copyright (c) 2015 Mohsen Azimi + +import { + isObject, + getObjectName, + getType, + getValuePreview, + getPreview, + cssClass, + createElement +} from './helpers'; + +const DATE_STRING_REGEX = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/; +const PARTIAL_DATE_REGEX = /\d{2}:\d{2}:\d{2} GMT-\d{4}/; +const JSON_DATE_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/; + +// When toggleing, don't animated removal or addition of more than a few items +const MAX_ANIMATED_TOGGLE_ITEMS = 10; + +const requestAnimationFrame = window.requestAnimationFrame || function(cb: ()=>void) { cb(); return 0; }; + +export interface JsonExplorerConfig { + hoverPreviewEnabled?: boolean; + hoverPreviewArrayCount?: number; + hoverPreviewFieldCount?: number; + animateOpen?: boolean; + animateClose?: boolean; + theme?: string; +} + +const _defaultConfig: JsonExplorerConfig = { + hoverPreviewEnabled: false, + hoverPreviewArrayCount: 100, + hoverPreviewFieldCount: 5, + animateOpen: true, + animateClose: true, + theme: null +}; + + +/** + * @class JsonExplorer + * + * JsonExplorer allows you to render JSON objects in HTML with a + * **collapsible** navigation. +*/ +export default class JsonExplorer { + + // Hold the open state after the toggler is used + private _isOpen: boolean = null; + + // A reference to the element that we render to + private element: Element; + + /** + * @param {object} json The JSON object you want to render. It has to be an + * object or array. Do NOT pass raw JSON string. + * + * @param {number} [open=1] his number indicates up to how many levels the + * rendered tree should expand. Set it to `0` to make the whole tree collapsed + * or set it to `Infinity` to expand the tree deeply + * + * @param {object} [config=defaultConfig] - + * defaultConfig = { + * hoverPreviewEnabled: false, + * hoverPreviewArrayCount: 100, + * hoverPreviewFieldCount: 5 + * } + * + * Available configurations: + * #####Hover Preview + * * `hoverPreviewEnabled`: enable preview on hover + * * `hoverPreviewArrayCount`: number of array items to show in preview Any + * array larger than this number will be shown as `Array[XXX]` where `XXX` + * is length of the array. + * * `hoverPreviewFieldCount`: number of object properties to show for object + * preview. Any object with more properties that thin number will be + * truncated. + * + * @param {string} [key=undefined] The key that this object in it's parent + * context + */ + constructor(public json: any, private open = 1, private config: JsonExplorerConfig = _defaultConfig, private key?: string) { + + // Setting default values for config object + if (this.config.hoverPreviewEnabled === undefined) { + this.config.hoverPreviewEnabled = _defaultConfig.hoverPreviewEnabled; + } + if (this.config.hoverPreviewArrayCount === undefined) { + this.config.hoverPreviewArrayCount = _defaultConfig.hoverPreviewArrayCount; + } + if (this.config.hoverPreviewFieldCount === undefined) { + this.config.hoverPreviewFieldCount = _defaultConfig.hoverPreviewFieldCount; + } + } + + /* + * is formatter open? + */ + private get isOpen(): boolean { + if (this._isOpen !== null) { + return this._isOpen; + } else { + return this.open > 0; + } + } + + /* + * set open state (from toggler) + */ + private set isOpen(value: boolean) { + this._isOpen = value; + } + + /* + * is this a date string? + */ + private get isDate(): boolean { + return (this.type === 'string') && + (DATE_STRING_REGEX.test(this.json) || + JSON_DATE_REGEX.test(this.json) || + PARTIAL_DATE_REGEX.test(this.json)); + } + + /* + * is this a URL string? + */ + private get isUrl(): boolean { + return this.type === 'string' && (this.json.indexOf('http') === 0); + } + + /* + * is this an array? + */ + private get isArray(): boolean { + return Array.isArray(this.json); + } + + /* + * is this an object? + * Note: In this context arrays are object as well + */ + private get isObject(): boolean { + return isObject(this.json); + } + + /* + * is this an empty object with no properties? + */ + private get isEmptyObject(): boolean { + return !this.keys.length && !this.isArray; + } + + /* + * is this an empty object or array? + */ + private get isEmpty(): boolean { + return this.isEmptyObject || (this.keys && !this.keys.length && this.isArray); + } + + /* + * did we recieve a key argument? + * This means that the formatter was called as a sub formatter of a parent formatter + */ + private get hasKey(): boolean { + return typeof this.key !== 'undefined'; + } + + /* + * if this is an object, get constructor function name + */ + private get constructorName(): string { + return getObjectName(this.json); + } + + /* + * get type of this value + * Possible values: all JavaScript primitive types plus "array" and "null" + */ + private get type(): string { + return getType(this.json); + } + + /* + * get object keys + * If there is an empty key we pad it wit quotes to make it visible + */ + private get keys(): string[] { + if (this.isObject) { + return Object.keys(this.json).map((key)=> key ? key : '""'); + } else { + return []; + } + } + + /** + * Toggles `isOpen` state + * + */ + toggleOpen() { + this.isOpen = !this.isOpen; + + if (this.element) { + if (this.isOpen) { + this.appendChildren(this.config.animateOpen); + } else{ + this.removeChildren(this.config.animateClose); + } + this.element.classList.toggle(cssClass('open')); + } + } + + /** + * Open all children up to a certain depth. + * Allows actions such as expand all/collapse all + * + */ + openAtDepth(depth = 1) { + if (depth < 0) { + return; + } + + this.open = depth; + this.isOpen = (depth !== 0); + + if (this.element) { + this.removeChildren(false); + + if (depth === 0) { + this.element.classList.remove(cssClass('open')); + } else { + this.appendChildren(this.config.animateOpen); + this.element.classList.add(cssClass('open')); + } + } + } + + /** + * Generates inline preview + * + * @returns {string} + */ + getInlinepreview() { + if (this.isArray) { + + // if array length is greater then 100 it shows "Array[101]" + if (this.json.length > this.config.hoverPreviewArrayCount) { + return `Array[${this.json.length}]`; + } else { + return `[${this.json.map(getPreview).join(', ')}]`; + } + } else { + + const keys = this.keys; + + // the first five keys (like Chrome Developer Tool) + const narrowKeys = keys.slice(0, this.config.hoverPreviewFieldCount); + + // json value schematic information + const kvs = narrowKeys.map(key => `${key}:${getPreview(this.json[key])}`); + + // if keys count greater then 5 then show ellipsis + const ellipsis = keys.length >= this.config.hoverPreviewFieldCount ? '…' : ''; + + return `{${kvs.join(', ')}${ellipsis}}`; + } + } + + + /** + * Renders an HTML element and installs event listeners + * + * @returns {HTMLDivElement} + */ + render(): HTMLDivElement { + + // construct the root element and assign it to this.element + this.element = createElement('div', 'row'); + + // construct the toggler link + const togglerLink = createElement('a', 'toggler-link'); + + // if this is an object we need a wrapper span (toggler) + if (this.isObject) { + togglerLink.appendChild(createElement('span', 'toggler')); + } + + // if this is child of a parent formatter we need to append the key + if (this.hasKey) { + togglerLink.appendChild(createElement('span', 'key', `${this.key}:`)); + } + + // Value for objects and arrays + if (this.isObject) { + + // construct the value holder element + const value = createElement('span', 'value'); + + // we need a wrapper span for objects + const objectWrapperSpan = createElement('span'); + + // get constructor name and append it to wrapper span + var constructorName = createElement('span', 'constructor-name', this.constructorName); + objectWrapperSpan.appendChild(constructorName); + + // if it's an array append the array specific elements like brackets and length + if (this.isArray) { + const arrayWrapperSpan = createElement('span'); + arrayWrapperSpan.appendChild(createElement('span', 'bracket', '[')); + arrayWrapperSpan.appendChild(createElement('span', 'number', (this.json.length))); + arrayWrapperSpan.appendChild(createElement('span', 'bracket', ']')); + objectWrapperSpan.appendChild(arrayWrapperSpan); + } + + // append object wrapper span to toggler link + value.appendChild(objectWrapperSpan); + togglerLink.appendChild(value); + + // Primitive values + } else { + + // make a value holder element + const value = this.isUrl ? createElement('a') : createElement('span'); + + // add type and other type related CSS classes + value.classList.add(cssClass(this.type)); + if (this.isDate) { + value.classList.add(cssClass('date')); + } + if (this.isUrl) { + value.classList.add(cssClass('url')); + value.setAttribute('href', this.json); + } + + // Append value content to value element + const valuePreview = getValuePreview(this.json, this.json); + value.appendChild(document.createTextNode(valuePreview)); + + // append the value element to toggler link + togglerLink.appendChild(value); + } + + // if hover preview is enabled, append the inline preview element + if (this.isObject && this.config.hoverPreviewEnabled) { + const preview = createElement('span', 'preview-text'); + preview.appendChild(document.createTextNode(this.getInlinepreview())); + togglerLink.appendChild(preview); + } + + // construct a children element + const children = createElement('div', 'children'); + + // set CSS classes for children + if (this.isObject) { + children.classList.add(cssClass('object')); + } + if (this.isArray) { + children.classList.add(cssClass('array')); + } + if (this.isEmpty) { + children.classList.add(cssClass('empty')); + } + + // set CSS classes for root element + if (this.config && this.config.theme) { + this.element.classList.add(cssClass(this.config.theme)); + } + if (this.isOpen) { + this.element.classList.add(cssClass('open')); + } + + // append toggler and children elements to root element + this.element.appendChild(togglerLink); + this.element.appendChild(children); + + // if formatter is set to be open call appendChildren + if (this.isObject && this.isOpen) { + this.appendChildren(); + } + + // add event listener for toggling + if (this.isObject) { + togglerLink.addEventListener('click', this.toggleOpen.bind(this)); + } + + return this.element as HTMLDivElement; + } + + /** + * Appends all the children to children element + * Animated option is used when user triggers this via a click + */ + appendChildren(animated = false) { + const children = this.element.querySelector(`div.${cssClass('children')}`); + + if (!children || this.isEmpty) { return; } + + if (animated) { + let index = 0; + const addAChild = ()=> { + const key = this.keys[index]; + const formatter = new JsonExplorer(this.json[key], this.open - 1, this.config, key); + children.appendChild(formatter.render()); + + index += 1; + + if (index < this.keys.length) { + if (index > MAX_ANIMATED_TOGGLE_ITEMS) { + addAChild(); + } else { + requestAnimationFrame(addAChild); + } + } + }; + + requestAnimationFrame(addAChild); + + } else { + this.keys.forEach(key => { + const formatter = new JsonExplorer(this.json[key], this.open - 1, this.config, key); + children.appendChild(formatter.render()); + }); + } + } + + /** + * Removes all the children from children element + * Animated option is used when user triggers this via a click + */ + removeChildren(animated = false) { + const childrenElement = this.element.querySelector(`div.${cssClass('children')}`) as HTMLDivElement; + + if (animated) { + let childrenRemoved = 0; + const removeAChild = ()=> { + if (childrenElement && childrenElement.children.length) { + childrenElement.removeChild(childrenElement.children[0]); + childrenRemoved += 1; + if (childrenRemoved > MAX_ANIMATED_TOGGLE_ITEMS) { + removeAChild(); + } else { + requestAnimationFrame(removeAChild); + } + } + }; + requestAnimationFrame(removeAChild); + } else { + if (childrenElement) { + childrenElement.innerHTML = ''; + } + } + } +} diff --git a/public/app/core/components/jsonview/helpers.ts b/public/app/core/components/jsonview/helpers.ts deleted file mode 100644 index 3ab36a19a7d..00000000000 --- a/public/app/core/components/jsonview/helpers.ts +++ /dev/null @@ -1,110 +0,0 @@ -// #<{(| -// * Escapes `"` charachters from string -// |)}># -// function escapeString(str: string): string { -// return str.replace('"', '\"'); -// } -// -// #<{(| -// * Determines if a value is an object -// |)}># -// export function isObject(value: any): boolean { -// var type = typeof value; -// return !!value && (type === 'object'); -// } -// -// #<{(| -// * Gets constructor name of an object. -// * From http://stackoverflow.com/a/332429 -// * -// |)}># -// export function getObjectName(object: Object): string { -// if (object === undefined) { -// return ''; -// } -// if (object === null) { -// return 'Object'; -// } -// if (typeof object === 'object' && !object.constructor) { -// return 'Object'; -// } -// -// const funcNameRegex = /function ([^(]*)/; -// const results = (funcNameRegex).exec((object).constructor.toString()); -// if (results && results.length > 1) { -// return results[1]; -// } else { -// return ''; -// } -// } -// -// #<{(| -// * Gets type of an object. Returns "null" for null objects -// |)}># -// export function getType(object: Object): string { -// if (object === null) { return 'null'; } -// return typeof object; -// } -// -// #<{(| -// * Generates inline preview for a JavaScript object based on a value -// |)}># -// export function getValuePreview (object: Object, value: string): string { -// var type = getType(object); -// -// if (type === 'null' || type === 'undefined') { return type; } -// -// if (type === 'string') { -// value = '"' + escapeString(value) + '"'; -// } -// if (type === 'function'){ -// -// // Remove content of the function -// return object.toString() -// .replace(/[\r\n]/g, '') -// .replace(/\{.*\}/, '') + '{…}'; -// } -// return value; -// } -// -// #<{(| -// * Generates inline preview for a JavaScript object -// |)}># -// export function getPreview(object: string): string { -// let value = ''; -// if (isObject(object)) { -// value = getObjectName(object); -// if (Array.isArray(object)) { -// value += '[' + object.length + ']'; -// } -// } else { -// value = getValuePreview(object, object); -// } -// return value; -// } -// -// #<{(| -// * Generates a prefixed CSS class name -// |)}># -// export function cssClass(className: string): string { -// return `json-formatter-${className}`; -// } -// -// #<{(| -// * Creates a new DOM element wiht given type and class -// * TODO: move me to helpers -// |)}># -// export function createElement(type: string, className?: string, content?: Element|string): Element { -// const el = document.createElement(type); -// if (className) { -// el.classList.add(cssClass(className)); -// } -// if (content !== undefined) { -// if (content instanceof Node) { -// el.appendChild(content); -// } else { -// el.appendChild(document.createTextNode(String(content))); -// } -// } -// return el; -// } diff --git a/public/app/core/components/jsonview/jsonview.ts b/public/app/core/components/jsonview/jsonview.ts deleted file mode 100644 index 71994ceef59..00000000000 --- a/public/app/core/components/jsonview/jsonview.ts +++ /dev/null @@ -1,453 +0,0 @@ -// import { -// isObject, -// getObjectName, -// getType, -// getValuePreview, -// getPreview, -// cssClass, -// createElement -// } from './helpers'; -// -// import './style.less'; -// -// const DATE_STRING_REGEX = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/; -// const PARTIAL_DATE_REGEX = /\d{2}:\d{2}:\d{2} GMT-\d{4}/; -// const JSON_DATE_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/; -// -// // When toggleing, don't animated removal or addition of more than a few items -// const MAX_ANIMATED_TOGGLE_ITEMS = 10; -// -// const requestAnimationFrame = window.requestAnimationFrame || function(cb: ()=>void) { cb(); return 0; }; -// -// export interface JSONFormatterConfiguration { -// hoverPreviewEnabled?: boolean; -// hoverPreviewArrayCount?: number; -// hoverPreviewFieldCount?: number; -// animateOpen?: boolean; -// animateClose?: boolean; -// theme?: string; -// }; -// -// const _defaultConfig: JSONFormatterConfiguration = { -// hoverPreviewEnabled: false, -// hoverPreviewArrayCount: 100, -// hoverPreviewFieldCount: 5, -// animateOpen: true, -// animateClose: true, -// theme: null -// }; -// -// -// #<{(|* -// * @class JSONFormatter -// * -// * JSONFormatter allows you to render JSON objects in HTML with a -// * **collapsible** navigation. -// |)}># -// export default class JSONFormatter { -// -// // Hold the open state after the toggler is used -// private _isOpen: boolean = null; -// -// // A reference to the element that we render to -// private element: Element; -// -// #<{(|* -// * @param {object} json The JSON object you want to render. It has to be an -// * object or array. Do NOT pass raw JSON string. -// * -// * @param {number} [open=1] his number indicates up to how many levels the -// * rendered tree should expand. Set it to `0` to make the whole tree collapsed -// * or set it to `Infinity` to expand the tree deeply -// * -// * @param {object} [config=defaultConfig] - -// * defaultConfig = { -// * hoverPreviewEnabled: false, -// * hoverPreviewArrayCount: 100, -// * hoverPreviewFieldCount: 5 -// * } -// * -// * Available configurations: -// * #####Hover Preview -// * * `hoverPreviewEnabled`: enable preview on hover -// * * `hoverPreviewArrayCount`: number of array items to show in preview Any -// * array larger than this number will be shown as `Array[XXX]` where `XXX` -// * is length of the array. -// * * `hoverPreviewFieldCount`: number of object properties to show for object -// * preview. Any object with more properties that thin number will be -// * truncated. -// * -// * @param {string} [key=undefined] The key that this object in it's parent -// * context -// |)}># -// constructor(public json: any, private open = 1, private config: JSONFormatterConfiguration = _defaultConfig, private key?: string) { -// -// // Setting default values for config object -// if (this.config.hoverPreviewEnabled === undefined) { -// this.config.hoverPreviewEnabled = _defaultConfig.hoverPreviewEnabled; -// } -// if (this.config.hoverPreviewArrayCount === undefined) { -// this.config.hoverPreviewArrayCount = _defaultConfig.hoverPreviewArrayCount; -// } -// if (this.config.hoverPreviewFieldCount === undefined) { -// this.config.hoverPreviewFieldCount = _defaultConfig.hoverPreviewFieldCount; -// } -// } -// -// #<{(| -// * is formatter open? -// |)}># -// private get isOpen(): boolean { -// if (this._isOpen !== null) { -// return this._isOpen; -// } else { -// return this.open > 0; -// } -// } -// -// #<{(| -// * set open state (from toggler) -// |)}># -// private set isOpen(value: boolean) { -// this._isOpen = value; -// } -// -// #<{(| -// * is this a date string? -// |)}># -// private get isDate(): boolean { -// return (this.type === 'string') && -// (DATE_STRING_REGEX.test(this.json) || -// JSON_DATE_REGEX.test(this.json) || -// PARTIAL_DATE_REGEX.test(this.json)); -// } -// -// #<{(| -// * is this a URL string? -// |)}># -// private get isUrl(): boolean { -// return this.type === 'string' && (this.json.indexOf('http') === 0); -// } -// -// #<{(| -// * is this an array? -// |)}># -// private get isArray(): boolean { -// return Array.isArray(this.json); -// } -// -// #<{(| -// * is this an object? -// * Note: In this context arrays are object as well -// |)}># -// private get isObject(): boolean { -// return isObject(this.json); -// } -// -// #<{(| -// * is this an empty object with no properties? -// |)}># -// private get isEmptyObject(): boolean { -// return !this.keys.length && !this.isArray; -// } -// -// #<{(| -// * is this an empty object or array? -// |)}># -// private get isEmpty(): boolean { -// return this.isEmptyObject || (this.keys && !this.keys.length && this.isArray); -// } -// -// #<{(| -// * did we recieve a key argument? -// * This means that the formatter was called as a sub formatter of a parent formatter -// |)}># -// private get hasKey(): boolean { -// return typeof this.key !== 'undefined'; -// } -// -// #<{(| -// * if this is an object, get constructor function name -// |)}># -// private get constructorName(): string { -// return getObjectName(this.json); -// } -// -// #<{(| -// * get type of this value -// * Possible values: all JavaScript primitive types plus "array" and "null" -// |)}># -// private get type(): string { -// return getType(this.json); -// } -// -// #<{(| -// * get object keys -// * If there is an empty key we pad it wit quotes to make it visible -// |)}># -// private get keys(): string[] { -// if (this.isObject) { -// return Object.keys(this.json).map((key)=> key ? key : '""'); -// } else { -// return []; -// } -// } -// -// #<{(|* -// * Toggles `isOpen` state -// * -// |)}># -// toggleOpen() { -// this.isOpen = !this.isOpen; -// -// if (this.element) { -// if (this.isOpen) { -// this.appendChildren(this.config.animateOpen); -// } else{ -// this.removeChildren(this.config.animateClose); -// } -// this.element.classList.toggle(cssClass('open')); -// } -// } -// -// #<{(|* -// * Open all children up to a certain depth. -// * Allows actions such as expand all/collapse all -// * -// |)}># -// openAtDepth(depth = 1) { -// if (depth < 0) { -// return; -// } -// -// this.open = depth; -// this.isOpen = (depth !== 0); -// -// if (this.element) { -// this.removeChildren(false); -// -// if (depth === 0) { -// this.element.classList.remove(cssClass('open')); -// } else { -// this.appendChildren(this.config.animateOpen); -// this.element.classList.add(cssClass('open')); -// } -// } -// } -// -// #<{(|* -// * Generates inline preview -// * -// * @returns {string} -// |)}># -// getInlinepreview() { -// if (this.isArray) { -// -// // if array length is greater then 100 it shows "Array[101]" -// if (this.json.length > this.config.hoverPreviewArrayCount) { -// return `Array[${this.json.length}]`; -// } else { -// return `[${this.json.map(getPreview).join(', ')}]`; -// } -// } else { -// -// const keys = this.keys; -// -// // the first five keys (like Chrome Developer Tool) -// const narrowKeys = keys.slice(0, this.config.hoverPreviewFieldCount); -// -// // json value schematic information -// const kvs = narrowKeys.map(key => `${key}:${getPreview(this.json[key])}`); -// -// // if keys count greater then 5 then show ellipsis -// const ellipsis = keys.length >= this.config.hoverPreviewFieldCount ? '…' : ''; -// -// return `{${kvs.join(', ')}${ellipsis}}`; -// } -// } -// -// -// #<{(|* -// * Renders an HTML element and installs event listeners -// * -// * @returns {HTMLDivElement} -// |)}># -// render(): HTMLDivElement { -// -// // construct the root element and assign it to this.element -// this.element = createElement('div', 'row'); -// -// // construct the toggler link -// const togglerLink = createElement('a', 'toggler-link'); -// -// // if this is an object we need a wrapper span (toggler) -// if (this.isObject) { -// togglerLink.appendChild(createElement('span', 'toggler')); -// } -// -// // if this is child of a parent formatter we need to append the key -// if (this.hasKey) { -// togglerLink.appendChild(createElement('span', 'key', `${this.key}:`)); -// } -// -// // Value for objects and arrays -// if (this.isObject) { -// -// // construct the value holder element -// const value = createElement('span', 'value'); -// -// // we need a wrapper span for objects -// const objectWrapperSpan = createElement('span'); -// -// // get constructor name and append it to wrapper span -// var constructorName = createElement('span', 'constructor-name', this.constructorName); -// objectWrapperSpan.appendChild(constructorName); -// -// // if it's an array append the array specific elements like brackets and length -// if (this.isArray) { -// const arrayWrapperSpan = createElement('span'); -// arrayWrapperSpan.appendChild(createElement('span', 'bracket', '[')); -// arrayWrapperSpan.appendChild(createElement('span', 'number', (this.json.length))); -// arrayWrapperSpan.appendChild(createElement('span', 'bracket', ']')); -// objectWrapperSpan.appendChild(arrayWrapperSpan); -// } -// -// // append object wrapper span to toggler link -// value.appendChild(objectWrapperSpan); -// togglerLink.appendChild(value); -// -// // Primitive values -// } else { -// -// // make a value holder element -// const value = this.isUrl ? createElement('a') : createElement('span'); -// -// // add type and other type related CSS classes -// value.classList.add(cssClass(this.type)); -// if (this.isDate) { -// value.classList.add(cssClass('date')); -// } -// if (this.isUrl) { -// value.classList.add(cssClass('url')); -// value.setAttribute('href', this.json); -// } -// -// // Append value content to value element -// const valuePreview = getValuePreview(this.json, this.json); -// value.appendChild(document.createTextNode(valuePreview)); -// -// // append the value element to toggler link -// togglerLink.appendChild(value); -// } -// -// // if hover preview is enabled, append the inline preview element -// if (this.isObject && this.config.hoverPreviewEnabled) { -// const preview = createElement('span', 'preview-text'); -// preview.appendChild(document.createTextNode(this.getInlinepreview())); -// togglerLink.appendChild(preview); -// } -// -// // construct a children element -// const children = createElement('div', 'children'); -// -// // set CSS classes for children -// if (this.isObject) { -// children.classList.add(cssClass('object')); -// } -// if (this.isArray) { -// children.classList.add(cssClass('array')); -// } -// if (this.isEmpty) { -// children.classList.add(cssClass('empty')); -// } -// -// // set CSS classes for root element -// if (this.config && this.config.theme) { -// this.element.classList.add(cssClass(this.config.theme)); -// } -// if (this.isOpen) { -// this.element.classList.add(cssClass('open')); -// } -// -// // append toggler and children elements to root element -// this.element.appendChild(togglerLink); -// this.element.appendChild(children); -// -// // if formatter is set to be open call appendChildren -// if (this.isObject && this.isOpen) { -// this.appendChildren(); -// } -// -// // add event listener for toggling -// if (this.isObject) { -// togglerLink.addEventListener('click', this.toggleOpen.bind(this)); -// } -// -// return this.element as HTMLDivElement; -// } -// -// #<{(|* -// * Appends all the children to children element -// * Animated option is used when user triggers this via a click -// |)}># -// appendChildren(animated = false) { -// const children = this.element.querySelector(`div.${cssClass('children')}`); -// -// if (!children || this.isEmpty) { return; } -// -// if (animated) { -// let index = 0; -// const addAChild = ()=> { -// const key = this.keys[index]; -// const formatter = new JSONFormatter(this.json[key], this.open - 1, this.config, key); -// children.appendChild(formatter.render()); -// -// index += 1; -// -// if (index < this.keys.length) { -// if (index > MAX_ANIMATED_TOGGLE_ITEMS) { -// addAChild(); -// } else { -// requestAnimationFrame(addAChild); -// } -// } -// }; -// -// requestAnimationFrame(addAChild); -// -// } else { -// this.keys.forEach(key => { -// const formatter = new JSONFormatter(this.json[key], this.open - 1, this.config, key); -// children.appendChild(formatter.render()); -// }); -// } -// } -// -// #<{(|* -// * Removes all the children from children element -// * Animated option is used when user triggers this via a click -// |)}># -// removeChildren(animated = false) { -// const childrenElement = this.element.querySelector(`div.${cssClass('children')}`) as HTMLDivElement; -// -// if (animated) { -// let childrenRemoved = 0; -// const removeAChild = ()=> { -// if (childrenElement && childrenElement.children.length) { -// childrenElement.removeChild(childrenElement.children[0]); -// childrenRemoved += 1; -// if (childrenRemoved > MAX_ANIMATED_TOGGLE_ITEMS) { -// removeAChild(); -// } else { -// requestAnimationFrame(removeAChild); -// } -// } -// }; -// requestAnimationFrame(removeAChild); -// } else { -// if (childrenElement) { -// childrenElement.innerHTML = ''; -// } -// } -// } -// } diff --git a/public/app/core/components/response_viewer.ts b/public/app/core/components/response_viewer.ts index 5861e010fb3..fe332f070ec 100644 --- a/public/app/core/components/response_viewer.ts +++ b/public/app/core/components/response_viewer.ts @@ -1,7 +1,7 @@ /// import coreModule from 'app/core/core_module'; -import JsonFormatter from 'json-formatter-js'; +import JsonExplorer from './json_explorer/json_explorer'; const template = ` @@ -48,7 +48,7 @@ export function responseViewer() { } - const formatter = new JsonFormatter(scope.response, 2, { + const formatter = new JsonExplorer(scope.response, 2, { theme: 'dark', }); diff --git a/public/app/system.conf.js b/public/app/system.conf.js index 9354a708785..816cba4fb42 100644 --- a/public/app/system.conf.js +++ b/public/app/system.conf.js @@ -33,7 +33,6 @@ System.config({ "jquery.flot.gauge": "vendor/flot/jquery.flot.gauge", "d3": "vendor/d3/d3.js", "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes", - "json-formatter-js": "vendor/npm/json-formatter-js/dist/json-formatter" }, packages: { diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 6128a9c47a8..c8f82ad845a 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -76,6 +76,7 @@ @import "components/edit_sidemenu.scss"; @import "components/row.scss"; @import "components/response_viewer.scss"; +@import "components/json_explorer.scss"; // PAGES @import "pages/login"; diff --git a/public/sass/components/_json_explorer.scss b/public/sass/components/_json_explorer.scss new file mode 100644 index 00000000000..3c4c19eceb7 --- /dev/null +++ b/public/sass/components/_json_explorer.scss @@ -0,0 +1,128 @@ +@mixin json-explorer-theme( + $default-color: black, + $string-color: green, + $number-color: blue, + $boolean-color: red, + $null-color: #855A00, + $undefined-color: rgb(202, 11, 105), + $function-color: #FF20ED, + $rotate-time: 100ms, + $toggler-opacity: 0.6, + $toggler-color: #45376F, + $bracket-color: blue, + $key-color: #00008B, + $url-color: blue) { + + font-family: monospace; + &, a, a:hover { + color: $default-color; + text-decoration: none; + } + + .json-formatter-row { + margin-left: 1rem; + } + + .json-formatter-children { + &.json-formatter-empty { + opacity: 0.5; + margin-left: 1rem; + + &::after { display: none; } + &.json-formatter-object::after { content: "No properties"; } + &.json-formatter-array::after { content: "[]"; } + } + } + + .json-formatter-string { + color: $string-color; + white-space: pre; + word-wrap: break-word; + } + .json-formatter-number { color: $number-color; } + .json-formatter-boolean { color: $boolean-color; } + .json-formatter-null { color: $null-color; } + .json-formatter-undefined { color: $undefined-color; } + .json-formatter-function { color: $function-color; } + .json-formatter-date { background-color: fade($default-color, 5%); } + .json-formatter-url { + text-decoration: underline; + color: $url-color; + cursor: pointer; + } + + .json-formatter-bracket { color: $bracket-color; } + .json-formatter-key { + color: $key-color; + cursor: pointer; + padding-right: 0.2rem; + } + .json-formatter-constructor-name { + cursor: pointer; + } + + .json-formatter-toggler { + line-height: 1.2rem; + font-size: 0.7rem; + vertical-align: middle; + opacity: $toggler-opacity; + cursor: pointer; + padding-right: 0.2rem; + + &::after { + display: inline-block; + transition: transform $rotate-time ease-in; + content: "►"; + } + } + + // Inline preview on hover (optional) + > a > .json-formatter-preview-text { + opacity: 0; + transition: opacity .15s ease-in; + font-style: italic; + } + + &:hover > a > .json-formatter-preview-text { + opacity: 0.6; + } + + // Open state + &.json-formatter-open { + > .json-formatter-toggler-link .json-formatter-toggler::after{ + transform: rotate(90deg); + } + > .json-formatter-children::after { + display: inline-block; + } + > a > .json-formatter-preview-text { + display: none; + } + &.json-formatter-empty::after { + display: block; + } + } +} + + +.json-formatter-row { + @include json-explorer-theme(); +} + +// Dark theme +.json-formatter-dark.json-formatter-row { + @include json-explorer-theme( + $default-color: white, + $string-color: #31F031, + $number-color: #66C2FF, + $boolean-color: #EC4242, + $null-color: #EEC97D, + $undefined-color: rgb(239, 143, 190), + $function-color: #FD48CB, + $rotate-time: 100ms, + $toggler-opacity: 0.6, + $toggler-color: #45376F, + $bracket-color: #9494FF, + $key-color: #23A0DB, + $url-color: #027BFF); +} diff --git a/public/test/test-main.js b/public/test/test-main.js index 6cdf19c5372..777e9d76afb 100644 --- a/public/test/test-main.js +++ b/public/test/test-main.js @@ -41,7 +41,6 @@ "jquery.flot.gauge": "vendor/flot/jquery.flot.gauge", "d3": "vendor/d3/d3.js", "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes", - "json-formatter-js": "vendor/npm/json-formatter-js/dist/json-formatter" }, packages: { diff --git a/tasks/options/copy.js b/tasks/options/copy.js index 6a902c7188b..59921576da3 100644 --- a/tasks/options/copy.js +++ b/tasks/options/copy.js @@ -34,7 +34,6 @@ module.exports = function(config) { 'remarkable/dist/*', 'virtual-scroll/**/*', 'mousetrap/**/*', - 'json-formatter-js/dist/*.js', ], dest: '<%= srcDir %>/vendor/npm' } diff --git a/yarn.lock b/yarn.lock index cb45e85d1fb..a9100c88e10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2561,10 +2561,6 @@ jshint@~2.9.4: shelljs "0.3.x" strip-json-comments "1.0.x" -json-formatter-js@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json-formatter-js/-/json-formatter-js-2.2.0.tgz#1ed987223ef2f1d945304597faae78b580a8212b" - json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" From 6ad1a396a543ff488093f38f3f743f2f8ebc768d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 19 May 2017 16:00:01 +0200 Subject: [PATCH 007/179] feat: query troubleshooter --- public/app/core/components/collapse_box.ts | 58 ++++++++++ .../components/json_explorer/json_explorer.ts | 8 +- public/app/core/components/response_viewer.ts | 63 ---------- public/app/core/core.ts | 6 +- public/app/features/panel/all.js | 1 + .../app/features/panel/metrics_ds_selector.ts | 27 ----- .../features/panel/query_troubleshooter.ts | 108 ++++++++++++++++++ public/app/partials/metrics.html | 4 +- public/sass/_grafana.scss | 2 +- public/sass/components/_collapse_box.scss | 29 +++++ public/sass/components/_json_explorer.scss | 2 +- public/sass/components/_response_viewer.scss | 6 - 12 files changed, 210 insertions(+), 104 deletions(-) create mode 100644 public/app/core/components/collapse_box.ts delete mode 100644 public/app/core/components/response_viewer.ts create mode 100644 public/app/features/panel/query_troubleshooter.ts create mode 100644 public/sass/components/_collapse_box.scss delete mode 100644 public/sass/components/_response_viewer.scss diff --git a/public/app/core/components/collapse_box.ts b/public/app/core/components/collapse_box.ts new file mode 100644 index 00000000000..05fac27904a --- /dev/null +++ b/public/app/core/components/collapse_box.ts @@ -0,0 +1,58 @@ +/// + +import coreModule from 'app/core/core_module'; + +const template = ` + +`; + +export class CollapseBoxCtrl { + isOpen: boolean; + onOpen: () => void; + + /** @ngInject **/ + constructor() { + this.isOpen = false; + } + + toggle() { + this.isOpen = !this.isOpen; + if (this.isOpen) { + this.onOpen(); + } + } +} + +export function collapseBox() { + return { + restrict: 'E', + template: template, + controller: CollapseBoxCtrl, + bindToController: true, + controllerAs: 'ctrl', + scope: { + "title": "@", + "isOpen": "=?", + "onOpen": "&" + }, + transclude: { + 'actions': '?collapseBoxActions', + 'body': 'collapseBoxBody', + }, + link: function(scope, elem, attrs) { + } + }; +} + +coreModule.directive('collapseBox', collapseBox); diff --git a/public/app/core/components/json_explorer/json_explorer.ts b/public/app/core/components/json_explorer/json_explorer.ts index 3f460968b77..4b57268c663 100644 --- a/public/app/core/components/json_explorer/json_explorer.ts +++ b/public/app/core/components/json_explorer/json_explorer.ts @@ -45,7 +45,7 @@ const _defaultConfig: JsonExplorerConfig = { * JsonExplorer allows you to render JSON objects in HTML with a * **collapsible** navigation. */ -export default class JsonExplorer { +export class JsonExplorer { // Hold the open state after the toggler is used private _isOpen: boolean = null; @@ -273,7 +273,7 @@ export default class JsonExplorer { * * @returns {HTMLDivElement} */ - render(): HTMLDivElement { + render(skipRoot = false): HTMLDivElement { // construct the root element and assign it to this.element this.element = createElement('div', 'row'); @@ -371,7 +371,9 @@ export default class JsonExplorer { } // append toggler and children elements to root element - this.element.appendChild(togglerLink); + if (!skipRoot) { + this.element.appendChild(togglerLink); + } this.element.appendChild(children); // if formatter is set to be open call appendChildren diff --git a/public/app/core/components/response_viewer.ts b/public/app/core/components/response_viewer.ts deleted file mode 100644 index fe332f070ec..00000000000 --- a/public/app/core/components/response_viewer.ts +++ /dev/null @@ -1,63 +0,0 @@ -/// - -import coreModule from 'app/core/core_module'; -import JsonExplorer from './json_explorer/json_explorer'; - - -const template = ` -
-
-
-`; - -export function responseViewer() { - return { - restrict: 'E', - template: template, - scope: {response: "="}, - link: function(scope, elem) { - var jsonElem = elem.find('.response-viewer-json'); - - scope.$watch("response", newVal => { - if (!newVal) { - elem.empty(); - return; - } - - if (scope.response.headers) { - delete scope.response.headers; - } - - if (scope.response.data) { - scope.response.response = scope.response.data; - delete scope.response.data; - } - - if (scope.response.config) { - scope.response.request = scope.response.config; - delete scope.response.config; - delete scope.response.request.transformRequest; - delete scope.response.request.transformResponse; - delete scope.response.request.paramSerializer; - delete scope.response.request.jsonpCallbackParam; - delete scope.response.request.headers; - delete scope.response.request.requestId; - delete scope.response.request.inspect; - delete scope.response.request.retry; - delete scope.response.request.timeout; - } - - - const formatter = new JsonExplorer(scope.response, 2, { - theme: 'dark', - }); - - const html = formatter.render(); - jsonElem.html(html); - }); - - } - }; -} - -coreModule.directive('responseViewer', responseViewer); diff --git a/public/app/core/core.ts b/public/app/core/core.ts index 4c5fa429677..f6b5046c3fc 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -45,7 +45,8 @@ import {assignModelProperties} from './utils/model_utils'; import {contextSrv} from './services/context_srv'; import {KeybindingSrv} from './services/keybindingSrv'; import {helpModal} from './components/help/help'; -import {responseViewer} from './components/response_viewer'; +import {collapseBox} from './components/collapse_box'; +import {JsonExplorer} from './components/json_explorer/json_explorer'; export { arrayJoin, @@ -69,5 +70,6 @@ export { contextSrv, KeybindingSrv, helpModal, - responseViewer, + collapseBox, + JsonExplorer, }; diff --git a/public/app/features/panel/all.js b/public/app/features/panel/all.js index 2f978e65345..b4afba4da1b 100644 --- a/public/app/features/panel/all.js +++ b/public/app/features/panel/all.js @@ -6,4 +6,5 @@ define([ './panel_editor_tab', './query_editor_row', './metrics_ds_selector', + './query_troubleshooter', ], function () {}); diff --git a/public/app/features/panel/metrics_ds_selector.ts b/public/app/features/panel/metrics_ds_selector.ts index 2a9137e6aa5..523268953a0 100644 --- a/public/app/features/panel/metrics_ds_selector.ts +++ b/public/app/features/panel/metrics_ds_selector.ts @@ -8,10 +8,6 @@ var module = angular.module('grafana.directives'); var template = ` -
- -
-
@@ -40,13 +36,6 @@ var template = `
-
- -
-
`; @@ -81,24 +70,8 @@ export class MetricsDsSelectorCtrl { this.dsSegment = uiSegmentSrv.newSegment({value: this.current.name, selectMode: true}); this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true}); - - appEvents.on('ds-request-response', this.onRequestResponse.bind(this), $scope); - appEvents.on('ds-request-error', this.onRequestError.bind(this), $scope); } - onRequestResponse(data) { - this.responseData = data; - } - - toggleShowResponse() { - this.showResponse = !this.showResponse; - } - - onRequestError(err) { - this.responseData = err; - this.responseData.isError = true; - this.showResponse = true; - } getOptions(includeBuiltin) { return Promise.resolve(this.datasources.filter(value => { diff --git a/public/app/features/panel/query_troubleshooter.ts b/public/app/features/panel/query_troubleshooter.ts new file mode 100644 index 00000000000..0c9dabb3ac1 --- /dev/null +++ b/public/app/features/panel/query_troubleshooter.ts @@ -0,0 +1,108 @@ +/// + +import _ from 'lodash'; +import appEvents from 'app/core/app_events'; +import {coreModule, JsonExplorer} from 'app/core/core'; + +const template = ` + + + Copy to clipboard + + +
+
+
+`; + +export class QueryTroubleshooterCtrl { + responseData: any; + showResponse: boolean; + panelCtrl: any; + renderJsonExplorer: (data) => void; + + /** @ngInject **/ + constructor($scope, private $timeout) { + appEvents.on('ds-request-response', this.onRequestResponse.bind(this), $scope); + appEvents.on('ds-request-error', this.onRequestError.bind(this), $scope); + } + + onRequestResponse(data) { + this.responseData = data; + } + + toggleShowResponse() { + this.showResponse = !this.showResponse; + } + + onRequestError(err) { + this.responseData = err; + this.responseData.isError = true; + this.showResponse = true; + } + + onOpen() { + if (!this.responseData) { + console.log('no data'); + return; + } + + var data = this.responseData; + if (data.headers) { + delete data.headers; + } + + if (data.config) { + data.request = data.config; + delete data.config; + delete data.request.transformRequest; + delete data.request.transformResponse; + delete data.request.paramSerializer; + delete data.request.jsonpCallbackParam; + delete data.request.headers; + delete data.request.requestId; + delete data.request.inspect; + delete data.request.retry; + delete data.request.timeout; + } + + if (data.data) { + data.response = data.data; + + delete data.data; + delete data.status; + delete data.statusText; + delete data.$$config; + } + + this.$timeout(_.partial(this.renderJsonExplorer, data), 10); + } +} + +export function queryTroubleshooter() { + return { + restrict: 'E', + template: template, + controller: QueryTroubleshooterCtrl, + bindToController: true, + controllerAs: 'ctrl', + scope: { + panelCtrl: "=" + }, + link: function(scope, elem, attrs, ctrl) { + + ctrl.renderJsonExplorer = function(data) { + var jsonElem = elem.find('.query-troubleshooter-json'); + + const formatter = new JsonExplorer(data, 2, { + theme: 'dark', + }); + + const html = formatter.render(true); + jsonElem.html(html); + }; + } + }; +} + +coreModule.directive('queryTroubleshooter', queryTroubleshooter); diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index 39c471eabd1..d3c6e6bcfc4 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -1,4 +1,6 @@ + +
@@ -8,7 +10,7 @@
- +
diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index c8f82ad845a..63ff5c6fe02 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -75,8 +75,8 @@ @import "components/jsontree"; @import "components/edit_sidemenu.scss"; @import "components/row.scss"; -@import "components/response_viewer.scss"; @import "components/json_explorer.scss"; +@import "components/collapse_box.scss"; // PAGES @import "pages/login"; diff --git a/public/sass/components/_collapse_box.scss b/public/sass/components/_collapse_box.scss new file mode 100644 index 00000000000..61abebaf634 --- /dev/null +++ b/public/sass/components/_collapse_box.scss @@ -0,0 +1,29 @@ +.collapse-box { + margin-bottom: $spacer; +} + +.collapse-box__header { + display: flex; + flex-direction: row; + padding: $input-padding-y $input-padding-x; + margin-right: $gf-form-margin; + background-color: $input-bg; + font-size: $font-size-sm; + margin-right: $gf-form-margin; + + border: $input-btn-border-width solid transparent; + @include border-radius($label-border-radius-sm); +} + +.collapse-box__header-title { + flex-grow: 1; +} + +.collapse-box__body { + padding: $input-padding-y*2 $input-padding-x; + background-color: $input-label-bg; + display: block; + margin-right: $gf-form-margin; + border: $input-btn-border-width solid transparent; + @include border-radius($label-border-radius-sm); +} diff --git a/public/sass/components/_json_explorer.scss b/public/sass/components/_json_explorer.scss index 3c4c19eceb7..d372c332176 100644 --- a/public/sass/components/_json_explorer.scss +++ b/public/sass/components/_json_explorer.scss @@ -36,7 +36,7 @@ .json-formatter-string { color: $string-color; - white-space: pre; + white-space: normal; word-wrap: break-word; } .json-formatter-number { color: $number-color; } diff --git a/public/sass/components/_response_viewer.scss b/public/sass/components/_response_viewer.scss deleted file mode 100644 index f554f98e382..00000000000 --- a/public/sass/components/_response_viewer.scss +++ /dev/null @@ -1,6 +0,0 @@ -.response-viewer { - background: $card-background; - box-shadow: $card-shadow; - padding: 1rem; - border-radius: 4px; -} From 5fcb966297948cb9f35f24a4ac140c136bb3fe96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 19 May 2017 17:35:36 +0200 Subject: [PATCH 008/179] feat: query troubleshooter progress --- public/app/core/components/collapse_box.ts | 14 +++--- .../features/panel/query_troubleshooter.ts | 50 +++++++++++-------- .../plugins/datasource/influxdb/datasource.ts | 10 ++-- public/sass/components/_collapse_box.scss | 8 +++ 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/public/app/core/components/collapse_box.ts b/public/app/core/components/collapse_box.ts index 05fac27904a..7fc234cb583 100644 --- a/public/app/core/components/collapse_box.ts +++ b/public/app/core/components/collapse_box.ts @@ -10,7 +10,7 @@ const template = ` {{ctrl.title}} -
+
@@ -19,18 +19,18 @@ const template = ` export class CollapseBoxCtrl { isOpen: boolean; - onOpen: () => void; + stateChanged: () => void; /** @ngInject **/ - constructor() { + constructor(private $timeout) { this.isOpen = false; } toggle() { this.isOpen = !this.isOpen; - if (this.isOpen) { - this.onOpen(); - } + this.$timeout(() => { + this.stateChanged(); + }); } } @@ -44,7 +44,7 @@ export function collapseBox() { scope: { "title": "@", "isOpen": "=?", - "onOpen": "&" + "stateChanged": "&" }, transclude: { 'actions': '?collapseBoxActions', diff --git a/public/app/features/panel/query_troubleshooter.ts b/public/app/features/panel/query_troubleshooter.ts index 0c9dabb3ac1..7d5e4dd0e9c 100644 --- a/public/app/features/panel/query_troubleshooter.ts +++ b/public/app/features/panel/query_troubleshooter.ts @@ -5,7 +5,8 @@ import appEvents from 'app/core/app_events'; import {coreModule, JsonExplorer} from 'app/core/core'; const template = ` - + Copy to clipboard @@ -16,38 +17,47 @@ const template = ` `; export class QueryTroubleshooterCtrl { - responseData: any; + isOpen: any; showResponse: boolean; panelCtrl: any; renderJsonExplorer: (data) => void; + onRequestErrorEventListener: any; + onRequestResponseEventListener: any; + hasError: boolean; /** @ngInject **/ constructor($scope, private $timeout) { - appEvents.on('ds-request-response', this.onRequestResponse.bind(this), $scope); - appEvents.on('ds-request-error', this.onRequestError.bind(this), $scope); + this.onRequestErrorEventListener = this.onRequestError.bind(this); + this.onRequestResponseEventListener = this.onRequestResponse.bind(this); + + appEvents.on('ds-request-error', this.onRequestErrorEventListener); + $scope.$on('$destroy', this.removeEventsListeners.bind(this)); } - onRequestResponse(data) { - this.responseData = data; - } - - toggleShowResponse() { - this.showResponse = !this.showResponse; + removeEventsListeners() { + appEvents.off('ds-request-response', this.onRequestResponseEventListener); + appEvents.off('ds-request-error', this.onRequestErrorEventListener); } onRequestError(err) { - this.responseData = err; - this.responseData.isError = true; - this.showResponse = true; + this.isOpen = true; + this.hasError = true; + this.onRequestResponse(err); } - onOpen() { - if (!this.responseData) { - console.log('no data'); - return; + stateChanged() { + console.log(this.isOpen); + if (this.isOpen) { + appEvents.on('ds-request-response', this.onRequestResponseEventListener); + this.panelCtrl.refresh(); + } else { + this.hasError = false; } + } + + onRequestResponse(data) { + data = _.cloneDeep(data); - var data = this.responseData; if (data.headers) { delete data.headers; } @@ -75,7 +85,7 @@ export class QueryTroubleshooterCtrl { delete data.$$config; } - this.$timeout(_.partial(this.renderJsonExplorer, data), 10); + this.$timeout(_.partial(this.renderJsonExplorer, data)); } } @@ -94,7 +104,7 @@ export function queryTroubleshooter() { ctrl.renderJsonExplorer = function(data) { var jsonElem = elem.find('.query-troubleshooter-json'); - const formatter = new JsonExplorer(data, 2, { + const formatter = new JsonExplorer(data, 3, { theme: 'dark', }); diff --git a/public/app/plugins/datasource/influxdb/datasource.ts b/public/app/plugins/datasource/influxdb/datasource.ts index 6af6a849e95..6bfcaf45fef 100644 --- a/public/app/plugins/datasource/influxdb/datasource.ts +++ b/public/app/plugins/datasource/influxdb/datasource.ts @@ -213,10 +213,12 @@ export default class InfluxDatasource { var currentUrl = self.urls.shift(); self.urls.push(currentUrl); - var params: any = { - u: self.username, - p: self.password, - }; + var params: any = {}; + + if (self.username) { + params.username = self.username; + params.password = self.password; + } if (self.database) { params.db = self.database; diff --git a/public/sass/components/_collapse_box.scss b/public/sass/components/_collapse_box.scss index 61abebaf634..96835ba9db9 100644 --- a/public/sass/components/_collapse_box.scss +++ b/public/sass/components/_collapse_box.scss @@ -1,5 +1,12 @@ .collapse-box { margin-bottom: $spacer; + + &--error { + .collapse-box__header { + background-color: $red; + color: $white; + } + } } .collapse-box__header { @@ -27,3 +34,4 @@ border: $input-btn-border-width solid transparent; @include border-radius($label-border-radius-sm); } + From 5909f9ef924371a7cf2e423e433ee991c4152725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 19 May 2017 21:32:23 +0200 Subject: [PATCH 009/179] feat: more work on metrics tab reworkings --- docker/blocks/graphite/fig | 1 - .../app/core/directives/plugin_component.ts | 4 +- public/app/features/panel/all.js | 1 - .../app/features/panel/metrics_panel_ctrl.ts | 3 +- ...{metrics_ds_selector.ts => metrics_tab.ts} | 83 ++++++------------- public/app/partials/metrics.html | 58 +++++++++++-- 6 files changed, 80 insertions(+), 70 deletions(-) rename public/app/features/panel/{metrics_ds_selector.ts => metrics_tab.ts} (50%) diff --git a/docker/blocks/graphite/fig b/docker/blocks/graphite/fig index 60acb8c1131..b7e030e388e 100644 --- a/docker/blocks/graphite/fig +++ b/docker/blocks/graphite/fig @@ -4,7 +4,6 @@ graphite: - "8080:80" - "2003:2003" volumes: - - /var/docker/gfdev/graphite:/opt/graphite/storage/whisper - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro diff --git a/public/app/core/directives/plugin_component.ts b/public/app/core/directives/plugin_component.ts index 4c098f60a4c..3c797aede3e 100644 --- a/public/app/core/directives/plugin_component.ts +++ b/public/app/core/directives/plugin_component.ts @@ -109,7 +109,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $ baseUrl: ds.meta.baseUrl, name: 'query-ctrl-' + ds.meta.id, bindings: {target: "=", panelCtrl: "=", datasource: "="}, - attrs: {"target": "target", "panel-ctrl": "ctrl", datasource: "datasource"}, + attrs: {"target": "target", "panel-ctrl": "ctrl.panelCtrl", datasource: "datasource"}, Component: dsModule.QueryCtrl }; }); @@ -127,7 +127,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $ baseUrl: ds.meta.baseUrl, name: 'query-options-ctrl-' + ds.meta.id, bindings: {panelCtrl: "="}, - attrs: {"panel-ctrl": "ctrl"}, + attrs: {"panel-ctrl": "ctrl.panelCtrl"}, Component: dsModule.QueryOptionsCtrl }; }); diff --git a/public/app/features/panel/all.js b/public/app/features/panel/all.js index b4afba4da1b..cba296643ef 100644 --- a/public/app/features/panel/all.js +++ b/public/app/features/panel/all.js @@ -5,6 +5,5 @@ define([ './query_ctrl', './panel_editor_tab', './query_editor_row', - './metrics_ds_selector', './query_troubleshooter', ], function () {}); diff --git a/public/app/features/panel/metrics_panel_ctrl.ts b/public/app/features/panel/metrics_panel_ctrl.ts index 000705d74d5..ee1b45b4abf 100644 --- a/public/app/features/panel/metrics_panel_ctrl.ts +++ b/public/app/features/panel/metrics_panel_ctrl.ts @@ -10,6 +10,7 @@ import * as rangeUtil from 'app/core/utils/rangeutil'; import * as dateMath from 'app/core/utils/datemath'; import {Subject} from 'vendor/npm/rxjs/Subject'; +import {metricsTabDirective} from './metrics_tab'; class MetricsPanelCtrl extends PanelCtrl { scope: any; @@ -61,7 +62,7 @@ class MetricsPanelCtrl extends PanelCtrl { } private onInitMetricsPanelEditMode() { - this.addEditorTab('Metrics', 'public/app/partials/metrics.html'); + this.addEditorTab('Metrics', metricsTabDirective); this.addEditorTab('Time range', 'public/app/features/panel/partials/panelTime.html'); } diff --git a/public/app/features/panel/metrics_ds_selector.ts b/public/app/features/panel/metrics_tab.ts similarity index 50% rename from public/app/features/panel/metrics_ds_selector.ts rename to public/app/features/panel/metrics_tab.ts index 523268953a0..4fe96be052b 100644 --- a/public/app/features/panel/metrics_ds_selector.ts +++ b/public/app/features/panel/metrics_tab.ts @@ -1,59 +1,26 @@ /// -import angular from 'angular'; import _ from 'lodash'; -import appEvents from 'app/core/app_events'; +import {DashboardModel} from '../dashboard/model'; -var module = angular.module('grafana.directives'); - -var template = ` - -
-
-
- - - - -
- -
- - - -
- -
-
-`; - - -export class MetricsDsSelectorCtrl { +export class MetricsTabCtrl { dsSegment: any; mixedDsSegment: any; dsName: string; + panel: any; panelCtrl: any; datasources: any[]; current: any; - lastResponse: any; - responseData: any; - showResponse: boolean; + nextRefId: string; + dashboard: DashboardModel; /** @ngInject */ constructor($scope, private uiSegmentSrv, datasourceSrv) { + this.panelCtrl = $scope.ctrl; + $scope.ctrl = this; + + this.panel = this.panelCtrl.panel; + this.dashboard = this.panelCtrl.dashboard; this.datasources = datasourceSrv.getMetricSources(); var dsValue = this.panelCtrl.panel.datasource || null; @@ -70,9 +37,9 @@ export class MetricsDsSelectorCtrl { this.dsSegment = uiSegmentSrv.newSegment({value: this.current.name, selectMode: true}); this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true}); + this.nextRefId = this.getNextQueryLetter(); } - getOptions(includeBuiltin) { return Promise.resolve(this.datasources.filter(value => { return includeBuiltin || !value.meta.builtIn; @@ -86,7 +53,6 @@ export class MetricsDsSelectorCtrl { if (ds) { this.current = ds; this.panelCtrl.setDatasource(ds); - this.responseData = null; } } @@ -100,22 +66,27 @@ export class MetricsDsSelectorCtrl { } } + getNextQueryLetter() { + return this.dashboard.getNextQueryLetter(this.panel); + } + addDataQuery() { - var target: any = {isNew: true}; + var target: any = { + isNew: true, + refId: this.getNextQueryLetter() + }; this.panelCtrl.panel.targets.push(target); + this.nextRefId = this.getNextQueryLetter(); } } -module.directive('metricsDsSelector', function() { +/** @ngInject **/ +export function metricsTabDirective() { + 'use strict'; return { restrict: 'E', - template: template, - controller: MetricsDsSelectorCtrl, - bindToController: true, - controllerAs: 'ctrl', - transclude: true, - scope: { - panelCtrl: "=" - } + scope: true, + templateUrl: 'public/app/partials/metrics.html', + controller: MetricsTabCtrl, }; -}); +} diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index d3c6e6bcfc4..131c85996ae 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -1,5 +1,21 @@ - +
+
+
+ + + + + +
+
+
@@ -7,16 +23,40 @@ -
+
+ +
+
+ + + + +
+
- + -
- - - - -
+ + + +
+ + + + +
+ +
+
From 912301fe24ee3c24405434ed96bae108523e7d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 10:14:41 +0200 Subject: [PATCH 010/179] query: more work on metrics tab changes --- .../app/features/panel/metrics_panel_ctrl.ts | 21 +++++++++++++++++++ public/app/features/panel/metrics_tab.ts | 21 +++++++------------ public/app/features/panel/panel_ctrl.ts | 12 ++++++++++- public/app/features/panel/query_editor_row.ts | 21 ++++--------------- public/app/partials/metrics.html | 8 ++----- public/sass/components/_gf-form.scss | 1 + public/sass/components/edit_sidemenu.scss | 1 - 7 files changed, 46 insertions(+), 39 deletions(-) diff --git a/public/app/features/panel/metrics_panel_ctrl.ts b/public/app/features/panel/metrics_panel_ctrl.ts index ee1b45b4abf..e3b4e9c77cf 100644 --- a/public/app/features/panel/metrics_panel_ctrl.ts +++ b/public/app/features/panel/metrics_panel_ctrl.ts @@ -1,5 +1,6 @@ /// +import angular from 'angular'; import config from 'app/core/config'; import $ from 'jquery'; import _ from 'lodash'; @@ -33,6 +34,7 @@ class MetricsPanelCtrl extends PanelCtrl { dataStream: any; dataSubscription: any; dataList: any; + nextRefId: string; constructor($scope, $injector) { super($scope, $injector); @@ -307,6 +309,25 @@ class MetricsPanelCtrl extends PanelCtrl { this.datasource = null; this.refresh(); } + + addQuery(target) { + target.refId = this.dashboard.getNextQueryLetter(this.panel); + + this.panel.targets.push(target); + this.nextRefId = this.dashboard.getNextQueryLetter(this.panel); + } + + removeQuery(target) { + var index = _.indexOf(this.panel.targets, target); + this.panel.targets.splice(index, 1); + this.nextRefId = this.dashboard.getNextQueryLetter(this.panel); + this.refresh(); + } + + moveQuery(target, direction) { + var index = _.indexOf(this.panel.targets, target); + _.move(this.panel.targets, index, index + direction); + } } export {MetricsPanelCtrl}; diff --git a/public/app/features/panel/metrics_tab.ts b/public/app/features/panel/metrics_tab.ts index 4fe96be052b..375c20b0ae0 100644 --- a/public/app/features/panel/metrics_tab.ts +++ b/public/app/features/panel/metrics_tab.ts @@ -36,8 +36,10 @@ export class MetricsTabCtrl { } this.dsSegment = uiSegmentSrv.newSegment({value: this.current.name, selectMode: true}); - this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true}); - this.nextRefId = this.getNextQueryLetter(); + this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true, fake: true}); + + // update next ref id + this.panelCtrl.nextRefId = this.dashboard.getNextQueryLetter(this.panel); } getOptions(includeBuiltin) { @@ -61,22 +63,13 @@ export class MetricsTabCtrl { var ds = _.find(this.datasources, {name: this.mixedDsSegment.value}); if (ds) { target.datasource = ds.name; - this.panelCtrl.panel.targets.push(target); + this.panelCtrl.addDataQuery(target); this.mixedDsSegment.value = ''; } } - getNextQueryLetter() { - return this.dashboard.getNextQueryLetter(this.panel); - } - - addDataQuery() { - var target: any = { - isNew: true, - refId: this.getNextQueryLetter() - }; - this.panelCtrl.panel.targets.push(target); - this.nextRefId = this.getNextQueryLetter(); + addQuery() { + this.panelCtrl.addQuery({isNew: true}); } } diff --git a/public/app/features/panel/panel_ctrl.ts b/public/app/features/panel/panel_ctrl.ts index 8de78291baa..a0645af43de 100644 --- a/public/app/features/panel/panel_ctrl.ts +++ b/public/app/features/panel/panel_ctrl.ts @@ -76,8 +76,18 @@ export class PanelCtrl { profiler.renderingCompleted(this.panel.id, this.timing); } + shouldSkipRefresh() { + // some scenarios we should never ignore refresh + if (this.fullscreen || this.dashboard.meta.soloMode || this.dashboard.snapshot) { + return false; + } + + return !this.isPanelVisible(); + } + refresh() { - if (!this.isPanelVisible() && !this.dashboard.meta.soloMode && !this.dashboard.snapshot) { + // somet + if (this.shouldSkipRefresh()) { this.skippedLastRefresh = true; return; } diff --git a/public/app/features/panel/query_editor_row.ts b/public/app/features/panel/query_editor_row.ts index 8249d84774f..1241d45db69 100644 --- a/public/app/features/panel/query_editor_row.ts +++ b/public/app/features/panel/query_editor_row.ts @@ -21,7 +21,7 @@ export class QueryRowCtrl { this.panel = this.panelCtrl.panel; if (!this.target.refId) { - this.target.refId = this.getNextQueryLetter(); + this.target.refId = this.panelCtrl.dashboard.getNextQueryLetter(this.panel); } this.toggleCollapse(true); @@ -40,16 +40,6 @@ export class QueryRowCtrl { this.panelCtrl.refresh(); } - getNextQueryLetter() { - var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - - return _.find(letters, refId => { - return _.every(this.panel.targets, function(other) { - return other.refId !== refId; - }); - }); - } - toggleCollapse(init) { if (!this.canCollapse) { return; @@ -87,19 +77,16 @@ export class QueryRowCtrl { delete this.panelCtrl.__collapsedQueryCache[this.target.refId]; } - this.panel.targets = _.without(this.panel.targets, this.target); - this.panelCtrl.refresh(); + this.panelCtrl.removeQuery(this.target); } duplicateQuery() { var clone = angular.copy(this.target); - clone.refId = this.getNextQueryLetter(); - this.panel.targets.push(clone); + this.panelCtrl.addQuery(clone); } moveQuery(direction) { - var index = _.indexOf(this.panel.targets, this.target); - _.move(this.panel.targets, index, index + direction); + this.panelCtrl.moveQuery(this.target, direction); } } diff --git a/public/app/partials/metrics.html b/public/app/partials/metrics.html index 131c85996ae..46f690bd775 100644 --- a/public/app/partials/metrics.html +++ b/public/app/partials/metrics.html @@ -2,10 +2,6 @@
- - @@ -31,9 +27,9 @@ - {{ctrl.nextRefId}} + {{ctrl.panelCtrl.nextRefId}} - diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 9c88435fcc2..313f4ced3ed 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -118,6 +118,7 @@ $gf-form-margin: 0.25rem; padding: $input-padding-y $input-padding-x; margin-right: $gf-form-margin; font-size: $font-size-base; + margin-right: $gf-form-margin; line-height: $input-line-height; color: $input-color; background-color: $input-bg; diff --git a/public/sass/components/edit_sidemenu.scss b/public/sass/components/edit_sidemenu.scss index 5da2f6a21ce..e84ae2c1914 100644 --- a/public/sass/components/edit_sidemenu.scss +++ b/public/sass/components/edit_sidemenu.scss @@ -10,7 +10,6 @@ } .edit-sidemenu-aside { - min-width: 6rem; margin-right: $spacer*2; } From b8aa6a8e4725bbec7a8c75a67a61b0cc0131092d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 10:48:47 +0200 Subject: [PATCH 011/179] query: more work on metrics tab changes --- public/app/core/directives/misc.js | 17 +++++++++++++- .../app/features/dashboard/shareModalCtrl.js | 17 +------------- .../features/panel/query_troubleshooter.ts | 22 +++++++++++++++---- public/sass/components/_collapse_box.scss | 7 ++++++ 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/public/app/core/directives/misc.js b/public/app/core/directives/misc.js index 8e1791af46c..ff005e76b64 100644 --- a/public/app/core/directives/misc.js +++ b/public/app/core/directives/misc.js @@ -1,9 +1,10 @@ define([ 'angular', + 'require', '../core_module', 'app/core/utils/kbn', ], -function (angular, coreModule, kbn) { +function (angular, require, coreModule, kbn) { 'use strict'; coreModule.default.directive('tip', function($compile) { @@ -18,6 +19,20 @@ function (angular, coreModule, kbn) { }; }); + coreModule.default.directive('clipboardButton',function() { + return function(scope, elem) { + require(['vendor/clipboard/dist/clipboard'], function(Clipboard) { + scope.clipboard = new Clipboard(elem[0]); + }); + + scope.$on('$destroy', function() { + if (scope.clipboard) { + scope.clipboard.destroy(); + } + }); + }; + }); + coreModule.default.directive('watchChange', function() { return { scope: { onchange: '&watchChange' }, diff --git a/public/app/features/dashboard/shareModalCtrl.js b/public/app/features/dashboard/shareModalCtrl.js index 6f3cb320bef..10f6a62fc3e 100644 --- a/public/app/features/dashboard/shareModalCtrl.js +++ b/public/app/features/dashboard/shareModalCtrl.js @@ -2,10 +2,9 @@ define(['angular', 'lodash', 'jquery', 'moment', - 'require', 'app/core/config', ], -function (angular, _, $, moment, require, config) { +function (angular, _, $, moment, config) { 'use strict'; var module = angular.module('grafana.controllers'); @@ -91,18 +90,4 @@ function (angular, _, $, moment, require, config) { }); - module.directive('clipboardButton',function() { - return function(scope, elem) { - require(['vendor/clipboard/dist/clipboard'], function(Clipboard) { - scope.clipboard = new Clipboard(elem[0]); - }); - - scope.$on('$destroy', function() { - if (scope.clipboard) { - scope.clipboard.destroy(); - } - }); - }; - }); - }); diff --git a/public/app/features/panel/query_troubleshooter.ts b/public/app/features/panel/query_troubleshooter.ts index 7d5e4dd0e9c..08388eb1b5e 100644 --- a/public/app/features/panel/query_troubleshooter.ts +++ b/public/app/features/panel/query_troubleshooter.ts @@ -8,7 +8,13 @@ const template = ` - Copy to clipboard + + Expand All + + + Collapse All + + Copy to Clipboard
@@ -24,6 +30,8 @@ export class QueryTroubleshooterCtrl { onRequestErrorEventListener: any; onRequestResponseEventListener: any; hasError: boolean; + allNodesExpanded: boolean; + jsonExplorer: JsonExplorer; /** @ngInject **/ constructor($scope, private $timeout) { @@ -46,7 +54,6 @@ export class QueryTroubleshooterCtrl { } stateChanged() { - console.log(this.isOpen); if (this.isOpen) { appEvents.on('ds-request-response', this.onRequestResponseEventListener); this.panelCtrl.refresh(); @@ -87,6 +94,13 @@ export class QueryTroubleshooterCtrl { this.$timeout(_.partial(this.renderJsonExplorer, data)); } + + toggleExpand(depth) { + if (this.jsonExplorer) { + this.allNodesExpanded = !this.allNodesExpanded; + this.jsonExplorer.openAtDepth(this.allNodesExpanded ? 20 : 1); + } + } } export function queryTroubleshooter() { @@ -104,11 +118,11 @@ export function queryTroubleshooter() { ctrl.renderJsonExplorer = function(data) { var jsonElem = elem.find('.query-troubleshooter-json'); - const formatter = new JsonExplorer(data, 3, { + ctrl.jsonExplorer = new JsonExplorer(data, 3, { theme: 'dark', }); - const html = formatter.render(true); + const html = ctrl.jsonExplorer.render(true); jsonElem.html(html); }; } diff --git a/public/sass/components/_collapse_box.scss b/public/sass/components/_collapse_box.scss index 96835ba9db9..38dbb3d8ca6 100644 --- a/public/sass/components/_collapse_box.scss +++ b/public/sass/components/_collapse_box.scss @@ -35,3 +35,10 @@ @include border-radius($label-border-radius-sm); } +.collapse-box__header-actions { + display: flex; + flex-direction: row; + a { + margin-left: $spacer; + } +} From 5e090b84ec5bed4a60cd466c96c6ee4a5c979171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 14:52:28 +0200 Subject: [PATCH 012/179] feat: Copy to clipboard now works in query troubleshooter --- public/app/core/directives/misc.js | 39 ++++++++++++------- .../dashboard/partials/shareModal.html | 4 +- .../app/features/dashboard/shareModalCtrl.js | 4 ++ .../features/dashboard/shareSnapshotCtrl.js | 4 ++ .../features/panel/query_troubleshooter.ts | 8 +++- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/public/app/core/directives/misc.js b/public/app/core/directives/misc.js index ff005e76b64..82076eebb7f 100644 --- a/public/app/core/directives/misc.js +++ b/public/app/core/directives/misc.js @@ -19,17 +19,26 @@ function (angular, require, coreModule, kbn) { }; }); - coreModule.default.directive('clipboardButton',function() { - return function(scope, elem) { - require(['vendor/clipboard/dist/clipboard'], function(Clipboard) { - scope.clipboard = new Clipboard(elem[0]); - }); + coreModule.default.directive('clipboardButton', function() { + return { + scope: { + getText: '&clipboardButton' + }, + link: function(scope, elem) { + require(['vendor/clipboard/dist/clipboard'], function(Clipboard) { + scope.clipboard = new Clipboard(elem[0], { + text: function() { + return scope.getText(); + } + }); + }); - scope.$on('$destroy', function() { - if (scope.clipboard) { - scope.clipboard.destroy(); - } - }); + scope.$on('$destroy', function() { + if (scope.clipboard) { + scope.clipboard.destroy(); + } + }); + } }; }); @@ -78,10 +87,10 @@ function (angular, require, coreModule, kbn) { text + tip + ''; var template = - '' + - ' '; + '' + + ' '; template = template + label; elem.addClass('gf-form-checkbox'); @@ -106,7 +115,7 @@ function (angular, require, coreModule, kbn) { var li = '' + '' + (item.text || '') + ''; + '>' + (item.text || '') + ''; if (item.submenu && item.submenu.length) { li += buildTemplate(item.submenu).join('\n'); diff --git a/public/app/features/dashboard/partials/shareModal.html b/public/app/features/dashboard/partials/shareModal.html index f9bf5ccf4ad..382baec1aba 100644 --- a/public/app/features/dashboard/partials/shareModal.html +++ b/public/app/features/dashboard/partials/shareModal.html @@ -86,7 +86,7 @@
- +
@@ -143,7 +143,7 @@ {{snapshotUrl}}
- + diff --git a/public/app/features/dashboard/shareModalCtrl.js b/public/app/features/dashboard/shareModalCtrl.js index 10f6a62fc3e..211b0efbac9 100644 --- a/public/app/features/dashboard/shareModalCtrl.js +++ b/public/app/features/dashboard/shareModalCtrl.js @@ -88,6 +88,10 @@ function (angular, _, $, moment, config) { $scope.imageUrl += '&tz=UTC' + encodeURIComponent(moment().format("Z")); }; + $scope.getShareUrl = function() { + return $scope.shareUrl; + }; + }); }); diff --git a/public/app/features/dashboard/shareSnapshotCtrl.js b/public/app/features/dashboard/shareSnapshotCtrl.js index 846dc0f7ed7..a30caf7f1c9 100644 --- a/public/app/features/dashboard/shareSnapshotCtrl.js +++ b/public/app/features/dashboard/shareSnapshotCtrl.js @@ -96,6 +96,10 @@ function (angular, _) { }); }; + $scope.getSnapshotUrl = function() { + return $scope.snapshotUrl; + }; + $scope.scrubDashboard = function(dash) { // change title dash.title = $scope.snapshot.name; diff --git a/public/app/features/panel/query_troubleshooter.ts b/public/app/features/panel/query_troubleshooter.ts index 08388eb1b5e..658d3bce003 100644 --- a/public/app/features/panel/query_troubleshooter.ts +++ b/public/app/features/panel/query_troubleshooter.ts @@ -14,7 +14,7 @@ const template = ` Collapse All - Copy to Clipboard + Copy to Clipboard
@@ -62,6 +62,12 @@ export class QueryTroubleshooterCtrl { } } + getClipboardText() { + if (this.jsonExplorer) { + return JSON.stringify(this.jsonExplorer.json, null, 2); + } + } + onRequestResponse(data) { data = _.cloneDeep(data); From 499e01d8327fea2636e1519713ba7658b3bd0ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 18:21:41 +0200 Subject: [PATCH 013/179] feat: metrics tab reworking --- public/app/features/panel/metrics_tab.ts | 5 +- public/app/features/panel/panel_editor_tab.ts | 7 +- .../app/features/panel/partials/metrics.html | 1 + .../panel/partials/metrics_tab.html} | 1 - .../features/panel/query_troubleshooter.ts | 8 +-- .../graphite/partials/query.options.html | 2 +- public/sass/_variables.dark.scss | 18 ++++++ public/sass/_variables.light.scss | 20 ++++++ public/sass/components/_collapse_box.scss | 24 +++---- public/sass/components/_json_explorer.scss | 64 +++++-------------- public/sass/grafana.dark.scss | 1 + 11 files changed, 81 insertions(+), 70 deletions(-) create mode 100644 public/app/features/panel/partials/metrics.html rename public/app/{partials/metrics.html => features/panel/partials/metrics_tab.html} (99%) diff --git a/public/app/features/panel/metrics_tab.ts b/public/app/features/panel/metrics_tab.ts index 375c20b0ae0..8f5e3dfdded 100644 --- a/public/app/features/panel/metrics_tab.ts +++ b/public/app/features/panel/metrics_tab.ts @@ -1,6 +1,7 @@ /// import _ from 'lodash'; +//import {coreModule} from 'app/core/core'; import {DashboardModel} from '../dashboard/model'; export class MetricsTabCtrl { @@ -79,7 +80,9 @@ export function metricsTabDirective() { return { restrict: 'E', scope: true, - templateUrl: 'public/app/partials/metrics.html', + templateUrl: 'public/app/features/panel/partials/metrics_tab.html', controller: MetricsTabCtrl, }; } + +//coreModule.directive('metricsTab', metricsTabDirective); diff --git a/public/app/features/panel/panel_editor_tab.ts b/public/app/features/panel/panel_editor_tab.ts index f6c11306678..9bbb979bcc0 100644 --- a/public/app/features/panel/panel_editor_tab.ts +++ b/public/app/features/panel/panel_editor_tab.ts @@ -16,10 +16,15 @@ function panelEditorTab(dynamicDirectiveSrv) { directive: scope => { var pluginId = scope.ctrl.pluginId; var tabIndex = scope.index; + // create a wrapper for directiveFn + // required for metrics tab directive + // that is the same for many panels but + // given different names in this function + var fn = () => scope.editorTab.directiveFn(); return Promise.resolve({ name: `panel-editor-tab-${pluginId}${tabIndex}`, - fn: scope.editorTab.directiveFn, + fn: fn, }); } }); diff --git a/public/app/features/panel/partials/metrics.html b/public/app/features/panel/partials/metrics.html new file mode 100644 index 00000000000..5d44948df4a --- /dev/null +++ b/public/app/features/panel/partials/metrics.html @@ -0,0 +1 @@ + diff --git a/public/app/partials/metrics.html b/public/app/features/panel/partials/metrics_tab.html similarity index 99% rename from public/app/partials/metrics.html rename to public/app/features/panel/partials/metrics_tab.html index 46f690bd775..9ecfd769f7a 100644 --- a/public/app/partials/metrics.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -1,4 +1,3 @@ -
diff --git a/public/app/features/panel/query_troubleshooter.ts b/public/app/features/panel/query_troubleshooter.ts index 658d3bce003..bbbe0e70935 100644 --- a/public/app/features/panel/query_troubleshooter.ts +++ b/public/app/features/panel/query_troubleshooter.ts @@ -9,10 +9,10 @@ const template = ` ng-class="{'collapse-box--error': ctrl.hasError}"> - Expand All + Expand All - Collapse All + Collapse All Copy to Clipboard @@ -124,9 +124,7 @@ export function queryTroubleshooter() { ctrl.renderJsonExplorer = function(data) { var jsonElem = elem.find('.query-troubleshooter-json'); - ctrl.jsonExplorer = new JsonExplorer(data, 3, { - theme: 'dark', - }); + ctrl.jsonExplorer = new JsonExplorer(data, 3, { }); const html = ctrl.jsonExplorer.render(true); jsonElem.html(html); diff --git a/public/app/plugins/datasource/graphite/partials/query.options.html b/public/app/plugins/datasource/graphite/partials/query.options.html index 05aecf4b44a..22c7d8c0be8 100644 --- a/public/app/plugins/datasource/graphite/partials/query.options.html +++ b/public/app/plugins/datasource/graphite/partials/query.options.html @@ -1,4 +1,4 @@ -
+
diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index 7e7865b6b88..c6bee53b14b 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -280,3 +280,21 @@ $card-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, .1), 1px 1px 0 0 rgba(0, 0, 0, .3) $footer-link-color: $gray-1; $footer-link-hover: $gray-4; +// collapse box +$collapse-box-body-border: $dark-5; +$collapse-box-body-error-border: $red; + +// json-explorer +$json-explorer-default-color: white; +$json-explorer-string-color: #31F031; +$json-explorer-number-color: #66C2FF; +$json-explorer-boolean-color: #EC4242; +$json-explorer-null-color: #EEC97D; +$json-explorer-undefined-color: rgb(239, 143, 190); +$json-explorer-function-color: #FD48CB; +$json-explorer-rotate-time: 100ms; +$json-explorer-toggler-opacity: 0.6; +$json-explorer-toggler-color: #45376F; +$json-explorer-bracket-color: #9494FF; +$json-explorer-key-color: #23A0DB; +$json-explorer-url-color: #027BFF; diff --git a/public/sass/_variables.light.scss b/public/sass/_variables.light.scss index a10f94afc1b..de23ae512f1 100644 --- a/public/sass/_variables.light.scss +++ b/public/sass/_variables.light.scss @@ -303,3 +303,23 @@ $card-shadow: -1px -1px 0 0 hsla(0, 0%, 100%, .1), 1px 1px 0 0 rgba(0, 0, 0, .1) // footer $footer-link-color: $gray-3; $footer-link-hover: $dark-5; + +// collapse box +$collapse-box-body-border: $gray-4; +$collapse-box-body-error-border: $red; + +// json explorer +$json-explorer-default-color: black; +$json-explorer-string-color: green; +$json-explorer-number-color: blue; +$json-explorer-boolean-color: red; +$json-explorer-null-color: #855A00; +$json-explorer-undefined-color: rgb(202, 11, 105); +$json-explorer-function-color: #FF20ED; +$json-explorer-rotate-time: 100ms; +$json-explorer-toggler-opacity: 0.6; +$json-explorer-toggler-color: #45376F; +$json-explorer-bracket-color: blue; +$json-explorer-key-color: #00008B; +$json-explorer-url-color: blue; + diff --git a/public/sass/components/_collapse_box.scss b/public/sass/components/_collapse_box.scss index 38dbb3d8ca6..a8a5db46abe 100644 --- a/public/sass/components/_collapse_box.scss +++ b/public/sass/components/_collapse_box.scss @@ -1,12 +1,5 @@ .collapse-box { margin-bottom: $spacer; - - &--error { - .collapse-box__header { - background-color: $red; - color: $white; - } - } } .collapse-box__header { @@ -14,12 +7,15 @@ flex-direction: row; padding: $input-padding-y $input-padding-x; margin-right: $gf-form-margin; - background-color: $input-bg; + background-color: $input-label-bg; font-size: $font-size-sm; margin-right: $gf-form-margin; - - border: $input-btn-border-width solid transparent; + border: $input-btn-border-width solid $collapse-box-body-border; @include border-radius($label-border-radius-sm); + + &--error { + border-color: $collapse-box-body-error-border; + } } .collapse-box__header-title { @@ -28,11 +24,15 @@ .collapse-box__body { padding: $input-padding-y*2 $input-padding-x; - background-color: $input-label-bg; display: block; margin-right: $gf-form-margin; - border: $input-btn-border-width solid transparent; + border: $input-btn-border-width solid $collapse-box-body-border; + border-top: none; @include border-radius($label-border-radius-sm); + + &--error { + border-color: $collapse-box-body-error-border; + } } .collapse-box__header-actions { diff --git a/public/sass/components/_json_explorer.scss b/public/sass/components/_json_explorer.scss index d372c332176..b6a2f089db6 100644 --- a/public/sass/components/_json_explorer.scss +++ b/public/sass/components/_json_explorer.scss @@ -1,21 +1,9 @@ -@mixin json-explorer-theme( - $default-color: black, - $string-color: green, - $number-color: blue, - $boolean-color: red, - $null-color: #855A00, - $undefined-color: rgb(202, 11, 105), - $function-color: #FF20ED, - $rotate-time: 100ms, - $toggler-opacity: 0.6, - $toggler-color: #45376F, - $bracket-color: blue, - $key-color: #00008B, - $url-color: blue) { +.json-formatter-row { font-family: monospace; + &, a, a:hover { - color: $default-color; + color: $json-explorer-default-color; text-decoration: none; } @@ -35,25 +23,25 @@ } .json-formatter-string { - color: $string-color; + color: $json-explorer-string-color; white-space: normal; word-wrap: break-word; } - .json-formatter-number { color: $number-color; } - .json-formatter-boolean { color: $boolean-color; } - .json-formatter-null { color: $null-color; } - .json-formatter-undefined { color: $undefined-color; } - .json-formatter-function { color: $function-color; } - .json-formatter-date { background-color: fade($default-color, 5%); } + .json-formatter-number { color: $json-explorer-number-color; } + .json-formatter-boolean { color: $json-explorer-boolean-color; } + .json-formatter-null { color: $json-explorer-null-color; } + .json-formatter-undefined { color: $json-explorer-undefined-color; } + .json-formatter-function { color: $json-explorer-function-color; } + .json-formatter-date { background-color: fade($json-explorer-default-color, 5%); } .json-formatter-url { text-decoration: underline; - color: $url-color; + color: $json-explorer-url-color; cursor: pointer; } - .json-formatter-bracket { color: $bracket-color; } + .json-formatter-bracket { color: $json-explorer-bracket-color; } .json-formatter-key { - color: $key-color; + color: $json-explorer-key-color; cursor: pointer; padding-right: 0.2rem; } @@ -65,13 +53,13 @@ line-height: 1.2rem; font-size: 0.7rem; vertical-align: middle; - opacity: $toggler-opacity; + opacity: $json-explorer-toggler-opacity; cursor: pointer; padding-right: 0.2rem; &::after { display: inline-block; - transition: transform $rotate-time ease-in; + transition: transform $json-explorer-rotate-time ease-in; content: "►"; } } @@ -104,25 +92,3 @@ } } - -.json-formatter-row { - @include json-explorer-theme(); -} - -// Dark theme -.json-formatter-dark.json-formatter-row { - @include json-explorer-theme( - $default-color: white, - $string-color: #31F031, - $number-color: #66C2FF, - $boolean-color: #EC4242, - $null-color: #EEC97D, - $undefined-color: rgb(239, 143, 190), - $function-color: #FD48CB, - $rotate-time: 100ms, - $toggler-opacity: 0.6, - $toggler-color: #45376F, - $bracket-color: #9494FF, - $key-color: #23A0DB, - $url-color: #027BFF); -} diff --git a/public/sass/grafana.dark.scss b/public/sass/grafana.dark.scss index 53193d213e6..858d6ace336 100644 --- a/public/sass/grafana.dark.scss +++ b/public/sass/grafana.dark.scss @@ -1,3 +1,4 @@ @import "variables"; @import "variables.dark"; @import "grafana"; + From 4a2c405ac0001be46f98a31624a83f74ac5c12ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 18:35:34 +0200 Subject: [PATCH 014/179] feat: metris tab, moved data source selector --- .../app/features/panel/partials/metrics.html | 1 - .../features/panel/partials/metrics_tab.html | 33 ++++++++----------- 2 files changed, 14 insertions(+), 20 deletions(-) delete mode 100644 public/app/features/panel/partials/metrics.html diff --git a/public/app/features/panel/partials/metrics.html b/public/app/features/panel/partials/metrics.html deleted file mode 100644 index 5d44948df4a..00000000000 --- a/public/app/features/panel/partials/metrics.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index 9ecfd769f7a..5cffbc19666 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -1,17 +1,3 @@ -
-
-
- - - -
-
-
-
@@ -41,16 +27,25 @@ - +
- - - - +
+
+ + +
+
+ + + + +
From a8673a2e330bf9c33a7c071f6d7289ce94eb7f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 22:41:34 +0200 Subject: [PATCH 015/179] feat: metrics tab --- .../features/panel/partials/metrics_tab.html | 2 +- .../app/features/panel/query_troubleshooter.ts | 15 +++++++++++++-- public/sass/components/_collapse_box.scss | 18 ++++++++++-------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index 5cffbc19666..b9e704bbcca 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -27,7 +27,7 @@ - +
diff --git a/public/app/features/panel/query_troubleshooter.ts b/public/app/features/panel/query_troubleshooter.ts index bbbe0e70935..68c2bf35c10 100644 --- a/public/app/features/panel/query_troubleshooter.ts +++ b/public/app/features/panel/query_troubleshooter.ts @@ -17,6 +17,7 @@ const template = ` Copy to Clipboard +
@@ -24,6 +25,7 @@ const template = ` export class QueryTroubleshooterCtrl { isOpen: any; + isLoading: boolean; showResponse: boolean; panelCtrl: any; renderJsonExplorer: (data) => void; @@ -57,8 +59,7 @@ export class QueryTroubleshooterCtrl { if (this.isOpen) { appEvents.on('ds-request-response', this.onRequestResponseEventListener); this.panelCtrl.refresh(); - } else { - this.hasError = false; + this.isLoading = true; } } @@ -69,6 +70,7 @@ export class QueryTroubleshooterCtrl { } onRequestResponse(data) { + this.isLoading = false; data = _.cloneDeep(data); if (data.headers) { @@ -92,6 +94,15 @@ export class QueryTroubleshooterCtrl { if (data.data) { data.response = data.data; + if (data.status === 200) { + // if we are in error state, assume we automatically opened + // and auto close it again + if (this.hasError) { + this.hasError = false; + this.isOpen = false; + } + } + delete data.data; delete data.status; delete data.statusText; diff --git a/public/sass/components/_collapse_box.scss b/public/sass/components/_collapse_box.scss index a8a5db46abe..86658cfcfec 100644 --- a/public/sass/components/_collapse_box.scss +++ b/public/sass/components/_collapse_box.scss @@ -1,5 +1,15 @@ .collapse-box { margin-bottom: $spacer; + + &--error { + .collapse-box__header { + border-color: $collapse-box-body-error-border; + } + .collapse-box__body { + border-color: $collapse-box-body-error-border; + } + } + } .collapse-box__header { @@ -12,10 +22,6 @@ margin-right: $gf-form-margin; border: $input-btn-border-width solid $collapse-box-body-border; @include border-radius($label-border-radius-sm); - - &--error { - border-color: $collapse-box-body-error-border; - } } .collapse-box__header-title { @@ -29,10 +35,6 @@ border: $input-btn-border-width solid $collapse-box-body-border; border-top: none; @include border-radius($label-border-radius-sm); - - &--error { - border-color: $collapse-box-body-error-border; - } } .collapse-box__header-actions { From d840645dd742054c8b4bf6146220576e1feb96be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 22:55:36 +0200 Subject: [PATCH 016/179] feat: metrics tab, minor change --- public/app/core/services/backend_srv.ts | 2 +- public/app/features/panel/query_troubleshooter.ts | 11 +++++++++-- public/sass/_variables.dark.scss | 6 +++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 85cc63d057f..5965793d738 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -170,7 +170,7 @@ export class BackendSrv { }); } - //populate error obj on Internal Error + // populate error obj on Internal Error if (_.isString(err.data) && err.status === 500) { err.data = { error: err.statusText, diff --git a/public/app/features/panel/query_troubleshooter.ts b/public/app/features/panel/query_troubleshooter.ts index 68c2bf35c10..84ae2045dc7 100644 --- a/public/app/features/panel/query_troubleshooter.ts +++ b/public/app/features/panel/query_troubleshooter.ts @@ -40,6 +40,7 @@ export class QueryTroubleshooterCtrl { this.onRequestErrorEventListener = this.onRequestError.bind(this); this.onRequestResponseEventListener = this.onRequestResponse.bind(this); + appEvents.on('ds-request-response', this.onRequestResponseEventListener); appEvents.on('ds-request-error', this.onRequestErrorEventListener); $scope.$on('$destroy', this.removeEventsListeners.bind(this)); } @@ -57,7 +58,6 @@ export class QueryTroubleshooterCtrl { stateChanged() { if (this.isOpen) { - appEvents.on('ds-request-response', this.onRequestResponseEventListener); this.panelCtrl.refresh(); this.isLoading = true; } @@ -70,6 +70,11 @@ export class QueryTroubleshooterCtrl { } onRequestResponse(data) { + // ignore if closed + if (!this.isOpen) { + return; + } + this.isLoading = false; data = _.cloneDeep(data); @@ -135,7 +140,9 @@ export function queryTroubleshooter() { ctrl.renderJsonExplorer = function(data) { var jsonElem = elem.find('.query-troubleshooter-json'); - ctrl.jsonExplorer = new JsonExplorer(data, 3, { }); + ctrl.jsonExplorer = new JsonExplorer(data, 3, { + animateOpen: true, + }); const html = ctrl.jsonExplorer.render(true); jsonElem.html(html); diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index c6bee53b14b..30b769c3cda 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -286,9 +286,9 @@ $collapse-box-body-error-border: $red; // json-explorer $json-explorer-default-color: white; -$json-explorer-string-color: #31F031; -$json-explorer-number-color: #66C2FF; -$json-explorer-boolean-color: #EC4242; +$json-explorer-string-color: #23d662; +$json-explorer-number-color: $variable; +$json-explorer-boolean-color: $variable; $json-explorer-null-color: #EEC97D; $json-explorer-undefined-color: rgb(239, 143, 190); $json-explorer-function-color: #FD48CB; From 7cb64662513f1470f3149b51de07729336f2a6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 20 May 2017 23:43:59 +0200 Subject: [PATCH 017/179] feat: query troubleshooter, improving json explorer --- .../components/json_explorer/json_explorer.ts | 103 +++++++----------- public/sass/_variables.dark.scss | 2 +- public/sass/components/_json_explorer.scss | 4 + 3 files changed, 44 insertions(+), 65 deletions(-) diff --git a/public/app/core/components/json_explorer/json_explorer.ts b/public/app/core/components/json_explorer/json_explorer.ts index 4b57268c663..c2810f23b54 100644 --- a/public/app/core/components/json_explorer/json_explorer.ts +++ b/public/app/core/components/json_explorer/json_explorer.ts @@ -11,6 +11,8 @@ import { createElement } from './helpers'; +import _ from 'lodash'; + const DATE_STRING_REGEX = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/; const PARTIAL_DATE_REGEX = /\d{2}:\d{2}:\d{2} GMT-\d{4}/; const JSON_DATE_REGEX = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/; @@ -21,18 +23,12 @@ const MAX_ANIMATED_TOGGLE_ITEMS = 10; const requestAnimationFrame = window.requestAnimationFrame || function(cb: ()=>void) { cb(); return 0; }; export interface JsonExplorerConfig { - hoverPreviewEnabled?: boolean; - hoverPreviewArrayCount?: number; - hoverPreviewFieldCount?: number; animateOpen?: boolean; animateClose?: boolean; theme?: string; } const _defaultConfig: JsonExplorerConfig = { - hoverPreviewEnabled: false, - hoverPreviewArrayCount: 100, - hoverPreviewFieldCount: 5, animateOpen: true, animateClose: true, theme: null @@ -53,6 +49,8 @@ export class JsonExplorer { // A reference to the element that we render to private element: Element; + private skipChildren = false; + /** * @param {object} json The JSON object you want to render. It has to be an * object or array. Do NOT pass raw JSON string. @@ -82,17 +80,6 @@ export class JsonExplorer { * context */ constructor(public json: any, private open = 1, private config: JsonExplorerConfig = _defaultConfig, private key?: string) { - - // Setting default values for config object - if (this.config.hoverPreviewEnabled === undefined) { - this.config.hoverPreviewEnabled = _defaultConfig.hoverPreviewEnabled; - } - if (this.config.hoverPreviewArrayCount === undefined) { - this.config.hoverPreviewArrayCount = _defaultConfig.hoverPreviewArrayCount; - } - if (this.config.hoverPreviewFieldCount === undefined) { - this.config.hoverPreviewFieldCount = _defaultConfig.hoverPreviewFieldCount; - } } /* @@ -236,54 +223,48 @@ export class JsonExplorer { } } - /** - * Generates inline preview - * - * @returns {string} - */ - getInlinepreview() { - if (this.isArray) { - - // if array length is greater then 100 it shows "Array[101]" - if (this.json.length > this.config.hoverPreviewArrayCount) { - return `Array[${this.json.length}]`; - } else { - return `[${this.json.map(getPreview).join(', ')}]`; - } - } else { - - const keys = this.keys; - - // the first five keys (like Chrome Developer Tool) - const narrowKeys = keys.slice(0, this.config.hoverPreviewFieldCount); - - // json value schematic information - const kvs = narrowKeys.map(key => `${key}:${getPreview(this.json[key])}`); - - // if keys count greater then 5 then show ellipsis - const ellipsis = keys.length >= this.config.hoverPreviewFieldCount ? '…' : ''; - - return `{${kvs.join(', ')}${ellipsis}}`; - } + isNumberArray() { + return (this.json.length > 0 && this.json.length < 4) && + (_.isNumber(this.json[0]) || _.isNumber(this.json[1])); } + renderArray() { + const arrayWrapperSpan = createElement('span'); + arrayWrapperSpan.appendChild(createElement('span', 'bracket', '[')); + + // some pretty handling of number arrays + if (this.isNumberArray()) { + this.json.forEach((val, index) => { + if (index > 0) { + arrayWrapperSpan.appendChild(createElement('span', 'array-comma', ',')); + } + arrayWrapperSpan.appendChild(createElement('span', 'number', val)); + }); + this.skipChildren = true; + } else { + arrayWrapperSpan.appendChild(createElement('span', 'number', (this.json.length))); + } + + arrayWrapperSpan.appendChild(createElement('span', 'bracket', ']')); + return arrayWrapperSpan; + } /** * Renders an HTML element and installs event listeners * * @returns {HTMLDivElement} - */ + */ render(skipRoot = false): HTMLDivElement { - // construct the root element and assign it to this.element this.element = createElement('div', 'row'); // construct the toggler link const togglerLink = createElement('a', 'toggler-link'); + const togglerIcon = createElement('span', 'toggler'); // if this is an object we need a wrapper span (toggler) if (this.isObject) { - togglerLink.appendChild(createElement('span', 'toggler')); + togglerLink.appendChild(togglerIcon); } // if this is child of a parent formatter we need to append the key @@ -293,7 +274,6 @@ export class JsonExplorer { // Value for objects and arrays if (this.isObject) { - // construct the value holder element const value = createElement('span', 'value'); @@ -306,18 +286,14 @@ export class JsonExplorer { // if it's an array append the array specific elements like brackets and length if (this.isArray) { - const arrayWrapperSpan = createElement('span'); - arrayWrapperSpan.appendChild(createElement('span', 'bracket', '[')); - arrayWrapperSpan.appendChild(createElement('span', 'number', (this.json.length))); - arrayWrapperSpan.appendChild(createElement('span', 'bracket', ']')); + const arrayWrapperSpan = this.renderArray(); objectWrapperSpan.appendChild(arrayWrapperSpan); } // append object wrapper span to toggler link value.appendChild(objectWrapperSpan); togglerLink.appendChild(value); - - // Primitive values + // Primitive values } else { // make a value holder element @@ -341,13 +317,6 @@ export class JsonExplorer { togglerLink.appendChild(value); } - // if hover preview is enabled, append the inline preview element - if (this.isObject && this.config.hoverPreviewEnabled) { - const preview = createElement('span', 'preview-text'); - preview.appendChild(document.createTextNode(this.getInlinepreview())); - togglerLink.appendChild(preview); - } - // construct a children element const children = createElement('div', 'children'); @@ -374,7 +343,13 @@ export class JsonExplorer { if (!skipRoot) { this.element.appendChild(togglerLink); } - this.element.appendChild(children); + + if (!this.skipChildren) { + this.element.appendChild(children); + } else { + // remove togglerIcon + togglerLink.removeChild(togglerIcon); + } // if formatter is set to be open call appendChildren if (this.isObject && this.isOpen) { diff --git a/public/sass/_variables.dark.scss b/public/sass/_variables.dark.scss index 30b769c3cda..2a9d5256252 100644 --- a/public/sass/_variables.dark.scss +++ b/public/sass/_variables.dark.scss @@ -285,7 +285,7 @@ $collapse-box-body-border: $dark-5; $collapse-box-body-error-border: $red; // json-explorer -$json-explorer-default-color: white; +$json-explorer-default-color: $text-color; $json-explorer-string-color: #23d662; $json-explorer-number-color: $variable; $json-explorer-boolean-color: $variable; diff --git a/public/sass/components/_json_explorer.scss b/public/sass/components/_json_explorer.scss index b6a2f089db6..37c610b2002 100644 --- a/public/sass/components/_json_explorer.scss +++ b/public/sass/components/_json_explorer.scss @@ -44,11 +44,15 @@ color: $json-explorer-key-color; cursor: pointer; padding-right: 0.2rem; + margin-right: 4px; } + .json-formatter-constructor-name { cursor: pointer; } + .json-formatter-array-comma { margin-right: 4px; } + .json-formatter-toggler { line-height: 1.2rem; font-size: 0.7rem; From 525da95f49350711d5fdc1f724a4b3b313f46edc Mon Sep 17 00:00:00 2001 From: Michael Ambrose Date: Fri, 5 May 2017 16:22:03 -0400 Subject: [PATCH 018/179] Updated cloudwatch plugin to allow specific tag selection Tags come back from AWS as a key value pair inside an array This array is now converted to an object Tags can be selected when using the 'ec2_instance_attribute' query Example: `ec2_instance_attribute(us-east-1, Tags.Name, { "tag:Grafana": [ "true" ] })` --- .../app/plugins/datasource/cloudwatch/datasource.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/cloudwatch/datasource.js b/public/app/plugins/datasource/cloudwatch/datasource.js index 60c7e167a06..b9f9b062ce6 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.js +++ b/public/app/plugins/datasource/cloudwatch/datasource.js @@ -260,7 +260,17 @@ function (angular, _, moment, dateMath, kbn, templatingVariable, CloudWatchAnnot return this.performEC2DescribeInstances(region, filters, null).then(function(result) { var attributes = _.chain(result.Reservations) .map(function(reservations) { - return _.map(reservations.Instances, targetAttributeName); + return _.map(reservations.Instances, function(instance) { + var tags = {}; + _.each(instance.Tags, function(tag) { + tags[tag.Key] = tag.Value; + }); + instance.Tags = tags; + return instance; + }); + }) + .map(function(instances) { + return _.map(instances, targetAttributeName); }) .flatten().uniq().sortBy().value(); return transformSuggestData(attributes); From f0169656ba57dcea47eaed808cfb7758b39a6755 Mon Sep 17 00:00:00 2001 From: Michael Ambrose Date: Wed, 7 Jun 2017 16:07:47 -0400 Subject: [PATCH 019/179] Added test to for Cloudwatch EC2 tag selection --- .../cloudwatch/specs/datasource_specs.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts index afc0f4a5962..28fd524663b 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource_specs.ts @@ -318,4 +318,38 @@ describe('CloudWatchDatasource', function() { expect(scenario.request.data.action).to.be('ListMetrics'); }); }); + + describeMetricFindQuery('ec2_instance_attribute(us-east-1, Tags.Name, { "tag:team": [ "sysops" ] })', scenario => { + scenario.setup(() => { + scenario.requestResponse = { + Reservations: [ + { + Instances: [ + { + Tags: [ + { Key: 'InstanceId', Value: 'i-123456' }, + { Key: 'Name', Value: 'Sysops Dev Server' }, + { Key: 'env', Value: 'dev' }, + { Key: 'team', Value: 'sysops' } + ] + }, + { + Tags: [ + { Key: 'InstanceId', Value: 'i-789012' }, + { Key: 'Name', Value: 'Sysops Staging Server' }, + { Key: 'env', Value: 'staging' }, + { Key: 'team', Value: 'sysops' } + ] + } + ] + } + ] + }; + }); + + it('should return the "Name" tag for each instance', function() { + expect(scenario.result[0].text).to.be('Sysops Dev Server'); + expect(scenario.result[1].text).to.be('Sysops Staging Server'); + }); + }); }); From aa3a737fea8a77a858d5d022c3ce70766e161d35 Mon Sep 17 00:00:00 2001 From: Michael Ambrose Date: Wed, 7 Jun 2017 16:52:45 -0400 Subject: [PATCH 020/179] Updated cloudwatch doc to be more clear on ec2_instance_attribute usage and added Tag selection example --- .../features/datasources/cloudwatch.md | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/docs/sources/features/datasources/cloudwatch.md b/docs/sources/features/datasources/cloudwatch.md index 8d77e5c59c0..61dd90d2881 100644 --- a/docs/sources/features/datasources/cloudwatch.md +++ b/docs/sources/features/datasources/cloudwatch.md @@ -84,8 +84,8 @@ Name | Description *metrics(namespace, [region])* | Returns a list of metrics in the namespace. (specify region for custom metrics) *dimension_keys(namespace)* | Returns a list of dimension keys in the namespace. *dimension_values(region, namespace, metric, dimension_key)* | Returns a list of dimension values matching the specified `region`, `namespace`, `metric` and `dimension_key`. -*ebs_volume_ids(region, instance_id)* | Returns a list of volume id matching the specified `region`, `instance_id`. -*ec2_instance_attribute(region, attribute_name, filters)* | Returns a list of attribute matching the specified `region`, `attribute_name`, `filters`. +*ebs_volume_ids(region, instance_id)* | Returns a list of volume ids matching the specified `region`, `instance_id`. +*ec2_instance_attribute(region, attribute_name, filters)* | Returns a list of attributes matching the specified `region`, `attribute_name`, `filters`. For details about the metrics CloudWatch provides, please refer to the [CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html). @@ -101,10 +101,13 @@ Query | Service *dimension_values(us-east-1,AWS/RDS,CPUUtilization,DBInstanceIdentifier)* | RDS *dimension_values(us-east-1,AWS/S3,BucketSizeBytes,BucketName)* | S3 -#### ec2_instance_attribute JSON filters +## ec2_instance_attribute examples -The `ec2_instance_attribute` query take `filters` in JSON format. +### JSON filters + +The `ec2_instance_attribute` query takes `filters` in JSON format. You can specify [pre-defined filters of ec2:DescribeInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html). +Note that the actual filtering takes place on Amazon's servers, not in Grafana. Filters syntax: @@ -116,6 +119,45 @@ Example `ec2_instance_attribute()` query ec2_instance_attribute(us-east-1, InstanceId, { "tag:Environment": [ "production" ] }) +### Selecting Attributes + +Only 1 attribute per instance can be returned. Any flat attribute can be selected (i.e. if the attribute has a single value and isn't an object or array). Below is a list of available flat attributes: + + * `AmiLaunchIndex` + * `Architecture` + * `ClientToken` + * `EbsOptimized` + * `EnaSupport` + * `Hypervisor` + * `IamInstanceProfile` + * `ImageId` + * `InstanceId` + * `InstanceLifecycle` + * `InstanceType` + * `KernelId` + * `KeyName` + * `LaunchTime` + * `Platform` + * `PrivateDnsName` + * `PrivateIpAddress` + * `PublicDnsName` + * `PublicIpAddress` + * `RamdiskId` + * `RootDeviceName` + * `RootDeviceType` + * `SourceDestCheck` + * `SpotInstanceRequestId` + * `SriovNetSupport` + * `SubnetId` + * `VirtualizationType` + * `VpcId` + +Tags can be selected by prepending the tag name with `Tags.` + +Example `ec2_instance_attribute()` query + + ec2_instance_attribute(us-east-1, Tags.Name, { "tag:Team": [ "sysops" ] }) + ## Cost Amazon provides 1 million CloudWatch API requests each month at no additional charge. Past this, From d10d897d6546f45a36f338ec9aca276d061fc0f7 Mon Sep 17 00:00:00 2001 From: Martin Molnar Date: Mon, 12 Jun 2017 15:11:00 +0200 Subject: [PATCH 021/179] fix: component name of plugin page contains 'undefined' (#8590) --- public/app/core/directives/plugin_component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/core/directives/plugin_component.ts b/public/app/core/directives/plugin_component.ts index 4c098f60a4c..22c83f9b557 100644 --- a/public/app/core/directives/plugin_component.ts +++ b/public/app/core/directives/plugin_component.ts @@ -181,7 +181,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $ return System.import(appModel.module).then(function(appModule) { return { baseUrl: appModel.baseUrl, - name: 'app-page-' + appModel.appId + '-' + scope.ctrl.page.slug, + name: 'app-page-' + appModel.id + '-' + scope.ctrl.page.slug, bindings: {appModel: "="}, attrs: {"app-model": "ctrl.appModel"}, Component: appModule[scope.ctrl.page.component], From 192c447c2ce05367dbe1b66e68b5c451bdbb9abe Mon Sep 17 00:00:00 2001 From: Trent White Date: Mon, 12 Jun 2017 11:17:00 -0400 Subject: [PATCH 022/179] create new auth icon for grafana.com so it doesn't share the same file as the main logo (#8581) --- public/app/partials/login.html | 2 +- public/img/grafana_com_auth_icon.svg | 57 +++++++++++++ public/img/grafana_icon.svg | 115 +++++++++++++-------------- public/sass/pages/_login.scss | 1 + 4 files changed, 116 insertions(+), 59 deletions(-) create mode 100644 public/img/grafana_com_auth_icon.svg diff --git a/public/app/partials/login.html b/public/app/partials/login.html index 38517951cea..fe19d34f8d5 100644 --- a/public/app/partials/login.html +++ b/public/app/partials/login.html @@ -60,7 +60,7 @@ GitHub - + Grafana.com diff --git a/public/img/grafana_com_auth_icon.svg b/public/img/grafana_com_auth_icon.svg new file mode 100644 index 00000000000..72702223dc7 --- /dev/null +++ b/public/img/grafana_com_auth_icon.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + diff --git a/public/img/grafana_icon.svg b/public/img/grafana_icon.svg index 8616d369046..72702223dc7 100644 --- a/public/img/grafana_icon.svg +++ b/public/img/grafana_icon.svg @@ -1,58 +1,57 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/public/sass/pages/_login.scss b/public/sass/pages/_login.scss index 67218f4dc71..2b3426b45b5 100644 --- a/public/sass/pages/_login.scss +++ b/public/sass/pages/_login.scss @@ -119,6 +119,7 @@ img { width: 19px; + vertical-align: sub; } } } From 7d642546b3fcf8ac8876fa46ee42d394670b832b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 13 Jun 2017 13:21:22 -0400 Subject: [PATCH 023/179] fix: restore dashboard history version did not reload route correctly when slug did not change --- public/app/features/dashboard/history/history.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/app/features/dashboard/history/history.ts b/public/app/features/dashboard/history/history.ts index 10ab3f3fa28..f199d84ffb4 100644 --- a/public/app/features/dashboard/history/history.ts +++ b/public/app/features/dashboard/history/history.ts @@ -27,6 +27,7 @@ export class HistoryListCtrl { /** @ngInject */ constructor(private $scope, + private $route, private $rootScope, private $location, private $window, @@ -179,6 +180,7 @@ export class HistoryListCtrl { this.loading = true; return this.historySrv.restoreDashboard(this.dashboard, version).then(response => { this.$location.path('dashboard/db/' + response.slug); + this.$route.reload(); this.$rootScope.appEvent('alert-success', ['Dashboard restored', 'Restored from version ' + version]); }).catch(() => { this.mode = 'list'; From 1f92e589e816f50fc3b5e3a4a60e87521bdb96cf Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 13 Jun 2017 22:42:56 +0200 Subject: [PATCH 024/179] exporter: query template var keeps refresh value.. on export if the value is not set to never. Otherwise the template variable will not be populated with any values."" --- public/app/features/dashboard/export/exporter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/dashboard/export/exporter.ts b/public/app/features/dashboard/export/exporter.ts index 0a0b4cbdaab..d76e782905b 100644 --- a/public/app/features/dashboard/export/exporter.ts +++ b/public/app/features/dashboard/export/exporter.ts @@ -103,7 +103,7 @@ export class DashboardExporter { templateizeDatasourceUsage(variable); variable.options = []; variable.current = {}; - variable.refresh = 1; + variable.refresh = variable.refresh > 0 ? variable.refresh : 1; } } From cb720d8eafc1f55ebef8c9575bc687335126246c Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 13 Jun 2017 23:17:14 +0200 Subject: [PATCH 025/179] docs: add body options for snapshot api --- docs/sources/http_api/snapshot.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/sources/http_api/snapshot.md b/docs/sources/http_api/snapshot.md index f0b8304cd24..d466d01e051 100644 --- a/docs/sources/http_api/snapshot.md +++ b/docs/sources/http_api/snapshot.md @@ -52,6 +52,15 @@ parent = "http_api" "expires": 3600 } +JSON Body schema: + +- **dashboard** – Required. The complete dashboard model. +- **name** – Optional. snapshot name +- **expires** - Optional. When the snapshot should expire in seconds. 3600 is 1 hour, 86400 is 1 day. Default is never to expire. +- **external** - Optional. Save the snapshot on an external server rather than locally. Default is `false`. +- **key** - Optional. Define the unique key. Required if **external** is `true`. +- **deleteKey** - Optional. Unique key used to delete the snapshot. It is different from the **key** so that only the creator can delete the snapshot. Required if **external** is `true`. + **Example Response**: HTTP/1.1 200 From c771dd4bd27a22c319a69575dd2a1a0548aceedd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 13 Jun 2017 18:31:43 -0400 Subject: [PATCH 026/179] ux: metrics tab add query feature --- public/app/features/panel/metrics_tab.ts | 10 +++- .../features/panel/partials/metrics_tab.html | 55 ++++++++----------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/public/app/features/panel/metrics_tab.ts b/public/app/features/panel/metrics_tab.ts index 8f5e3dfdded..f2d99738040 100644 --- a/public/app/features/panel/metrics_tab.ts +++ b/public/app/features/panel/metrics_tab.ts @@ -62,11 +62,17 @@ export class MetricsTabCtrl { mixedDatasourceChanged() { var target: any = {isNew: true}; var ds = _.find(this.datasources, {name: this.mixedDsSegment.value}); + if (ds) { target.datasource = ds.name; - this.panelCtrl.addDataQuery(target); - this.mixedDsSegment.value = ''; + this.panelCtrl.addQuery(target); } + + // metric segments are really bad, requires hacks to update + const segment = this.uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true, fake: true}); + this.mixedDsSegment.value = segment.value; + this.mixedDsSegment.html = segment.html; + this.mixedDsSegment.text = segment.text; } addQuery() { diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index b9e704bbcca..a020a2edbd1 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -14,39 +14,32 @@ {{ctrl.panelCtrl.nextRefId}} - + - -
-
+ +
+
- + - - +
+
+
+ + +
+
+
-
-
-
- - -
-
-
- - - - - - -
-
- -
+ + + + +
From 6a95df403ac967f1b24133209e36ebe313ce2d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 14 Jun 2017 19:42:45 -0400 Subject: [PATCH 027/179] refacoring: more work on metric segment replacement --- .../form_dropdown/form_dropdown.html | 13 --- .../components/form_dropdown/form_dropdown.ts | 90 ++++++++++++++----- public/app/core/directives/dash_edit_link.js | 2 +- public/app/core/directives/metric_segment.js | 2 + public/app/features/panel/metrics_tab.ts | 51 +++++------ .../features/panel/partials/metrics_tab.html | 15 ++-- 6 files changed, 102 insertions(+), 71 deletions(-) delete mode 100644 public/app/core/components/form_dropdown/form_dropdown.html diff --git a/public/app/core/components/form_dropdown/form_dropdown.html b/public/app/core/components/form_dropdown/form_dropdown.html deleted file mode 100644 index 34737eab27e..00000000000 --- a/public/app/core/components/form_dropdown/form_dropdown.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/public/app/core/components/form_dropdown/form_dropdown.ts b/public/app/core/components/form_dropdown/form_dropdown.ts index fd363d3b75e..eb8be1e0945 100644 --- a/public/app/core/components/form_dropdown/form_dropdown.ts +++ b/public/app/core/components/form_dropdown/form_dropdown.ts @@ -15,15 +15,17 @@ function typeaheadMatcher(item) { export class FormDropdownCtrl { inputElement: any; linkElement: any; - value: any; - text: any; + model: any; display: any; + text: any; options: any; cssClass: any; allowCustom: any; linkMode: boolean; cancelBlur: any; onChange: any; + getOptions: any; + optionCache: any; constructor(private $scope, $element, private $sce, private templateSrv) { this.inputElement = $element.find('input').first(); @@ -31,11 +33,15 @@ export class FormDropdownCtrl { this.linkMode = true; this.cancelBlur = null; - if (this.options) { - var item = _.find(this.options, {value: this.value}); - this.updateDisplay(item ? item.text : this.value); + if (!this.getOptions) { + this.getOptions = () => { + return Promise.resolve(this.options); + }; } + // listen to model changes + $scope.$watch("ctrl.model", this.modelChanged.bind(this)); + this.inputElement.attr('data-provide', 'typeahead'); this.inputElement.typeahead({ source: this.typeaheadSource.bind(this), @@ -64,19 +70,40 @@ export class FormDropdownCtrl { this.inputElement.blur(this.inputBlur.bind(this)); } - typeaheadSource(query, callback) { - if (this.options) { - var typeaheadOptions = _.map(this.options, 'text'); + modelChanged(newVal) { + if (_.isObject(this.model)) { + this.updateDisplay(this.model.text); + } else { - // add current custom value + // if we have text use it + if (this.text) { + this.updateDisplay(this.text); + } else { + // otherwise we need to do initial lookup, usually happens first time + this.getOptions().then(options => { + var item = _.find(options, {value: this.model}); + this.updateDisplay(item ? item.text : this.model); + }); + } + } + } + + typeaheadSource(query, callback) { + this.getOptions({$query: query}).then(options => { + this.optionCache = options; + + // extract texts + let optionTexts = _.map(options, 'text'); + + // add custom values if (this.allowCustom) { - if (_.indexOf(typeaheadOptions, this.text) === -1) { - typeaheadOptions.unshift(this.text); + if (_.indexOf(optionTexts, this.text) === -1) { + options.unshift(this.text); } } - callback(typeaheadOptions); - } + callback(optionTexts); + }); } typeaheadUpdater(text) { @@ -114,21 +141,29 @@ export class FormDropdownCtrl { } this.$scope.$apply(() => { - var option = _.find(this.options, {text: text}); + var option = _.find(this.optionCache, {text: text}); if (option) { - this.value = option.value; - this.updateDisplay(option.text); + if (_.isObject(this.model)) { + this.model = option; + } else { + this.model = option.value; + } + this.text = option.text; } else if (this.allowCustom) { - this.value = text; - this.updateDisplay(text); + if (_.isObject(this.model)) { + this.model.text = this.model.value = text; + } else { + this.model = text; + } + this.text = text; } // needs to call this after digest so // property is synced with outerscope this.$scope.$$postDigest(() => { this.$scope.$apply(() => { - this.onChange(); + this.onChange({$option: option}); }); }); @@ -157,17 +192,30 @@ export class FormDropdownCtrl { } } +const template = ` + + +`; export function formDropdownDirective() { return { restrict: 'E', - templateUrl: 'public/app/core/components/form_dropdown/form_dropdown.html', + template: template, controller: FormDropdownCtrl, bindToController: true, controllerAs: 'ctrl', scope: { - value: "=", + model: "=", options: "=", getOptions: "&", onChange: "&", diff --git a/public/app/core/directives/dash_edit_link.js b/public/app/core/directives/dash_edit_link.js index 3e4bdd4c5c7..a4c1ad53b3c 100644 --- a/public/app/core/directives/dash_edit_link.js +++ b/public/app/core/directives/dash_edit_link.js @@ -35,7 +35,7 @@ function ($, angular, coreModule) { options.html = editViewMap[options.editview].html; } - if (lastEditView === options.editview) { + if (lastEditView && lastEditView === options.editview) { hideEditorPane(false); return; } diff --git a/public/app/core/directives/metric_segment.js b/public/app/core/directives/metric_segment.js index 0605d54a815..2e9442c15a0 100644 --- a/public/app/core/directives/metric_segment.js +++ b/public/app/core/directives/metric_segment.js @@ -143,6 +143,7 @@ function (_, $, coreModule) { $input.focus(); linkMode = false; + var typeahead = $input.data('typeahead'); if (typeahead) { $input.val(''); @@ -151,6 +152,7 @@ function (_, $, coreModule) { }); $input.blur($scope.inputBlur); + $compile(elem.contents())($scope); } }; diff --git a/public/app/features/panel/metrics_tab.ts b/public/app/features/panel/metrics_tab.ts index f2d99738040..c03c4d83bc2 100644 --- a/public/app/features/panel/metrics_tab.ts +++ b/public/app/features/panel/metrics_tab.ts @@ -5,8 +5,6 @@ import _ from 'lodash'; import {DashboardModel} from '../dashboard/model'; export class MetricsTabCtrl { - dsSegment: any; - mixedDsSegment: any; dsName: string; panel: any; panelCtrl: any; @@ -14,30 +12,26 @@ export class MetricsTabCtrl { current: any; nextRefId: string; dashboard: DashboardModel; + panelDsValue: any; + addQueryDropdown: any; /** @ngInject */ - constructor($scope, private uiSegmentSrv, datasourceSrv) { + constructor($scope, private uiSegmentSrv, private datasourceSrv) { this.panelCtrl = $scope.ctrl; $scope.ctrl = this; this.panel = this.panelCtrl.panel; this.dashboard = this.panelCtrl.dashboard; this.datasources = datasourceSrv.getMetricSources(); - - var dsValue = this.panelCtrl.panel.datasource || null; + this.panelDsValue = this.panelCtrl.panel.datasource || null; for (let ds of this.datasources) { - if (ds.value === dsValue) { + if (ds.value === this.panelDsValue) { this.current = ds; } } - if (!this.current) { - this.current = {name: dsValue + ' not found', value: null}; - } - - this.dsSegment = uiSegmentSrv.newSegment({value: this.current.name, selectMode: true}); - this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true, fake: true}); + this.addQueryDropdown = {text: 'Add Query', value: null, fake: true}; // update next ref id this.panelCtrl.nextRefId = this.dashboard.getNextQueryLetter(this.panel); @@ -46,33 +40,28 @@ export class MetricsTabCtrl { getOptions(includeBuiltin) { return Promise.resolve(this.datasources.filter(value => { return includeBuiltin || !value.meta.builtIn; - }).map(value => { - return this.uiSegmentSrv.newSegment(value.name); + }).map(ds => { + return {value: ds.value, text: ds.name, datasource: ds}; })); } - datasourceChanged() { - var ds = _.find(this.datasources, {name: this.dsSegment.value}); - if (ds) { - this.current = ds; - this.panelCtrl.setDatasource(ds); + datasourceChanged(option) { + if (!option) { + return; } + + this.current = option.datasource; + this.panelCtrl.setDatasource(option.datasource); } - mixedDatasourceChanged() { - var target: any = {isNew: true}; - var ds = _.find(this.datasources, {name: this.mixedDsSegment.value}); - - if (ds) { - target.datasource = ds.name; - this.panelCtrl.addQuery(target); + addMixedQuery(option) { + if (!option) { + return; } - // metric segments are really bad, requires hacks to update - const segment = this.uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true, fake: true}); - this.mixedDsSegment.value = segment.value; - this.mixedDsSegment.html = segment.html; - this.mixedDsSegment.text = segment.text; + var target: any = {isNew: true}; + this.panelCtrl.addQuery({isNew: true, datasource: option.datasource.name}); + this.addQueryDropdown = {text: 'Add Query', value: null, fake: true}; } addQuery() { diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index a020a2edbd1..32f43f1d639 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -19,7 +19,10 @@
@@ -30,10 +33,12 @@
- - + + +
From 5f3b5fdcb25c8d3c35b098d990520b1f1dc93d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 15 Jun 2017 12:21:12 -0400 Subject: [PATCH 028/179] updated --- .../core/components/form_dropdown/form_dropdown.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/public/app/core/components/form_dropdown/form_dropdown.ts b/public/app/core/components/form_dropdown/form_dropdown.ts index eb8be1e0945..cb7390ead9a 100644 --- a/public/app/core/components/form_dropdown/form_dropdown.ts +++ b/public/app/core/components/form_dropdown/form_dropdown.ts @@ -194,17 +194,19 @@ export class FormDropdownCtrl { const template = ` + data-provide="typeahead" + class="gf-form-input" + spellcheck="false" + style="display:none"> + + ng-bind-html="ctrl.display"> + `; export function formDropdownDirective() { @@ -221,6 +223,7 @@ export function formDropdownDirective() { onChange: "&", cssClass: "@", allowCustom: "@", + selectMode: "@", }, link: function() { } From 76c4bfe2682a926ee479783abfe3ba4571e973ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 15 Jun 2017 14:03:26 -0400 Subject: [PATCH 029/179] ux: new metric segment is starting to work --- .../components/form_dropdown/form_dropdown.ts | 21 +++++++++---------- .../features/panel/partials/metrics_tab.html | 3 +-- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/public/app/core/components/form_dropdown/form_dropdown.ts b/public/app/core/components/form_dropdown/form_dropdown.ts index cb7390ead9a..50017225720 100644 --- a/public/app/core/components/form_dropdown/form_dropdown.ts +++ b/public/app/core/components/form_dropdown/form_dropdown.ts @@ -20,7 +20,9 @@ export class FormDropdownCtrl { text: any; options: any; cssClass: any; + cssClasses: any; allowCustom: any; + labelMode: boolean; linkMode: boolean; cancelBlur: any; onChange: any; @@ -33,15 +35,15 @@ export class FormDropdownCtrl { this.linkMode = true; this.cancelBlur = null; - if (!this.getOptions) { - this.getOptions = () => { - return Promise.resolve(this.options); - }; - } - // listen to model changes $scope.$watch("ctrl.model", this.modelChanged.bind(this)); + if (this.labelMode) { + this.cssClasses = 'gf-form-label ' + this.cssClass; + } else { + this.cssClasses = 'gf-form-input gf-form-input--dropdown ' + this.cssClass; + } + this.inputElement.attr('data-provide', 'typeahead'); this.inputElement.typeahead({ source: this.typeaheadSource.bind(this), @@ -199,9 +201,7 @@ const template = ` spellcheck="false" style="display:none"> - -Panel Data Source + on-change="ctrl.datasourceChanged($option)"> From 840099bec0b58f464f3605c30c2f072a96f4d994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 15 Jun 2017 15:56:24 -0400 Subject: [PATCH 030/179] refactor: metric segment remake --- .../components/form_dropdown/form_dropdown.ts | 38 ++++++++++---- .../features/panel/partials/metrics_tab.html | 1 + .../datasource/elasticsearch/bucket_agg.js | 21 +++++--- .../elasticsearch/partials/bucket_agg.html | 51 ++++++++++++++++--- .../elasticsearch/partials/metric_agg.html | 6 +-- .../datasource/elasticsearch/query_ctrl.ts | 4 +- 6 files changed, 91 insertions(+), 30 deletions(-) diff --git a/public/app/core/components/form_dropdown/form_dropdown.ts b/public/app/core/components/form_dropdown/form_dropdown.ts index 50017225720..72a101388b7 100644 --- a/public/app/core/components/form_dropdown/form_dropdown.ts +++ b/public/app/core/components/form_dropdown/form_dropdown.ts @@ -28,8 +28,9 @@ export class FormDropdownCtrl { onChange: any; getOptions: any; optionCache: any; + lookupText: boolean; - constructor(private $scope, $element, private $sce, private templateSrv) { + constructor(private $scope, $element, private $sce, private templateSrv, private $q) { this.inputElement = $element.find('input').first(); this.linkElement = $element.find('a').first(); this.linkMode = true; @@ -69,29 +70,45 @@ export class FormDropdownCtrl { } }); + this.inputElement.keydown(evt => { + if (evt.keyCode === 13) { + this.inputElement.blur(); + } + }); + this.inputElement.blur(this.inputBlur.bind(this)); } - modelChanged(newVal) { + getOptionsInternal(query) { + var result = this.getOptions({$query: query}); + if (this.isPromiseLike(result)) { + return result; + } + return this.$q.when(result); + } + + isPromiseLike(obj) { + return obj && (typeof obj.then === 'function'); + } + + modelChanged() { if (_.isObject(this.model)) { this.updateDisplay(this.model.text); } else { - // if we have text use it - if (this.text) { - this.updateDisplay(this.text); - } else { - // otherwise we need to do initial lookup, usually happens first time - this.getOptions().then(options => { + if (this.lookupText) { + this.getOptionsInternal("").then(options => { var item = _.find(options, {value: this.model}); this.updateDisplay(item ? item.text : this.model); }); + } else { + this.updateDisplay(this.model); } } } typeaheadSource(query, callback) { - this.getOptions({$query: query}).then(options => { + this.getOptionsInternal(query).then(options => { this.optionCache = options; // extract texts @@ -223,9 +240,8 @@ export function formDropdownDirective() { cssClass: "@", allowCustom: "@", labelMode: "@", + lookupText: "@", }, - link: function() { - } }; } diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index d8d8816d63b..bc0bcf7c6b2 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -35,6 +35,7 @@
diff --git a/public/app/plugins/datasource/elasticsearch/bucket_agg.js b/public/app/plugins/datasource/elasticsearch/bucket_agg.js index b2cfc819579..5adaed173af 100644 --- a/public/app/plugins/datasource/elasticsearch/bucket_agg.js +++ b/public/app/plugins/datasource/elasticsearch/bucket_agg.js @@ -26,13 +26,21 @@ function (angular, _, queryDef) { var bucketAggs = $scope.target.bucketAggs; $scope.orderByOptions = []; - $scope.bucketAggTypes = queryDef.bucketAggTypes; - $scope.orderOptions = queryDef.orderOptions; - $scope.sizeOptions = queryDef.sizeOptions; + + $scope.getBucketAggTypes = function() { + return queryDef.bucketAggTypes; + }; + + $scope.getOrderOptions = function() { + return queryDef.orderOptions; + }; + + $scope.getSizeOptions = function() { + return queryDef.sizeOptions; + }; $rootScope.onAppEvent('elastic-query-updated', function() { $scope.validateModel(); - $scope.updateOrderByOptions(); }, $scope); $scope.init = function() { @@ -166,11 +174,10 @@ function (angular, _, queryDef) { $scope.toggleOptions = function() { $scope.showOptions = !$scope.showOptions; - $scope.updateOrderByOptions(); }; - $scope.updateOrderByOptions = function() { - $scope.orderByOptions = queryDef.getOrderByOptions($scope.target); + $scope.getOrderByOptions = function() { + return queryDef.getOrderByOptions($scope.target); }; $scope.getFieldsInternal = function() { diff --git a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html index f6c86db0d1e..a180f97c994 100644 --- a/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html +++ b/public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html @@ -5,9 +5,22 @@ Then by - - - + + + +
@@ -34,7 +47,13 @@
- + +
@@ -67,11 +86,23 @@
- + +
- + +
@@ -79,7 +110,13 @@
- + +
- - - + + +
diff --git a/public/app/plugins/datasource/elasticsearch/query_ctrl.ts b/public/app/plugins/datasource/elasticsearch/query_ctrl.ts index 009befb37a4..ef6f1c5cdc7 100644 --- a/public/app/plugins/datasource/elasticsearch/query_ctrl.ts +++ b/public/app/plugins/datasource/elasticsearch/query_ctrl.ts @@ -31,11 +31,11 @@ export class ElasticQueryCtrl extends QueryCtrl { queryUpdated() { var newJson = angular.toJson(this.datasource.queryBuilder.build(this.target), true); - if (newJson !== this.rawQueryOld) { - this.rawQueryOld = newJson; + if (this.rawQueryOld && newJson !== this.rawQueryOld) { this.refresh(); } + this.rawQueryOld = newJson; this.$rootScope.appEvent('elastic-query-updated'); } From a49e82e4470490f62445cdadd0397523bd9315d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 16 Jun 2017 09:47:21 -0400 Subject: [PATCH 031/179] ux: revert dashboard search nav change, this is a tempoary change until we redesign the sidenav --- .../features/dashboard/dashnav/dashnav.html | 138 +++++++++++------- .../app/features/dashboard/dashnav/dashnav.ts | 19 ++- 2 files changed, 102 insertions(+), 55 deletions(-) diff --git a/public/app/features/dashboard/dashnav/dashnav.html b/public/app/features/dashboard/dashnav/dashnav.html index f1615a0bd1c..bab27289aca 100644 --- a/public/app/features/dashboard/dashnav/dashnav.html +++ b/public/app/features/dashboard/dashnav/dashnav.html @@ -1,63 +1,95 @@ - - - - -
+
+ + diff --git a/public/app/features/dashboard/dashnav/dashnav.ts b/public/app/features/dashboard/dashnav/dashnav.ts index e77c2bb3e09..98cefa46c7f 100644 --- a/public/app/features/dashboard/dashnav/dashnav.ts +++ b/public/app/features/dashboard/dashnav/dashnav.ts @@ -22,8 +22,8 @@ export class DashNavCtrl { private backendSrv, private $timeout, private datasourceSrv, - private navModelSrv) { - + private navModelSrv, + private contextSrv) { this.navModel = navModelSrv.getDashboardNav(this.dashboard, this); appEvents.on('save-dashboard', this.saveDashboard.bind(this), $scope); @@ -38,6 +38,10 @@ export class DashNavCtrl { } } + toggleSideMenu() { + this.contextSrv.toggleSideMenu(); + } + openEditView(editview) { var search = _.extend(this.$location.search(), {editview: editview}); this.$location.search(search); @@ -135,6 +139,17 @@ export class DashNavCtrl { var uri = "data:application/json;charset=utf-8," + encodeURIComponent(html); var newWindow = window.open(uri); } + + showSearch() { + this.$rootScope.appEvent('show-dash-search'); + } + + navItemClicked(navItem, evt) { + if (navItem.clickHandler) { + navItem.clickHandler(); + evt.preventDefault(); + } + } } export function dashNavDirective() { From 5d63ad21c1b8e2ffcac7cc28a0bad545925238aa Mon Sep 17 00:00:00 2001 From: Brandon Arp Date: Fri, 16 Jun 2017 07:45:52 -0700 Subject: [PATCH 032/179] allow heatmap parsing of scaled datapoints (#8632) --- .../app/plugins/panel/heatmap/heatmap_data_converter.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts index f7e32f3df7c..07057c53985 100644 --- a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts +++ b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts @@ -207,15 +207,20 @@ function pushToXBuckets(buckets, point, bucketNum, seriesName) { } function pushToYBuckets(buckets, bucketNum, value, point, bounds) { + var count = 1; + // Use the 3rd argument as scale/count + if (point.length > 2) { + count = parseInt(point[2]); + } if (buckets[bucketNum]) { buckets[bucketNum].values.push(value); - buckets[bucketNum].count += 1; + buckets[bucketNum].count += count; } else { buckets[bucketNum] = { y: bucketNum, bounds: bounds, values: [value], - count: 1, + count: count, }; } } From 056c57d55197bac83f3af6c6a5fc40ae04e87262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 16 Jun 2017 10:47:17 -0400 Subject: [PATCH 033/179] ux: temporary remove search --- public/app/core/components/navbar/navbar.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/app/core/components/navbar/navbar.html b/public/app/core/components/navbar/navbar.html index ea8eb21d6d6..085e2eef920 100644 --- a/public/app/core/components/navbar/navbar.html +++ b/public/app/core/components/navbar/navbar.html @@ -8,9 +8,9 @@ - - - + + +
From 724368d0cdf0f95922b14601d6ce65b5d90da687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 16 Jun 2017 11:43:37 -0400 Subject: [PATCH 034/179] fix: data source dropdown select --- public/app/core/components/form_dropdown/form_dropdown.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/app/core/components/form_dropdown/form_dropdown.ts b/public/app/core/components/form_dropdown/form_dropdown.ts index 72a101388b7..d8212e2f55c 100644 --- a/public/app/core/components/form_dropdown/form_dropdown.ts +++ b/public/app/core/components/form_dropdown/form_dropdown.ts @@ -72,7 +72,9 @@ export class FormDropdownCtrl { this.inputElement.keydown(evt => { if (evt.keyCode === 13) { - this.inputElement.blur(); + setTimeout(() => { + this.inputElement.blur(); + }, 100); } }); From 49fdbb3843753128eba5877c3e016e6af286455d Mon Sep 17 00:00:00 2001 From: Salman Jalali Date: Fri, 16 Jun 2017 16:10:45 -0700 Subject: [PATCH 035/179] Update kbn.js --- public/app/core/utils/kbn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/core/utils/kbn.js b/public/app/core/utils/kbn.js index d619d9c4977..6f8340d5940 100644 --- a/public/app/core/utils/kbn.js +++ b/public/app/core/utils/kbn.js @@ -841,7 +841,7 @@ function($, _) { { text: 'temperature', submenu: [ - {text: 'Celcius (°C)', value: 'celsius' }, + {text: 'Celsius (°C)', value: 'celsius' }, {text: 'Farenheit (°F)', value: 'farenheit' }, {text: 'Kelvin (K)', value: 'kelvin' }, ] From ad080af38f860e168e40e9357d66a2e1b619ff11 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Sat, 17 Jun 2017 20:59:19 +0200 Subject: [PATCH 036/179] docs: add tutorial for using API --- docs/sources/tutorials/api_org_token_howto.md | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 docs/sources/tutorials/api_org_token_howto.md diff --git a/docs/sources/tutorials/api_org_token_howto.md b/docs/sources/tutorials/api_org_token_howto.md new file mode 100644 index 00000000000..e985b499dbe --- /dev/null +++ b/docs/sources/tutorials/api_org_token_howto.md @@ -0,0 +1,74 @@ ++++ +title = "API Tutorial: How To Create API Tokens And Dashboards For A Specific Organization" +type = "docs" +keywords = ["grafana", "tutorials", "API", "Token", "Org", "Organization"] +[menu.docs] +parent = "tutorials" +weight = 10 ++++ + +# API Tutorial: How To Create API Tokens And Dashboards For A Specific Organization + +A common scenario is to want to via the Grafana API setup new Grafana organizations or to add dynamically generated dashboards to an existing organization. + +## Authentication + +There are two ways to authenticate against the API: basic authentication and API Tokens. + +Some parts of the API are only available through basic authentication and these parts of the API usually require that the user is a Grafana Admin. But all organization actions are accessed via an API Token. An API Token is tied to an organization and can be used to create dashboards etc but only for that organization. + +## How To Create A New Organization and an API Token + +The task is to create a new organization and then add a Token that can be used by other users. In the examples below which use basic auth, the user is `admin` and the password is `admin`. + +1. [Create the org](http://docs.grafana.org/http_api/org/#create-organisation). Here is an example using curl: + ``` + curl -X POST -H "Content-Type: application/json" -d '{"name":"apiorg"}' http://admin:admin@localhost:3000/api/orgs + ``` + + This should return a response: `{"message":"Organization created","orgId":6}`. Use the orgId for the next steps. + +2. Optional step. If the org was created previously and/or step 3 fails then first [add your Admin user to the org](http://docs.grafana.org/http_api/org/#add-user-in-organisation): + ``` + curl -X POST -H "Content-Type: application/json" -d '{"loginOrEmail":"admin", "role": "Admin"}' http://admin:admin@localhost:3000/api/orgs//users + ``` + +3. [Switch the org context for the Admin user to the new org](http://docs.grafana.org/http_api/user/#switch-user-context): + ``` + curl -X POST http://admin:admin@localhost:3000/api/user/using/ + ``` + +4. [Create the API token](http://docs.grafana.org/http_api/auth/#create-api-key): + ``` + curl -X POST -H "Content-Type: application/json" -d '{"name":"apikeycurl", "role": "Admin"}' http://admin:admin@localhost:3000/api/auth/keys + ``` + + This should return a response: `{"name":"apikeycurl","key":"eyJrIjoiR0ZXZmt1UFc0OEpIOGN5RWdUalBJTllUTk83VlhtVGwiLCJuIjoiYXBpa2V5Y3VybCIsImlkIjo2fQ=="}`. + + Save the key returned here in your password manager as it is not possible to fetch again it in the future. + +## How To Add A Dashboard + +Using the Token that was created in the previous step, you can create a dashboard or carry out other actions without having to switch organizations. + +1. [Add a dashboard](http://docs.grafana.org/http_api/dashboard/#create-update-dashboard) using the key (or bearer token as it is also called): + + ``` + curl -X POST --insecure -H "Authorization: Bearer eyJrIjoiR0ZXZmt1UFc0OEpIOGN5RWdUalBJTllUTk83VlhtVGwiLCJuIjoiYXBpa2V5Y3VybCIsImlkIjo2fQ==" -H "Content-Type: application/json" -d '{ + "dashboard": { + "id": null, + "title": "Production Overview", + "tags": [ "templated" ], + "timezone": "browser", + "rows": [ + { + } + ], + "schemaVersion": 6, + "version": 0 + }, + "overwrite": false + }' http://localhost:3000/api/dashboards/db + ``` + + This import will not work if you exported the dashboard via the Share -> Export menu in the Grafana UI (it strips out data source names etc.). View the JSON and save it to a file instead or fetch the dashboard JSON via the API. From 0eb297822c44edea7d4e981b654b658fccd02d9a Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Sat, 17 Jun 2017 23:10:12 +0200 Subject: [PATCH 037/179] httpserver: fixes #8641 Changes to the http_server class meant that the TLS settings were not getting applied anymore. This fixes so that the minimum TLS version is 1.2 again. --- pkg/api/http_server.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index 1e143ef876f..0468b5cbe8a 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -61,7 +61,7 @@ func (hs *HttpServer) Start(ctx context.Context) error { return nil } case setting.HTTPS: - err = hs.httpSrv.ListenAndServeTLS(setting.CertFile, setting.KeyFile) + err = hs.listenAndServeTLS(setting.CertFile, setting.KeyFile) if err == http.ErrServerClosed { hs.log.Debug("server was shutdown gracefully") return nil @@ -92,7 +92,7 @@ func (hs *HttpServer) Shutdown(ctx context.Context) error { return err } -func (hs *HttpServer) listenAndServeTLS(listenAddr, certfile, keyfile string) error { +func (hs *HttpServer) listenAndServeTLS(certfile, keyfile string) error { if certfile == "" { return fmt.Errorf("cert_file cannot be empty when using HTTPS") } @@ -127,14 +127,11 @@ func (hs *HttpServer) listenAndServeTLS(listenAddr, certfile, keyfile string) er tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, }, } - srv := &http.Server{ - Addr: listenAddr, - Handler: hs.macaron, - TLSConfig: tlsCfg, - TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0), - } - return srv.ListenAndServeTLS(setting.CertFile, setting.KeyFile) + hs.httpSrv.TLSConfig = tlsCfg + hs.httpSrv.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0) + + return hs.httpSrv.ListenAndServeTLS(setting.CertFile, setting.KeyFile) } func (hs *HttpServer) newMacaron() *macaron.Macaron { From 1f4140057b32c2b86ee855231245e5a73719dad7 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Sun, 18 Jun 2017 20:58:13 +0300 Subject: [PATCH 038/179] heatmap-tooltip: normalize histogram Y axis --- public/app/plugins/panel/heatmap/heatmap_tooltip.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts index 6d577ab9d37..3af78156536 100644 --- a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts +++ b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts @@ -172,9 +172,11 @@ export class HeatmapTooltip { } barWidth = Math.max(barWidth, 1); + // Normalize histogram Y axis + let histogramDomain = _.reduce(_.map(histogramData, d => d[1]), (sum, val) => sum + val, 0); let histYScale = d3.scaleLinear() - .domain([0, _.max(_.map(histogramData, d => d[1]))]) - .range([0, HISTOGRAM_HEIGHT]); + .domain([0, histogramDomain]) + .range([0, HISTOGRAM_HEIGHT]); let histogram = this.tooltip.select(".heatmap-histogram") .append("svg") From 9a7e460865b44b8884a2bce97c48f33fade5c4a7 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Sun, 18 Jun 2017 21:41:00 +0300 Subject: [PATCH 039/179] fix heatmap count values bug introduced by #8632 --- .../app/plugins/panel/heatmap/heatmap_data_converter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts index 07057c53985..d9e6bbb7d43 100644 --- a/public/app/plugins/panel/heatmap/heatmap_data_converter.ts +++ b/public/app/plugins/panel/heatmap/heatmap_data_converter.ts @@ -192,16 +192,16 @@ function pushToXBuckets(buckets, point, bucketNum, seriesName) { if (value === null || value === undefined || isNaN(value)) { return; } // Add series name to point for future identification - point.push(seriesName); + let point_ext = _.concat(point, seriesName); if (buckets[bucketNum] && buckets[bucketNum].values) { buckets[bucketNum].values.push(value); - buckets[bucketNum].points.push(point); + buckets[bucketNum].points.push(point_ext); } else { buckets[bucketNum] = { x: bucketNum, values: [value], - points: [point] + points: [point_ext] }; } } @@ -209,7 +209,7 @@ function pushToXBuckets(buckets, point, bucketNum, seriesName) { function pushToYBuckets(buckets, bucketNum, value, point, bounds) { var count = 1; // Use the 3rd argument as scale/count - if (point.length > 2) { + if (point.length > 3) { count = parseInt(point[2]); } if (buckets[bucketNum]) { From 41d300f69d09d44994cb21207ef53e0c188e109a Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Mon, 19 Jun 2017 14:58:22 +0200 Subject: [PATCH 040/179] Fix timeInterval for mysql datasource (#8651) * Fix timeInterval for mysql datasource This changes the > to >= and the < to <=, so the intervals are inclusive. This should fix the #8635 * Fix validation --- pkg/tsdb/mysql/macros.go | 2 +- pkg/tsdb/mysql/macros_test.go | 2 +- public/app/plugins/datasource/mysql/partials/query.editor.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/tsdb/mysql/macros.go b/pkg/tsdb/mysql/macros.go index def2fde9fcc..34bbfdc6865 100644 --- a/pkg/tsdb/mysql/macros.go +++ b/pkg/tsdb/mysql/macros.go @@ -73,7 +73,7 @@ func (m *MySqlMacroEngine) EvaluateMacro(name string, args []string) (string, er if len(args) == 0 { return "", fmt.Errorf("missing time column argument for macro %v", name) } - return fmt.Sprintf("%s > FROM_UNIXTIME(%d) AND %s < FROM_UNIXTIME(%d)", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil + return fmt.Sprintf("%s >= FROM_UNIXTIME(%d) AND %s <= FROM_UNIXTIME(%d)", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil default: return "", fmt.Errorf("Unknown macro %v", name) } diff --git a/pkg/tsdb/mysql/macros_test.go b/pkg/tsdb/mysql/macros_test.go index 5b6b885ff0e..9684daac4e8 100644 --- a/pkg/tsdb/mysql/macros_test.go +++ b/pkg/tsdb/mysql/macros_test.go @@ -36,7 +36,7 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate("WHERE $__timeFilter(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, "WHERE time_column > FROM_UNIXTIME(18446744066914186738) AND time_column < FROM_UNIXTIME(18446744066914187038)") + So(sql, ShouldEqual, "WHERE time_column >= FROM_UNIXTIME(18446744066914186738) AND time_column <= FROM_UNIXTIME(18446744066914187038)") }) }) diff --git a/public/app/plugins/datasource/mysql/partials/query.editor.html b/public/app/plugins/datasource/mysql/partials/query.editor.html index de54f0ce942..c7b90ad7815 100644 --- a/public/app/plugins/datasource/mysql/partials/query.editor.html +++ b/public/app/plugins/datasource/mysql/partials/query.editor.html @@ -46,7 +46,7 @@ Table: Macros: - $__time(column) -> UNIX_TIMESTAMP(column) as time_sec -- $__timeFilter(column) -> UNIX_TIMESTAMP(time_date_time) > from AND UNIX_TIMESTAMP(time_date_time) < 1492750877 +- $__timeFilter(column) -> UNIX_TIMESTAMP(time_date_time) ≥ from AND UNIX_TIMESTAMP(time_date_time) ≤ 1492750877
From 8440d2d0a2713fe2afaf5b9c685c30ffa22efb64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 19 Jun 2017 16:02:16 -0400 Subject: [PATCH 041/179] fix: fixed search issues with in active mode and keyboard nav --- public/app/core/components/search/search.ts | 2 +- public/sass/components/_search.scss | 7 ++----- public/sass/components/_view_states.scss | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/public/app/core/components/search/search.ts b/public/app/core/components/search/search.ts index f6810f2bc76..4644e7a5893 100644 --- a/public/app/core/components/search/search.ts +++ b/public/app/core/components/search/search.ts @@ -77,7 +77,7 @@ export class SearchCtrl { this.moveSelection(-1); } if (evt.keyCode === 13) { - if (this.$scope.tagMode) { + if (this.tagsMode) { var tag = this.results[this.selectedIndex]; if (tag) { this.filterByTag(tag.term, null); diff --git a/public/sass/components/_search.scss b/public/sass/components/_search.scss index 3c9f44afb2f..e35bf4e6b6e 100644 --- a/public/sass/components/_search.scss +++ b/public/sass/components/_search.scss @@ -122,14 +122,11 @@ content: "\f015"; } - &:hover { + &:hover, + &.selected { background-color: $tight-form-func-bg; @include left-brand-border-gradient(); } - - &.selected { - background-color: $grafanaListBackground; - } } .search-result-tags { diff --git a/public/sass/components/_view_states.scss b/public/sass/components/_view_states.scss index 900c9d1489b..a1ed89f9888 100644 --- a/public/sass/components/_view_states.scss +++ b/public/sass/components/_view_states.scss @@ -51,7 +51,7 @@ .navbar-page-btn { border-color: transparent; background: transparent; - transform: translate3d(-95px, 0, 0); + transform: translate3d(-50px, 0, 0); transition: all 1.5s ease-in-out 1s; .icon-gf { opacity: 0; From eaba985f25e7d829f787285a2386fa266160b6fd Mon Sep 17 00:00:00 2001 From: Denis Doria Date: Mon, 19 Jun 2017 22:23:12 +0200 Subject: [PATCH 042/179] Fix issue with kilovolt-ampere reactive (kvar) #8596 (#8650) This changes the css to handle overflow of the string on the input fields. If an overflow happends an ellipsis is used. --- public/sass/components/_gf-form.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 53d52541611..92b66ec54ca 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -113,6 +113,9 @@ $gf-form-margin: 0.25rem; @include border-radius($input-border-radius-sm); @include box-shadow($input-box-shadow); transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; // Unstyle the caret on `
- +
- + +
+
+
- +
- +
diff --git a/public/app/plugins/panel/table/renderer.ts b/public/app/plugins/panel/table/renderer.ts index ae56e8dff12..dc031df8d1e 100644 --- a/public/app/plugins/panel/table/renderer.ts +++ b/public/app/plugins/panel/table/renderer.ts @@ -130,6 +130,7 @@ export class TableRenderer { renderCell(columnIndex, value, addWidthHack = false) { value = this.formatColumnValue(columnIndex, value); var style = ''; + var cellClass = ''; if (this.colorState.cell) { style = ' style="background-color:' + this.colorState.cell + ';color: white"'; this.colorState.cell = null; @@ -153,7 +154,12 @@ export class TableRenderer { this.table.columns[columnIndex].hidden = false; } - return '' + value + widthHack + ''; + var columnStyle = this.table.columns[columnIndex].style; + if (columnStyle && columnStyle.preserveFormat) { + cellClass = ' class="table-panel-cell-pre" '; + } + + return '' + value + widthHack + ''; } render(page) { diff --git a/public/sass/components/_panel_table.scss b/public/sass/components/_panel_table.scss index ec0c73e2ec7..17dbc910b2d 100644 --- a/public/sass/components/_panel_table.scss +++ b/public/sass/components/_panel_table.scss @@ -72,6 +72,10 @@ &:last-child { border-right: none; } + + &.table-panel-cell-pre { + white-space: pre; + } } } From 53ea9cfbcf281255585e7654666e0f682480095b Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 27 Jun 2017 16:59:40 +0200 Subject: [PATCH 057/179] docs: update ha_setup with alerting deduping --- docs/sources/tutorials/ha_setup.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/sources/tutorials/ha_setup.md b/docs/sources/tutorials/ha_setup.md index 998b382a43f..9dd8aac4618 100644 --- a/docs/sources/tutorials/ha_setup.md +++ b/docs/sources/tutorials/ha_setup.md @@ -35,6 +35,4 @@ But we suggest that you store the session in redis/memcache since it makes it ea ## Alerting -Currently alerting does not support high availability. But this is something that we will be working on in the future. - - +Currently alerting supports a limited form of high availability. Since v4.2.0 of Grafana, alert notifications are deduped when running multiple servers. This means all alerts are executed on every server but no duplicate alert notifications are sent due to the deduping logic. Proper load balancing of alerts will be introduced in the future. From 8e5672aee6a710433a68bfeb2f7913a5a1d236e8 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 26 Jun 2017 18:13:32 +0300 Subject: [PATCH 058/179] heatmap: fix Y axis value rounding with linear scale --- public/app/plugins/panel/heatmap/rendering.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index 085d9bd2673..153375dfa41 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -131,7 +131,9 @@ export default function link(scope, elem, attrs, ctrl) { tick_interval = tickStep(y_min, y_max, ticks); ticks = Math.ceil((y_max - y_min) / tick_interval); + let decimalsAuto = getPrecision(tick_interval); let decimals = panel.yAxis.decimals === null ? getPrecision(tick_interval) : panel.yAxis.decimals; + let scaledDecimals = getScaledDecimals(decimals, tick_interval); // Set default Y min and max if no data if (_.isEmpty(data.buckets)) { @@ -153,7 +155,7 @@ export default function link(scope, elem, attrs, ctrl) { let yAxis = d3.axisLeft(yScale) .ticks(ticks) - .tickFormat(tickValueFormatter(decimals)) + .tickFormat(tickValueFormatter(decimals, scaledDecimals)) .tickSizeInner(0 - width) .tickSizeOuter(0) .tickPadding(Y_AXIS_TICK_PADDING); @@ -293,10 +295,14 @@ export default function link(scope, elem, attrs, ctrl) { return tickValues; } - function tickValueFormatter(decimals) { + function getScaledDecimals(decimals, tick_size) { + return decimals - Math.floor(Math.log(tick_size) / Math.LN10); + } + + function tickValueFormatter(decimals, scaledDecimals = null) { let format = panel.yAxis.format; return function(value) { - return kbn.valueFormats[format](value, decimals); + return kbn.valueFormats[format](value, decimals, scaledDecimals); }; } From b63d2b3279256f009bbb7d263a7e15ea4829f295 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 27 Jun 2017 12:26:41 +0300 Subject: [PATCH 059/179] heatmap: fix Y axis decimals with log scale --- public/app/plugins/panel/heatmap/rendering.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index 153375dfa41..54dbb812a95 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -132,7 +132,7 @@ export default function link(scope, elem, attrs, ctrl) { ticks = Math.ceil((y_max - y_min) / tick_interval); let decimalsAuto = getPrecision(tick_interval); - let decimals = panel.yAxis.decimals === null ? getPrecision(tick_interval) : panel.yAxis.decimals; + let decimals = panel.yAxis.decimals === null ? decimalsAuto : panel.yAxis.decimals; let scaledDecimals = getScaledDecimals(decimals, tick_interval); // Set default Y min and max if no data @@ -215,7 +215,10 @@ export default function link(scope, elem, attrs, ctrl) { let domain = yScale.domain(); let tick_values = logScaleTickValues(domain, log_base); - let decimals = panel.yAxis.decimals; + + let decimalsAuto = getPrecision(y_min); + let decimals = panel.yAxis.decimals || decimalsAuto; + let scaledDecimals = decimals - 2; data.yAxis = { min: y_min, @@ -225,7 +228,7 @@ export default function link(scope, elem, attrs, ctrl) { let yAxis = d3.axisLeft(yScale) .tickValues(tick_values) - .tickFormat(tickValueFormatter(decimals)) + .tickFormat(tickValueFormatter(decimals, scaledDecimals)) .tickSizeInner(0 - width) .tickSizeOuter(0) .tickPadding(Y_AXIS_TICK_PADDING); From 7c840cdf380232ea7196ca322aa38ef8ec8861bb Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 27 Jun 2017 13:13:50 +0300 Subject: [PATCH 060/179] heatmap: fix tooltip decimals --- public/app/core/utils/ticks.ts | 4 ++++ public/app/plugins/panel/heatmap/heatmap_ctrl.ts | 2 ++ public/app/plugins/panel/heatmap/heatmap_tooltip.ts | 12 ++++++++---- public/app/plugins/panel/heatmap/rendering.ts | 11 ++++++----- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/public/app/core/utils/ticks.ts b/public/app/core/utils/ticks.ts index 7e7abbcd8f0..fa68b04d614 100644 --- a/public/app/core/utils/ticks.ts +++ b/public/app/core/utils/ticks.ts @@ -25,3 +25,7 @@ export function tickStep(start: number, stop: number, count: number): number { return stop < start ? -step1 : step1; } + +export function getScaledDecimals(decimals, tick_size) { + return decimals - Math.floor(Math.log(tick_size) / Math.LN10); +} diff --git a/public/app/plugins/panel/heatmap/heatmap_ctrl.ts b/public/app/plugins/panel/heatmap/heatmap_ctrl.ts index 9d770f21e95..37aa9410ea8 100644 --- a/public/app/plugins/panel/heatmap/heatmap_ctrl.ts +++ b/public/app/plugins/panel/heatmap/heatmap_ctrl.ts @@ -95,6 +95,8 @@ export class HeatmapCtrl extends MetricsPanelCtrl { series: any; timeSrv: any; dataWarning: any; + decimals: number; + scaledDecimals: number; /** @ngInject */ constructor($scope, $injector, private $rootScope, timeSrv) { diff --git a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts index 3af78156536..097d9f5897d 100644 --- a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts +++ b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts @@ -15,6 +15,7 @@ export class HeatmapTooltip { tooltip: any; scope: any; dashboard: any; + panelCtrl: any; panel: any; heatmapPanel: any; mouseOverBucket: boolean; @@ -23,6 +24,7 @@ export class HeatmapTooltip { constructor(elem, scope) { this.scope = scope; this.dashboard = scope.ctrl.dashboard; + this.panelCtrl = scope.ctrl; this.panel = scope.ctrl.panel; this.heatmapPanel = elem; this.mouseOverBucket = false; @@ -85,8 +87,10 @@ export class HeatmapTooltip { let tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss'; let time = this.dashboard.formatDate(xData.x, tooltipTimeFormat); - let decimals = this.panel.tooltipDecimals || 5; - let valueFormatter = this.valueFormatter(decimals); + + let decimals = this.panel.tooltipDecimals || this.panelCtrl.decimals; + let scaledDecimals = decimals - 2; + let valueFormatter = this.valueFormatter(decimals, scaledDecimals); let tooltipHtml = `
${time}
`; @@ -220,13 +224,13 @@ export class HeatmapTooltip { .style("top", top + "px"); } - valueFormatter(decimals) { + valueFormatter(decimals, scaledDecimals = null) { let format = this.panel.yAxis.format; return function(value) { if (_.isInteger(value)) { decimals = 0; } - return kbn.valueFormats[format](value, decimals); + return kbn.valueFormats[format](value, decimals, scaledDecimals); }; } } diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index 54dbb812a95..c713d254021 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -5,7 +5,7 @@ import $ from 'jquery'; import moment from 'moment'; import kbn from 'app/core/utils/kbn'; import {appEvents, contextSrv} from 'app/core/core'; -import {tickStep} from 'app/core/utils/ticks'; +import {tickStep, getScaledDecimals} from 'app/core/utils/ticks'; import d3 from 'd3'; import {HeatmapTooltip} from './heatmap_tooltip'; import {convertToCards, mergeZeroBuckets} from './heatmap_data_converter'; @@ -134,6 +134,8 @@ export default function link(scope, elem, attrs, ctrl) { let decimalsAuto = getPrecision(tick_interval); let decimals = panel.yAxis.decimals === null ? decimalsAuto : panel.yAxis.decimals; let scaledDecimals = getScaledDecimals(decimals, tick_interval); + ctrl.decimals = decimals; + ctrl.scaledDecimals = scaledDecimals; // Set default Y min and max if no data if (_.isEmpty(data.buckets)) { @@ -218,7 +220,10 @@ export default function link(scope, elem, attrs, ctrl) { let decimalsAuto = getPrecision(y_min); let decimals = panel.yAxis.decimals || decimalsAuto; + // TODO: calculate scaledDecimals for log scales using tick size (as in jquery.flot.js) let scaledDecimals = decimals - 2; + ctrl.decimals = decimals; + ctrl.scaledDecimals = scaledDecimals; data.yAxis = { min: y_min, @@ -298,10 +303,6 @@ export default function link(scope, elem, attrs, ctrl) { return tickValues; } - function getScaledDecimals(decimals, tick_size) { - return decimals - Math.floor(Math.log(tick_size) / Math.LN10); - } - function tickValueFormatter(decimals, scaledDecimals = null) { let format = panel.yAxis.format; return function(value) { From c12a7d7f5980b4256b48244389a5ef9c40fa504e Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 27 Jun 2017 13:39:20 +0300 Subject: [PATCH 061/179] heatmap: adjust tests for fixed decimals calc --- public/app/plugins/panel/heatmap/specs/renderer_specs.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/panel/heatmap/specs/renderer_specs.ts b/public/app/plugins/panel/heatmap/specs/renderer_specs.ts index 3bb3c04d122..9ca7297e9b6 100644 --- a/public/app/plugins/panel/heatmap/specs/renderer_specs.ts +++ b/public/app/plugins/panel/heatmap/specs/renderer_specs.ts @@ -204,7 +204,7 @@ describe('grafanaHeatmap', function () { it('should draw correct Y axis', function () { var yTicks = getTicks(ctx.element, ".axis-y"); - expect(yTicks).to.eql(['1', '32', '1 K']); + expect(yTicks).to.eql(['1', '32', '1.0 K']); }); }); @@ -221,7 +221,7 @@ describe('grafanaHeatmap', function () { it('should draw correct Y axis', function () { var yTicks = getTicks(ctx.element, ".axis-y"); - expect(yTicks).to.eql(['1', '1 K', '1 Mil']); + expect(yTicks).to.eql(['1', '1 K', '1.0 Mil']); }); }); @@ -247,7 +247,7 @@ describe('grafanaHeatmap', function () { it('should draw correct Y axis', function () { var yTicks = getTicks(ctx.element, ".axis-y"); - expect(yTicks).to.eql(['0 ns', '17 min', '33 min', '50 min', '1 hour']); + expect(yTicks).to.eql(['0 ns', '17 min', '33 min', '50 min', '1.11 hour']); }); }); From 12644372c4b68b6ba88be51f288f6a0cea55adaa Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 27 Jun 2017 13:59:54 +0300 Subject: [PATCH 062/179] heatmap: fix scaledDecimals calculation (use the same method as in flot.js) --- public/app/core/utils/ticks.ts | 36 +++++++++++++++++++ .../plugins/panel/heatmap/heatmap_tooltip.ts | 2 +- public/app/plugins/panel/heatmap/rendering.ts | 12 ++++--- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/public/app/core/utils/ticks.ts b/public/app/core/utils/ticks.ts index fa68b04d614..b033e9247a1 100644 --- a/public/app/core/utils/ticks.ts +++ b/public/app/core/utils/ticks.ts @@ -29,3 +29,39 @@ export function tickStep(start: number, stop: number, count: number): number { export function getScaledDecimals(decimals, tick_size) { return decimals - Math.floor(Math.log(tick_size) / Math.LN10); } + +/** + * Calculate tick size based on min and max values, number of ticks and precision. + * @param min Axis minimum + * @param max Axis maximum + * @param noTicks Number of ticks + * @param tickDecimals Tick decimal precision + */ +export function getFlotTickSize(min: number, max: number, noTicks: number, tickDecimals: number) { + var delta = (max - min) / noTicks, + dec = -Math.floor(Math.log(delta) / Math.LN10), + maxDec = tickDecimals; + + var magn = Math.pow(10, -dec), + norm = delta / magn, // norm is between 1.0 and 10.0 + size; + + if (norm < 1.5) { + size = 1; + } else if (norm < 3) { + size = 2; + // special case for 2.5, requires an extra decimal + if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { + size = 2.5; + ++dec; + } + } else if (norm < 7.5) { + size = 5; + } else { + size = 10; + } + + size *= magn; + + return size; +} diff --git a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts index 097d9f5897d..d455d89d3b2 100644 --- a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts +++ b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts @@ -89,7 +89,7 @@ export class HeatmapTooltip { let time = this.dashboard.formatDate(xData.x, tooltipTimeFormat); let decimals = this.panel.tooltipDecimals || this.panelCtrl.decimals; - let scaledDecimals = decimals - 2; + let scaledDecimals = this.panel.tooltipDecimals ? decimals - 2 : this.panelCtrl.scaledDecimals; let valueFormatter = this.valueFormatter(decimals, scaledDecimals); let tooltipHtml = `
${time}
diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index c713d254021..94903cfcb81 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -5,7 +5,7 @@ import $ from 'jquery'; import moment from 'moment'; import kbn from 'app/core/utils/kbn'; import {appEvents, contextSrv} from 'app/core/core'; -import {tickStep, getScaledDecimals} from 'app/core/utils/ticks'; +import {tickStep, getScaledDecimals, getFlotTickSize} from 'app/core/utils/ticks'; import d3 from 'd3'; import {HeatmapTooltip} from './heatmap_tooltip'; import {convertToCards, mergeZeroBuckets} from './heatmap_data_converter'; @@ -133,7 +133,9 @@ export default function link(scope, elem, attrs, ctrl) { let decimalsAuto = getPrecision(tick_interval); let decimals = panel.yAxis.decimals === null ? decimalsAuto : panel.yAxis.decimals; - let scaledDecimals = getScaledDecimals(decimals, tick_interval); + // Calculate scaledDecimals for log scales using tick size (as in jquery.flot.js) + let flot_tick_size = getFlotTickSize(y_min, y_max, ticks, decimalsAuto); + let scaledDecimals = getScaledDecimals(decimals, flot_tick_size); ctrl.decimals = decimals; ctrl.scaledDecimals = scaledDecimals; @@ -220,8 +222,10 @@ export default function link(scope, elem, attrs, ctrl) { let decimalsAuto = getPrecision(y_min); let decimals = panel.yAxis.decimals || decimalsAuto; - // TODO: calculate scaledDecimals for log scales using tick size (as in jquery.flot.js) - let scaledDecimals = decimals - 2; + + // Calculate scaledDecimals for log scales using tick size (as in jquery.flot.js) + let flot_tick_size = getFlotTickSize(y_min, y_max, tick_values.length, decimalsAuto); + let scaledDecimals = getScaledDecimals(decimals, flot_tick_size); ctrl.decimals = decimals; ctrl.scaledDecimals = scaledDecimals; From 83fbace6b9e122216a190c48400b513c434f3795 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 27 Jun 2017 19:25:54 +0300 Subject: [PATCH 063/179] heatmap: fix tooltip decimals calculation --- .../plugins/panel/heatmap/heatmap_tooltip.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts index d455d89d3b2..531ed8ca5b2 100644 --- a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts +++ b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts @@ -88,9 +88,17 @@ export class HeatmapTooltip { let tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss'; let time = this.dashboard.formatDate(xData.x, tooltipTimeFormat); - let decimals = this.panel.tooltipDecimals || this.panelCtrl.decimals; - let scaledDecimals = this.panel.tooltipDecimals ? decimals - 2 : this.panelCtrl.scaledDecimals; - let valueFormatter = this.valueFormatter(decimals, scaledDecimals); + // Decimals override. Code from panel/graph/graph.ts + let valueFormatter; + if (_.isNumber(this.panel.tooltipDecimals)) { + valueFormatter = this.valueFormatter(this.panel.tooltipDecimals, null); + } else { + // auto decimals + // legend and tooltip gets one more decimal precision + // than graph legend ticks + let decimals = (this.panelCtrl.decimals || -1) + 1; + valueFormatter = this.valueFormatter(this.panel.tooltipDecimals, this.panelCtrl.scaledDecimals + 2); + } let tooltipHtml = `
${time}
`; @@ -227,9 +235,6 @@ export class HeatmapTooltip { valueFormatter(decimals, scaledDecimals = null) { let format = this.panel.yAxis.format; return function(value) { - if (_.isInteger(value)) { - decimals = 0; - } return kbn.valueFormats[format](value, decimals, scaledDecimals); }; } From b674b9dba202f50a0f5dd23cdda098633d25b054 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 27 Jun 2017 22:23:22 +0200 Subject: [PATCH 064/179] heatmap: small fix for tooltip auto decimals Closes #8717 --- public/app/plugins/panel/heatmap/heatmap_tooltip.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts index 531ed8ca5b2..5ec0a8fa308 100644 --- a/public/app/plugins/panel/heatmap/heatmap_tooltip.ts +++ b/public/app/plugins/panel/heatmap/heatmap_tooltip.ts @@ -97,7 +97,7 @@ export class HeatmapTooltip { // legend and tooltip gets one more decimal precision // than graph legend ticks let decimals = (this.panelCtrl.decimals || -1) + 1; - valueFormatter = this.valueFormatter(this.panel.tooltipDecimals, this.panelCtrl.scaledDecimals + 2); + valueFormatter = this.valueFormatter(decimals, this.panelCtrl.scaledDecimals + 2); } let tooltipHtml = `
${time}
From 1a61d2814cc81801638be25c79b36e3dd8eb2160 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 19 Jun 2017 15:33:31 +0200 Subject: [PATCH 065/179] docs: updates to build from source --- docs/sources/project/building_from_source.md | 38 +++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/sources/project/building_from_source.md b/docs/sources/project/building_from_source.md index 3d6673d2fb0..5056f1bd7b1 100644 --- a/docs/sources/project/building_from_source.md +++ b/docs/sources/project/building_from_source.md @@ -15,14 +15,21 @@ dev environment. Grafana ships with its own required backend server; also comple - [Go 1.8.1](https://golang.org/dl/) - [NodeJS LTS](https://nodejs.org/download/) +- [Git](https://git-scm.com/downloads) ## Get Code -Create a directory for the project and set your path accordingly. Then download and install Grafana into your $GOPATH directory +Create a directory for the project and set your path accordingly (or use the [default Go workspace directory](https://golang.org/doc/code.html#GOPATH)). Then download and install Grafana into your $GOPATH directory: + ``` export GOPATH=`pwd` go get github.com/grafana/grafana ``` +On Windows use setx instead of export and then restart your command prompt: +``` +setx GOPATH %cd% +``` + You may see an error such as: `package github.com/grafana/grafana: no buildable Go source files`. This is just a warning, and you can proceed with the directions. ## Building the backend @@ -36,6 +43,12 @@ go run build.go build # (or 'go build ./pkg/cmd/grafana-server') The Grafana backend includes Sqlite3 which requires GCC to compile. So in order to compile Grafana on windows you need to install GCC. We recommend [TDM-GCC](http://tdm-gcc.tdragon.net/download). +[node-gyp](https://github.com/nodejs/node-gyp#installation) is the Node.js native addon build tool and it requires extra dependencies to be installed on Windows. In a command prompt which is run as administrator, run: + +``` +npm --add-python-to-path='true' --debug install --global windows-build-tools +``` + ## Build the Front-end Assets To build less to css for the frontend you will need a recent version of node (v0.12.0), @@ -55,6 +68,8 @@ go get github.com/Unknwon/bra bra run ``` +If the `bra run` command does not work, make sure that the bin directory in your Go workspace directory is in the path. $GOPATH/bin (or %GOPATH%\bin in Windows) is in your path. + ## Running Grafana Locally You can run a local instance of Grafana by running: ``` @@ -94,3 +109,24 @@ Learn more about Grafana config options in the [Configuration section](/installa ## Create a pull requests Please contribute to the Grafana project and submit a pull request! Build new features, write or update documentation, fix bugs and generally make Grafana even more awesome. + +## Troubleshooting + +**Problem**: PhantomJS or node-sass errors when running grunt + +**Solution**: delete the node_modules directory. Install [node-gyp](https://github.com/nodejs/node-gyp#installation) properly for your platform. Then run `yarn install --pure-lockfile` again. +

+ +**Problem**: When running `bra run` for the first time you get an error that it is not a recognized command. + +**Solution**: Add the bin directory in your Go workspace directory to the path. Per default this is `$HOME/go/bin` on Linux and `%USERPROFILE%\go\bin` on Windows or `$GOPATH/bin` (`%GOPATH%\bin` on Windows) if you have set your own workspace directory. +

+ +**Problem**: When executing a `go get` command on Windows and you get an error about the git repository not existing. + +**Solution**: `go get` requires Git. If you run `go get` without Git then it will create an empty directory in your Go workspace for the library you are trying to get. Even after installing Git, you will get a similar error. To fix this, delete the empty directory (for example: if you tried to run `go get github.com/Unknwon/bra` then delete `%USERPROFILE%\go\src\github.com\Unknwon\bra`) and run the `go get` command again. +

+ +**Problem**: On Windows, getting errors about a tool not being installed even though you just installed that tool. + +**Solution**: It is usually because it got added to the path and you have to restart your command prompt to use it. From 8973b48f96d7bf67178ff1aeb06e653fee61897e Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 19 Jun 2017 15:36:08 +0200 Subject: [PATCH 066/179] setting: add tests for windows --- .gitignore | 1 + pkg/setting/setting_test.go | 88 ++++++++++++++++++------- tests/config-files/override_windows.ini | 3 + 3 files changed, 68 insertions(+), 24 deletions(-) create mode 100644 tests/config-files/override_windows.ini diff --git a/.gitignore b/.gitignore index 5d3c506ca7a..08cfb7a2931 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ awsconfig /public/vendor/npm /tmp vendor/phantomjs/phantomjs +vendor/phantomjs/phantomjs.exe docs/AWS_S3_BUCKET docs/GIT_BRANCH diff --git a/pkg/setting/setting_test.go b/pkg/setting/setting_test.go index b213c2795af..640a1648340 100644 --- a/pkg/setting/setting_test.go +++ b/pkg/setting/setting_test.go @@ -3,6 +3,7 @@ package setting import ( "os" "path/filepath" + "runtime" "testing" . "github.com/smartystreets/goconvey/convey" @@ -52,13 +53,22 @@ func TestLoadingSettings(t *testing.T) { }) Convey("Should be able to override via command line", func() { - NewConfigContext(&CommandLineArgs{ - HomePath: "../../", - Args: []string{"cfg:paths.data=/tmp/data", "cfg:paths.logs=/tmp/logs"}, - }) + if runtime.GOOS == "windows" { + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Args: []string{`cfg:paths.data=c:\tmp\data`, `cfg:paths.logs=c:\tmp\logs`}, + }) + So(DataPath, ShouldEqual, `c:\tmp\data`) + So(LogsPath, ShouldEqual, `c:\tmp\logs`) + } else { + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Args: []string{"cfg:paths.data=/tmp/data", "cfg:paths.logs=/tmp/logs"}, + }) - So(DataPath, ShouldEqual, "/tmp/data") - So(LogsPath, ShouldEqual, "/tmp/logs") + So(DataPath, ShouldEqual, "/tmp/data") + So(LogsPath, ShouldEqual, "/tmp/logs") + } }) Convey("Should be able to override defaults via command line", func() { @@ -74,33 +84,63 @@ func TestLoadingSettings(t *testing.T) { }) Convey("Defaults can be overridden in specified config file", func() { - NewConfigContext(&CommandLineArgs{ - HomePath: "../../", - Config: filepath.Join(HomePath, "tests/config-files/override.ini"), - Args: []string{"cfg:default.paths.data=/tmp/data"}, - }) + if runtime.GOOS == "windows" { + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Config: filepath.Join(HomePath, "tests/config-files/override_windows.ini"), + Args: []string{`cfg:default.paths.data=c:\tmp\data`}, + }) - So(DataPath, ShouldEqual, "/tmp/override") + So(DataPath, ShouldEqual, `c:\tmp\override`) + } else { + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Config: filepath.Join(HomePath, "tests/config-files/override.ini"), + Args: []string{"cfg:default.paths.data=/tmp/data"}, + }) + + So(DataPath, ShouldEqual, "/tmp/override") + } }) Convey("Command line overrides specified config file", func() { - NewConfigContext(&CommandLineArgs{ - HomePath: "../../", - Config: filepath.Join(HomePath, "tests/config-files/override.ini"), - Args: []string{"cfg:paths.data=/tmp/data"}, - }) + if runtime.GOOS == "windows" { + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Config: filepath.Join(HomePath, "tests/config-files/override_windows.ini"), + Args: []string{`cfg:paths.data=c:\tmp\data`}, + }) - So(DataPath, ShouldEqual, "/tmp/data") + So(DataPath, ShouldEqual, `c:\tmp\data`) + } else { + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Config: filepath.Join(HomePath, "tests/config-files/override.ini"), + Args: []string{"cfg:paths.data=/tmp/data"}, + }) + + So(DataPath, ShouldEqual, "/tmp/data") + } }) Convey("Can use environment variables in config values", func() { - os.Setenv("GF_DATA_PATH", "/tmp/env_override") - NewConfigContext(&CommandLineArgs{ - HomePath: "../../", - Args: []string{"cfg:paths.data=${GF_DATA_PATH}"}, - }) + if runtime.GOOS == "windows" { + os.Setenv("GF_DATA_PATH", `c:\tmp\env_override`) + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Args: []string{"cfg:paths.data=${GF_DATA_PATH}"}, + }) - So(DataPath, ShouldEqual, "/tmp/env_override") + So(DataPath, ShouldEqual, `c:\tmp\env_override`) + } else { + os.Setenv("GF_DATA_PATH", "/tmp/env_override") + NewConfigContext(&CommandLineArgs{ + HomePath: "../../", + Args: []string{"cfg:paths.data=${GF_DATA_PATH}"}, + }) + + So(DataPath, ShouldEqual, "/tmp/env_override") + } }) Convey("instance_name default to hostname even if hostname env is empty", func() { diff --git a/tests/config-files/override_windows.ini b/tests/config-files/override_windows.ini new file mode 100644 index 00000000000..c0219afc8c8 --- /dev/null +++ b/tests/config-files/override_windows.ini @@ -0,0 +1,3 @@ +[paths] +data = c:\tmp\override + From 91ad2605172615dcbf57adb13321b35d31b6d06d Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 19 Jun 2017 21:01:42 +0200 Subject: [PATCH 067/179] build: on windows, ignore linux packaging --- appveyor.yml | 1 + build.go | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 303c3abca9e..af28a77b8c5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -29,6 +29,7 @@ install: build_script: - go run build.go build + - go test -v ./pkg/... - grunt release - go run build.go sha-dist - cp dist/* . diff --git a/build.go b/build.go index f60a53e5ddb..a1d1d3012ab 100644 --- a/build.go +++ b/build.go @@ -95,7 +95,9 @@ func main() { case "package": grunt(gruntBuildArg("release")...) - createLinuxPackages() + if runtime.GOOS != "windows" { + createLinuxPackages() + } case "pkg-rpm": grunt(gruntBuildArg("release")...) @@ -345,7 +347,11 @@ func ChangeWorkingDir(dir string) { } func grunt(params ...string) { - runPrint("./node_modules/.bin/grunt", params...) + if runtime.GOOS == "windows" { + runPrint(`.\node_modules\.bin\grunt`, params...) + } else { + runPrint("./node_modules/.bin/grunt", params...) + } } func gruntBuildArg(task string) []string { From 3ac306a72ee8a44617935c6fc7af21a2d6044a6e Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Wed, 28 Jun 2017 16:29:46 +0200 Subject: [PATCH 068/179] playlist: fixes #6727. Remember Kiosk mode --- public/app/features/playlist/playlist_srv.ts | 45 ++++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/public/app/features/playlist/playlist_srv.ts b/public/app/features/playlist/playlist_srv.ts index 5ddfe572cda..c9553dcdcca 100644 --- a/public/app/features/playlist/playlist_srv.ts +++ b/public/app/features/playlist/playlist_srv.ts @@ -3,6 +3,7 @@ import angular from 'angular'; import coreModule from '../../core/core_module'; import kbn from 'app/core/utils/kbn'; +import appEvents from 'app/core/app_events'; class PlaylistSrv { private cancelPromise: any; @@ -14,7 +15,13 @@ class PlaylistSrv { public isPlaying: boolean; /** @ngInject */ - constructor(private $rootScope: any, private $location: any, private $timeout: any, private backendSrv: any) { } + constructor( + private $rootScope: any, + private $location: any, + private $timeout: any, + private backendSrv: any, + private $routeParams: any + ) { } next() { this.$timeout.cancel(this.cancelPromise); @@ -22,14 +29,32 @@ class PlaylistSrv { var playedAllDashboards = this.index > this.dashboards.length - 1; if (playedAllDashboards) { - window.location.href = this.startUrl; - } else { - var dash = this.dashboards[this.index]; - this.$location.url('dashboard/' + dash.uri); - - this.index++; - this.cancelPromise = this.$timeout(() => this.next(), this.interval); + window.location.href = this.getUrlWithKioskMode(); + return; } + + var dash = this.dashboards[this.index]; + this.$location.url('dashboard/' + dash.uri); + + this.index++; + this.cancelPromise = this.$timeout(() => this.next(), this.interval); + } + + getUrlWithKioskMode() { + const inKioskMode = document.body.classList.contains('page-kiosk-mode'); + + // check if should add kiosk query param + if (inKioskMode && this.startUrl.indexOf('kiosk') === -1) { + return this.startUrl + '?kiosk=true'; + } + + // check if should remove kiosk query param + if (!inKioskMode) { + return this.startUrl.split("?")[0]; + } + + // already has kiosk query param, just return startUrl + return this.startUrl; } prev() { @@ -45,6 +70,10 @@ class PlaylistSrv { this.playlistId = playlistId; this.isPlaying = true; + if (this.$routeParams.kiosk) { + appEvents.emit('toggle-kiosk-mode'); + } + this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => { this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => { this.dashboards = dashboards; From 8634c9d457d6e624d762a476e817a401bebcf442 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Wed, 28 Jun 2017 18:12:55 +0300 Subject: [PATCH 069/179] Histogram fix (#8727) * histogram: don't cut negative values, issue #8628 * histogram: add percent/count option * histogram: add tests for values normalizing * histogram: improved ticks rendering * histogram: fix default value in axes editor --- .../app/plugins/panel/graph/axes_editor.html | 6 ++++ public/app/plugins/panel/graph/axes_editor.ts | 6 ++++ public/app/plugins/panel/graph/graph.ts | 29 +++++++++++++---- public/app/plugins/panel/graph/histogram.ts | 11 +++++-- public/app/plugins/panel/graph/module.ts | 3 +- .../panel/graph/specs/histogram_specs.ts | 32 ++++++++++++++++--- 6 files changed, 73 insertions(+), 14 deletions(-) diff --git a/public/app/plugins/panel/graph/axes_editor.html b/public/app/plugins/panel/graph/axes_editor.html index b0ab759bf18..1e577fe392e 100644 --- a/public/app/plugins/panel/graph/axes_editor.html +++ b/public/app/plugins/panel/graph/axes_editor.html @@ -67,6 +67,12 @@
+
+ +
+ +
+
diff --git a/public/app/plugins/panel/graph/axes_editor.ts b/public/app/plugins/panel/graph/axes_editor.ts index adb3d1d6706..155265e5987 100644 --- a/public/app/plugins/panel/graph/axes_editor.ts +++ b/public/app/plugins/panel/graph/axes_editor.ts @@ -10,6 +10,7 @@ export class AxesEditorCtrl { xAxisModes: any; xAxisStatOptions: any; xNameSegment: any; + histogramValues: any; /** @ngInject **/ constructor(private $scope, private $q) { @@ -34,6 +35,11 @@ export class AxesEditorCtrl { // 'Data field': 'field', }; + this.histogramValues = { + 'Percent': 'percent', + 'Count': 'count' + }; + this.xAxisStatOptions = [ {text: 'Avg', value: 'avg'}, {text: 'Min', value: 'min'}, diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 16d259c210e..8c928fb6a41 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -312,10 +312,13 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { let histMax = _.max(_.map(data, s => s.stats.max)); let ticks = panel.xaxis.buckets || panelWidth / 50; bucketSize = tickStep(histMin, histMax, ticks); - let histogram = convertValuesToHistogram(values, bucketSize); + let normalize = panel.xaxis.histogramValue === 'percent'; + let histogram = convertValuesToHistogram(values, bucketSize, normalize); + + let seriesLabel = panel.xaxis.histogramValue || "count"; data[0].data = histogram; - data[0].alias = data[0].label = data[0].id = "count"; + data[0].alias = data[0].label = data[0].id = seriesLabel; data = [data[0]]; options.series.bars.barWidth = bucketSize * 0.8; @@ -422,21 +425,32 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { function addXHistogramAxis(options, bucketSize) { let ticks, min, max; + let defaultTicks = panelWidth / 50; if (data.length && bucketSize) { ticks = _.map(data[0].data, point => point[0]); + min = _.min(ticks); + max = _.max(ticks); + + // Adjust tick step + let tickStep = bucketSize; + let ticks_num = Math.floor((max - min) / tickStep); + while (ticks_num > defaultTicks) { + tickStep = tickStep * 2; + ticks_num = Math.ceil((max - min) / tickStep); + } // Expand ticks for pretty view - min = Math.max(0, _.min(ticks) - bucketSize); - max = _.max(ticks) + bucketSize; + min = Math.floor(min / tickStep) * tickStep; + max = Math.ceil(max / tickStep) * tickStep; ticks = []; - for (let i = min; i <= max; i += bucketSize) { + for (let i = min; i <= max; i += tickStep) { ticks.push(i); } } else { // Set defaults if no data - ticks = panelWidth / 100; + ticks = defaultTicks / 2; min = 0; max = 1; } @@ -450,6 +464,9 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { label: "Histogram", ticks: ticks }; + + // Use 'short' format for histogram values + configureAxisMode(options.xaxis, 'short'); } function addXTableAxis(options) { diff --git a/public/app/plugins/panel/graph/histogram.ts b/public/app/plugins/panel/graph/histogram.ts index e6ad7ebb0f6..efb13c546f0 100644 --- a/public/app/plugins/panel/graph/histogram.ts +++ b/public/app/plugins/panel/graph/histogram.ts @@ -26,7 +26,7 @@ export function getSeriesValues(data: any): number[] { * @param values * @param bucketSize */ -export function convertValuesToHistogram(values: number[], bucketSize: number): any[] { +export function convertValuesToHistogram(values: number[], bucketSize: number, normalize = false): any[] { let histogram = {}; for (let i = 0; i < values.length; i++) { @@ -38,9 +38,16 @@ export function convertValuesToHistogram(values: number[], bucketSize: number): } } - return _.map(histogram, (count, bound) => { + let histogam_series = _.map(histogram, (count, bound) => { + if (normalize && values.length) { + return [Number(bound), count / values.length]; + } + return [Number(bound), count]; }); + + // Sort by Y axis values + return _.sortBy(histogam_series, point => point[0]); } function getBucketBound(value: number, bucketSize: number): number { diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index e9ca8c5c4e2..fed739a60d7 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -58,7 +58,8 @@ class GraphCtrl extends MetricsPanelCtrl { mode: 'time', name: null, values: [], - buckets: null + buckets: null, + histogramValue: 'percent' }, // show/hide lines lines : true, diff --git a/public/app/plugins/panel/graph/specs/histogram_specs.ts b/public/app/plugins/panel/graph/specs/histogram_specs.ts index 71b3def8d1d..4d5ad02aec9 100644 --- a/public/app/plugins/panel/graph/specs/histogram_specs.ts +++ b/public/app/plugins/panel/graph/specs/histogram_specs.ts @@ -1,7 +1,6 @@ /// - +import _ from 'lodash'; import { describe, beforeEach, it, expect } from '../../../../../test/lib/common'; - import { convertValuesToHistogram, getSeriesValues } from '../histogram'; describe('Graph Histogam Converter', function () { @@ -11,13 +10,13 @@ describe('Graph Histogam Converter', function () { let bucketSize = 10; beforeEach(() => { - values = [1, 2, 10, 11, 17, 20, 29]; + values = [1, 2, 10, 11, 17, 20, 29, 30, 31, 33]; }); it('Should convert to series-like array', () => { bucketSize = 10; let expected = [ - [0, 2], [10, 3], [20, 2] + [0, 2], [10, 3], [20, 2], [30, 3] ]; let histogram = convertValuesToHistogram(values, bucketSize); @@ -27,12 +26,35 @@ describe('Graph Histogam Converter', function () { it('Should not add empty buckets', () => { bucketSize = 5; let expected = [ - [0, 2], [10, 2], [15, 1], [20, 1], [25, 1] + [0, 2], [10, 2], [15, 1], [20, 1], [25, 1], [30, 3] ]; let histogram = convertValuesToHistogram(values, bucketSize); expect(histogram).to.eql(expected); }); + + it('Should normalize values', () => { + bucketSize = 5; + let normalize = true; + let expected = [ + [0, 0.2], [10, 0.2], [15, 0.1], [20, 0.1], [25, 0.1], [30, 0.3] + ]; + + let histogram = convertValuesToHistogram(values, bucketSize, normalize); + expect(histogram).to.eql(expected); + }); + + it('Sum of normalized values should be 1', () => { + bucketSize = 5; + let normalize = true; + let expected = [ + [0, 0.2], [10, 0.2], [15, 0.1], [20, 0.1], [25, 0.1], [30, 0.3] + ]; + + let histogram = convertValuesToHistogram(values, bucketSize, normalize); + let sum = _.reduce(histogram, (sum, point) => sum + point[1], 0); + expect(sum).to.eql(1); + }); }); describe('Series to values converter', () => { From 97a7081b5735af8bb746ffd0e797f946f990ab34 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 29 Jun 2017 11:40:28 +0300 Subject: [PATCH 070/179] Fix 8706 (#8734) * heatmap: fix incorrect time for UTC timezone, fixes #8706 * heatmap: fix tests for time format --- public/app/plugins/panel/heatmap/rendering.ts | 9 ++++++++- .../plugins/panel/heatmap/specs/renderer_specs.ts | 14 +++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index 94903cfcb81..b928173eafe 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -100,10 +100,17 @@ export default function link(scope, elem, attrs, ctrl) { let ticks = chartWidth / DEFAULT_X_TICK_SIZE_PX; let grafanaTimeFormatter = grafanaTimeFormat(ticks, timeRange.from, timeRange.to); + let timeFormat; + let dashboardTimeZone = ctrl.dashboard.getTimezone(); + if (dashboardTimeZone === 'utc') { + timeFormat = d3.utcFormat(grafanaTimeFormatter); + } else { + timeFormat = d3.timeFormat(grafanaTimeFormatter); + } let xAxis = d3.axisBottom(xScale) .ticks(ticks) - .tickFormat(d3.timeFormat(grafanaTimeFormatter)) + .tickFormat(timeFormat) .tickPadding(X_AXIS_TICK_PADDING) .tickSize(chartHeight); diff --git a/public/app/plugins/panel/heatmap/specs/renderer_specs.ts b/public/app/plugins/panel/heatmap/specs/renderer_specs.ts index 9ca7297e9b6..5d3eb665e55 100644 --- a/public/app/plugins/panel/heatmap/specs/renderer_specs.ts +++ b/public/app/plugins/panel/heatmap/specs/renderer_specs.ts @@ -153,11 +153,11 @@ describe('grafanaHeatmap', function () { it('should draw correct X axis', function () { var xTicks = getTicks(ctx.element, ".axis-x"); let expectedTicks = [ - formatLocalTime("01 Mar 2017 10:00:00"), - formatLocalTime("01 Mar 2017 10:15:00"), - formatLocalTime("01 Mar 2017 10:30:00"), - formatLocalTime("01 Mar 2017 10:45:00"), - formatLocalTime("01 Mar 2017 11:00:00") + formatTime("01 Mar 2017 10:00:00"), + formatTime("01 Mar 2017 10:15:00"), + formatTime("01 Mar 2017 10:30:00"), + formatTime("01 Mar 2017 10:45:00"), + formatTime("01 Mar 2017 11:00:00") ]; expect(xTicks).to.eql(expectedTicks); }); @@ -261,7 +261,7 @@ function getTicks(element, axisSelector) { }).get(); } -function formatLocalTime(timeStr) { +function formatTime(timeStr) { let format = "HH:mm"; - return moment.utc(timeStr, 'DD MMM YYYY HH:mm:ss').local().format(format); + return moment.utc(timeStr, 'DD MMM YYYY HH:mm:ss').format(format); } From 7ea5930a90eb198ecd2b4051f27424ae35fd07bf Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Thu, 29 Jun 2017 12:18:10 +0200 Subject: [PATCH 071/179] alerting: minor fix --- public/app/features/alerting/notification_edit_ctrl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/alerting/notification_edit_ctrl.ts b/public/app/features/alerting/notification_edit_ctrl.ts index 768cc16266e..d1b855cbf3a 100644 --- a/public/app/features/alerting/notification_edit_ctrl.ts +++ b/public/app/features/alerting/notification_edit_ctrl.ts @@ -88,7 +88,7 @@ export class AlertNotificationEditCtrl { this.backendSrv.post(`/api/alert-notifications/test`, payload) .then(res => { - appEvents.emit('alert-succes', ['Test notification sent', '']); + appEvents.emit('alert-success', ['Test notification sent', '']); }); } } From 8683aff3e952ca1b2472d6249a13f1b8c34c77b0 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Thu, 29 Jun 2017 12:00:59 +0200 Subject: [PATCH 072/179] appveyor: build fix for go tests --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index af28a77b8c5..9f8e9a26622 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -29,10 +29,10 @@ install: build_script: - go run build.go build - - go test -v ./pkg/... - grunt release - go run build.go sha-dist - cp dist/* . + - go test -v ./pkg/... artifacts: - path: grafana-*windows-*.* From fb99ddf2955e60551cbaae23e358ee4e33136e1c Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Thu, 29 Jun 2017 13:58:54 +0200 Subject: [PATCH 073/179] influxdb: tweak to help text --- docs/sources/features/datasources/influxdb.md | 2 +- .../plugins/datasource/influxdb/partials/query.options.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sources/features/datasources/influxdb.md b/docs/sources/features/datasources/influxdb.md index 1f6c36a6bb3..39a22085d93 100644 --- a/docs/sources/features/datasources/influxdb.md +++ b/docs/sources/features/datasources/influxdb.md @@ -88,7 +88,7 @@ You can switch to raw query mode by clicking hamburger icon and then `Switch edi - $m = replaced with measurement name - $measurement = replaced with measurement name - $col = replaced with column name -- $tag_hostname = replaced with the value of the hostname tag. Use your tag instead of hostname and the tag must be used to group by in the query when used in the ALIAS BY field. +- $tag_exampletag = replaced with the value of the `exampletag` tag. To use your tag as an alias in the ALIAS BY field then the tag must be used to group by in the query. - You can also use [[tag_hostname]] pattern replacement syntax. For example, in the ALIAS BY field using this text `Host: [[tag_hostname]]` would substitute in the `hostname` tag value for each legend value and an example legend value would be: `Host: server1`. ### Table query / raw data diff --git a/public/app/plugins/datasource/influxdb/partials/query.options.html b/public/app/plugins/datasource/influxdb/partials/query.options.html index 80e7f0e59ea..68293b69f70 100644 --- a/public/app/plugins/datasource/influxdb/partials/query.options.html +++ b/public/app/plugins/datasource/influxdb/partials/query.options.html @@ -46,8 +46,8 @@
  • $measurement = replaced with measurement name
  • $1 - $9 = replaced with part of measurement name (if you separate your measurement name with dots)
  • $col = replaced with column name
  • -
  • $tag_hostname = replaced with the value of the hostname tag
  • -
  • You can also use [[tag_hostname]] pattern replacement syntax
  • +
  • $tag_exampletag = replaced with the value of the exampletag tag
  • +
  • You can also use [[tag_exampletag]] pattern replacement syntax
  • From 1fd7b60efec07c8dcf9a1c3182a2a7c1f333db16 Mon Sep 17 00:00:00 2001 From: Ben Tranter Date: Thu, 29 Jun 2017 14:38:48 -0400 Subject: [PATCH 074/179] Add more information to basic diff logic --- pkg/components/dashdiffs/formatter_basic.go | 175 +++++++++++++------- 1 file changed, 114 insertions(+), 61 deletions(-) diff --git a/pkg/components/dashdiffs/formatter_basic.go b/pkg/components/dashdiffs/formatter_basic.go index 5b1d5504bc6..af93ff42bf2 100644 --- a/pkg/components/dashdiffs/formatter_basic.go +++ b/pkg/components/dashdiffs/formatter_basic.go @@ -98,13 +98,7 @@ func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock { blocks := make([]*BasicBlock, 0) for _, line := range lines { - // In order to produce distinct "blocks" when rendering the basic diff, - // we need a way to distinguish between differnt sections of data. - // To do this, we consider the value(s) of each top-level JSON key to - // represent a distinct block for Grafana's JSON data structure, so - // we perform this check to see if we've entered a new "block". If we - // have, we simply append the existing block to the array of blocks. - if b.LastIndent == 2 && line.Indent == 1 && line.Change == ChangeNil { + if b.returnToTopLevelKey(line) { if b.Block != nil { blocks = append(blocks, b.Block) } @@ -114,56 +108,9 @@ func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock { // check for a change in depth inside the JSON data structures. b.LastIndent = line.Indent - // TODO: why special handling for indent 2? - // Here we - // If the line's indentation is at level 1, then we know it's a top - // level key in the JSON document. As mentioned earlier, we treat these - // specially as they indicate their values belong to distinct blocks. - // - // At level 1, we only record single-line changes, ie, the "added", - // "deleted", "old" or "new" cases, since we know those values aren't - // arrays or maps. We only handle these cases at level 2 or deeper, - // since for those we either output a "change" or "summary". This is - // done for formatting reasons only, so we have logical "blocks" to - // display. if line.Indent == 1 { - switch line.Change { - case ChangeNil: - if line.Change == ChangeNil { - if line.Key != "" { - b.Block = &BasicBlock{ - Title: line.Key, - Change: line.Change, - } - } - } - - case ChangeAdded, ChangeDeleted: - blocks = append(blocks, &BasicBlock{ - Title: line.Key, - Change: line.Change, - New: line.Val, - LineStart: line.LineNum, - }) - - case ChangeOld: - b.Block = &BasicBlock{ - Title: line.Key, - Old: line.Val, - Change: line.Change, - LineStart: line.LineNum, - } - - case ChangeNew: - b.Block.New = line.Val - b.Block.LineEnd = line.LineNum - - // For every "old" change there is a corresponding "new", which - // is why we wait until we detect the "new" change before - // appending the change. - blocks = append(blocks, b.Block) - default: - // ok + if block, ok := b.handleTopLevelChange(line); ok { + blocks = append(blocks, block) } } @@ -182,8 +129,8 @@ func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock { // finding the change, we append it to the current block, and begin // performing comparisons again. if line.Indent > 1 { - // Ensure a single line change - if line.Key != "" && line.Val != nil && !b.writing { + // check to ensure a single line change + if b.isSingleLineChange(line) { switch line.Change { case ChangeAdded, ChangeDeleted: @@ -211,13 +158,31 @@ func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock { //ok } + // otherwise, we're dealing with a change at a deeper level. We + // know there's a change somewhere in the JSON tree, but we + // don't know exactly where, so we go deeper. } else { + + // if the change is anything but unchanged, continue processing + // + // we keep "narrowing" the key as we go deeper, in order to + // correctly report the key name for changes found within an + // object or array. if line.Change != ChangeUnchanged { if line.Key != "" { b.narrow = line.Key b.keysIdent = line.Indent } + // if the change isn't nil, and we're not already writing + // out a change, then we've found something. + // + // First, try to determine the title of the embedded JSON + // object. If it's an empty string, then we're in an object + // or array, so we default to using the "narrowed" key. + // + // We also start recording the basic summary, until we find + // the next `ChangeUnchanged`. if line.Change != ChangeNil { if !b.writing { b.writing = true @@ -237,6 +202,17 @@ func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock { } } } + // if we find a `ChangeUnchanged`, we do one of two things: + // + // - if we're recording a change already, then we know + // we've come to the end of that change block, so we write + // that change out be recording the line number of where + // that change ends, and append it to the current block's + // summary. + // + // - if we're not recording a change, then we do nothing, + // since the BasicDiff doesn't report on unchanged JSON + // values. } else { if b.writing { b.writing = false @@ -251,6 +227,81 @@ func (b *BasicDiff) Basic(lines []*JSONLine) []*BasicBlock { return blocks } +// returnToTopLevelKey indicates that we've moved from a key at one level deep +// in the JSON document to a top level key. +// +// In order to produce distinct "blocks" when rendering the basic diff, +// we need a way to distinguish between differnt sections of data. +// To do this, we consider the value(s) of each top-level JSON key to +// represent a distinct block for Grafana's JSON data structure, so +// we perform this check to see if we've entered a new "block". If we +// have, we simply append the existing block to the array of blocks. +func (b *BasicDiff) returnToTopLevelKey(line *JSONLine) bool { + return b.LastIndent == 2 && line.Indent == 1 && line.Change == ChangeNil +} + +// handleTopLevelChange handles a change on one of the top-level keys on a JSON +// document. +// +// If the line's indentation is at level 1, then we know it's a top +// level key in the JSON document. As mentioned earlier, we treat these +// specially as they indicate their values belong to distinct blocks. +// +// At level 1, we only record single-line changes, ie, the "added", +// "deleted", "old" or "new" cases, since we know those values aren't +// arrays or maps. We only handle these cases at level 2 or deeper, +// since for those we either output a "change" or "summary". This is +// done for formatting reasons only, so we have logical "blocks" to +// display. +func (b *BasicDiff) handleTopLevelChange(line *JSONLine) (*BasicBlock, bool) { + switch line.Change { + case ChangeNil: + if line.Change == ChangeNil { + if line.Key != "" { + b.Block = &BasicBlock{ + Title: line.Key, + Change: line.Change, + } + } + } + + case ChangeAdded, ChangeDeleted: + return &BasicBlock{ + Title: line.Key, + Change: line.Change, + New: line.Val, + LineStart: line.LineNum, + }, true + + case ChangeOld: + b.Block = &BasicBlock{ + Title: line.Key, + Old: line.Val, + Change: line.Change, + LineStart: line.LineNum, + } + + case ChangeNew: + b.Block.New = line.Val + b.Block.LineEnd = line.LineNum + + // For every "old" change there is a corresponding "new", which + // is why we wait until we detect the "new" change before + // appending the change. + return b.Block, true + default: + // ok + } + + return nil, false +} + +// isSingleLineChange ensures we're iterating over a single line change (ie, +// either a single line or a old-new value pair was changed in the JSON file). +func (b *BasicDiff) isSingleLineChange(line *JSONLine) bool { + return line.Key != "" && line.Val != nil && !b.writing +} + // encStateMap is used in the template helper var ( encStateMap = map[ChangeType]string{ @@ -273,7 +324,9 @@ var ( ) var ( - // tplBlock is the whole thing + // tplBlock is the container for the basic diff. It iterates over each + // basic block, expanding each "change" and "summary" belonging to every + // block. tplBlock = `{{ define "block" -}} {{ range . }}
    @@ -319,7 +372,7 @@ var ( {{ end }} {{ end }}` - // tplChange is the template for changes + // tplChange is the template for basic changes. tplChange = `{{ define "change" -}}
  • @@ -346,7 +399,7 @@ var (
  • {{ end }}` - // tplSummary is for basis summaries + // tplSummary is for basic summaries. tplSummary = `{{ define "summary" -}}
    From b8aa203707f2c526152f9c0a43110859094e1d70 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Fri, 30 Jun 2017 20:21:05 +0200 Subject: [PATCH 075/179] signup: fix email sent logic for tempuser Fixes #8656 and properly sets the email_sent and email_sent_on fields for a tempuser (signup user). --- pkg/api/org_invite.go | 5 +++++ pkg/models/temp_user.go | 4 ++++ pkg/services/notifications/notifications.go | 8 +++++++- pkg/services/sqlstore/datasource_test.go | 2 ++ pkg/services/sqlstore/temp_user.go | 15 +++++++++++++++ pkg/services/sqlstore/temp_user_test.go | 13 +++++++++++++ 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/pkg/api/org_invite.go b/pkg/api/org_invite.go index 9e85808950f..b776186aec7 100644 --- a/pkg/api/org_invite.go +++ b/pkg/api/org_invite.go @@ -78,6 +78,11 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response return ApiError(500, "Failed to send email invite", err) } + emailSentCmd := m.UpdateTempUserWithEmailSentCommand{Code: cmd.Result.Code} + if err := bus.Dispatch(&emailSentCmd); err != nil { + return ApiError(500, "Failed to update invite with email sent info", err) + } + return ApiSuccess(fmt.Sprintf("Sent invite to %s", inviteDto.LoginOrEmail)) } diff --git a/pkg/models/temp_user.go b/pkg/models/temp_user.go index 00c496c4844..0e09627aab1 100644 --- a/pkg/models/temp_user.go +++ b/pkg/models/temp_user.go @@ -60,6 +60,10 @@ type UpdateTempUserStatusCommand struct { Status TempUserStatus } +type UpdateTempUserWithEmailSentCommand struct { + Code string +} + type GetTempUsersQuery struct { OrgId int64 Email string diff --git a/pkg/services/notifications/notifications.go b/pkg/services/notifications/notifications.go index c765774d062..25eb2b5936a 100644 --- a/pkg/services/notifications/notifications.go +++ b/pkg/services/notifications/notifications.go @@ -146,7 +146,7 @@ func signUpStartedHandler(evt *events.SignUpStarted) error { return nil } - return sendEmailCommandHandler(&m.SendEmailCommand{ + err := sendEmailCommandHandler(&m.SendEmailCommand{ To: []string{evt.Email}, Template: tmplSignUpStarted, Data: map[string]interface{}{ @@ -155,6 +155,12 @@ func signUpStartedHandler(evt *events.SignUpStarted) error { "SignUpUrl": setting.ToAbsUrl(fmt.Sprintf("signup/?email=%s&code=%s", url.QueryEscape(evt.Email), url.QueryEscape(evt.Code))), }, }) + if err != nil { + return err + } + + emailSentCmd := m.UpdateTempUserWithEmailSentCommand{Code: evt.Code} + return bus.Dispatch(&emailSentCmd) } func signUpCompletedHandler(evt *events.SignUpCompleted) error { diff --git a/pkg/services/sqlstore/datasource_test.go b/pkg/services/sqlstore/datasource_test.go index 2749a3cc426..51bc759fdaf 100644 --- a/pkg/services/sqlstore/datasource_test.go +++ b/pkg/services/sqlstore/datasource_test.go @@ -16,6 +16,8 @@ func InitTestDB(t *testing.T) { //x, err := xorm.NewEngine(sqlutil.TestDB_Mysql.DriverName, sqlutil.TestDB_Mysql.ConnStr) //x, err := xorm.NewEngine(sqlutil.TestDB_Postgres.DriverName, sqlutil.TestDB_Postgres.ConnStr) + // x.ShowSQL() + if err != nil { t.Fatalf("Failed to init in memory sqllite3 db %v", err) } diff --git a/pkg/services/sqlstore/temp_user.go b/pkg/services/sqlstore/temp_user.go index 8864d5fb02a..43e1f027057 100644 --- a/pkg/services/sqlstore/temp_user.go +++ b/pkg/services/sqlstore/temp_user.go @@ -12,6 +12,7 @@ func init() { bus.AddHandler("sql", GetTempUsersQuery) bus.AddHandler("sql", UpdateTempUserStatus) bus.AddHandler("sql", GetTempUserByCode) + bus.AddHandler("sql", UpdateTempUserWithEmailSent) } func UpdateTempUserStatus(cmd *m.UpdateTempUserStatusCommand) error { @@ -35,6 +36,7 @@ func CreateTempUser(cmd *m.CreateTempUserCommand) error { Status: cmd.Status, RemoteAddr: cmd.RemoteAddr, InvitedByUserId: cmd.InvitedByUserId, + EmailSentOn: time.Now(), Created: time.Now(), Updated: time.Now(), } @@ -48,6 +50,19 @@ func CreateTempUser(cmd *m.CreateTempUserCommand) error { }) } +func UpdateTempUserWithEmailSent(cmd *m.UpdateTempUserWithEmailSentCommand) error { + return inTransaction(func(sess *DBSession) error { + user := &m.TempUser{ + EmailSent: true, + EmailSentOn: time.Now(), + } + + _, err := sess.Where("code = ?", cmd.Code).Cols("email_sent", "email_sent_on").Update(user) + + return err + }) +} + func GetTempUsersQuery(query *m.GetTempUsersQuery) error { rawSql := `SELECT tu.id as id, diff --git a/pkg/services/sqlstore/temp_user_test.go b/pkg/services/sqlstore/temp_user_test.go index ebf753890f6..80560258162 100644 --- a/pkg/services/sqlstore/temp_user_test.go +++ b/pkg/services/sqlstore/temp_user_test.go @@ -54,6 +54,19 @@ func TestTempUserCommandsAndQueries(t *testing.T) { So(err, ShouldBeNil) }) + Convey("Should be able update email sent and email sent on", func() { + cmd3 := m.UpdateTempUserWithEmailSentCommand{Code: cmd.Result.Code} + err := UpdateTempUserWithEmailSent(&cmd3) + So(err, ShouldBeNil) + + query := m.GetTempUsersQuery{OrgId: 2256, Status: m.TmpUserInvitePending} + err = GetTempUsersQuery(&query) + + So(err, ShouldBeNil) + So(query.Result[0].EmailSent, ShouldBeTrue) + So(query.Result[0].EmailSentOn, ShouldHappenOnOrAfter, (query.Result[0].Created)) + }) + }) }) } From 1499c2bf747b81db44a9f23cf6d784fc033bff4d Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 3 Jul 2017 10:20:55 +0300 Subject: [PATCH 076/179] Fix User/Org default timezone bug (#8748) * dashboard: don't override timezone if default selected, issue #8503 * dashboard: hide UTC icon immediately after timezone changing --- public/app/features/dashboard/model.ts | 4 ++-- public/app/features/dashboard/timepicker/timepicker.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/public/app/features/dashboard/model.ts b/public/app/features/dashboard/model.ts index cdb61ac4ad7..01c805694a6 100644 --- a/public/app/features/dashboard/model.ts +++ b/public/app/features/dashboard/model.ts @@ -247,9 +247,9 @@ export class DashboardModel { formatDate(date, format?) { date = moment.isMoment(date) ? date : moment(date); format = format || 'YYYY-MM-DD HH:mm:ss'; - this.timezone = this.getTimezone(); + let timezone = this.getTimezone(); - return this.timezone === 'browser' ? + return timezone === 'browser' ? moment(date).format(format) : moment.utc(date).format(format); } diff --git a/public/app/features/dashboard/timepicker/timepicker.ts b/public/app/features/dashboard/timepicker/timepicker.ts index 2cdfd7a77f6..bf3937f8322 100644 --- a/public/app/features/dashboard/timepicker/timepicker.ts +++ b/public/app/features/dashboard/timepicker/timepicker.ts @@ -56,6 +56,7 @@ export class TimePickerCtrl { if (moment.isMoment(timeRaw.to)) { timeRaw.to.local(); } + this.isUtc = false; } else { this.isUtc = true; } From 6f4c7a4d65c613f2129637b6ffec0a058d6430a4 Mon Sep 17 00:00:00 2001 From: Ben Tranter Date: Mon, 3 Jul 2017 08:29:30 -0400 Subject: [PATCH 077/179] Add dashboard version history documentation (#8741) Adds docs for the new API endpoints, and for the dashboard history feature. --- docs/sources/http_api/dashboard_versions.md | 321 ++++++++++++++++++++ docs/sources/reference/dashboard_history.md | 40 +++ 2 files changed, 361 insertions(+) create mode 100644 docs/sources/http_api/dashboard_versions.md create mode 100644 docs/sources/reference/dashboard_history.md diff --git a/docs/sources/http_api/dashboard_versions.md b/docs/sources/http_api/dashboard_versions.md new file mode 100644 index 00000000000..3d0ec27a3a3 --- /dev/null +++ b/docs/sources/http_api/dashboard_versions.md @@ -0,0 +1,321 @@ ++++ +title = "Dashboard Versions HTTP API " +description = "Grafana Dashboard Versions HTTP API" +keywords = ["grafana", "http", "documentation", "api", "dashboard", "versions"] +aliases = ["/http_api/dashboardversions/"] +type = "docs" +[menu.docs] +name = "Dashboard Versions" +parent = "http_api" ++++ + +# Dashboard Versions + +## Get all dashboard versions + +Query parameters: + +- **limit** - Maximum number of results to return +- **start** - Version to start from when returning queries + +`GET /api/dashboards/id/:dashboardId/versions` + +Gets all existing dashboard versions for the dashboard with the given `dashboardId`. + +**Example request for getting all dashboard versions**: + +```http +GET /api/dashboards/id/1/versions?limit=2?start=0 HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +``` + +**Example Response** + +```http +HTTP/1.1 200 OK +Content-Type: application/json; charset=UTF-8 +Content-Length: 428 + +[ + { + "id": 2, + "dashboardId": 1, + "parentVersion": 1, + "restoredFrom": 0, + "version": 2, + "created": "2017-06-08T17:24:33-04:00", + "createdBy": "admin", + "message": "Updated panel title" + }, + { + "id": 1, + "dashboardId": 1, + "parentVersion": 0, + "restoredFrom": 0, + "version": 1, + "created": "2017-06-08T17:23:33-04:00", + "createdBy": "admin", + "message": "Initial save" + } +] +``` + +Status Codes: + +- **200** - Ok +- **400** - Errors +- **401** - Unauthorized +- **404** - Dashboard version not found + +## Get dashboard version + +`GET /api/dashboards/id/:dashboardId/versions/:id` + +Get the dashboard version with the given id, for the dashboard with the given id. + +**Example request for getting a dashboard version**: + +```http +GET /api/dashboards/id/1/versions/1 HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +``` + +**Example response**: + +```http +HTTP/1.1 200 OK +Content-Type: application/json; charset=UTF-8 +Content-Length: 1300 + +{ + "id": 1, + "dashboardId": 1, + "parentVersion": 0, + "restoredFrom": 0, + "version": 1, + "created": "2017-04-26T17:18:38-04:00", + "message": "Initial save", + "data": { + "annotations": { + "list": [ + + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": 1, + "links": [ + + ], + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + + ], + "templating": { + "list": [ + + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "test", + "version": 1 + }, + "createdBy": "admin" +} +``` + +Status Codes: + +- **200** - Ok +- **401** - Unauthorized +- **404** - Dashboard version not found + +## Restore dashboard + +`POST /api/dashboards/id/:dashboardId/restore` + +Restores a dashboard to a given dashboard version. + +**Example request for restoring a dashboard version**: + +```http +POST /api/dashboards/id/1/restore +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk + +{ + "version": 1 +} +``` + +JSON body schema: + +- **version** - The dashboard version to restore to + +**Example response**: + +```http +HTTP/1.1 200 OK +Content-Type: application/json; charset=UTF-8 +Content-Length: 67 + +{ + "slug": "my-dashboard", + "status": "success", + "version": 3 +} +``` + +JSON response body schema: + +- **slug** - the URL friendly slug of the dashboard's title +- **status** - whether the restoration was successful or not +- **version** - the new dashboard version, following the restoration + +Status codes: + +- **200** - OK +- **401** - Unauthorized +- **404** - Not found (dashboard not found or dashboard version not found) +- **500** - Internal server error (indicates issue retrieving dashboard tags from database) + +**Example error response** + +```http +HTTP/1.1 404 Not Found +Content-Type: application/json; charset=UTF-8 +Content-Length: 46 + +{ + "message": "Dashboard version not found" +} +``` + +JSON response body schema: + +- **message** - Message explaining the reason for the request failure. + +## Compare dashboard versions + +`POST /api/dashboards/calculate-diff` + +Compares two dashboard versions by calculating the JSON diff of them. + +**Example request**: + +```http +POST /api/dashboards/calculate-diff HTTP/1.1 +Accept: text/html +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk + +{ + "base": { + "dashboardId": 1, + "version": 1 + }, + "new": { + "dashboardId": 1, + "version": 2 + }, + "diffType": "json" +} +``` + +JSON body schema: + +- **base** - an object representing the base dashboard version +- **new** - an object representing the new dashboard version +- **diffType** - the type of diff to return. Can be "json" or "basic". + +**Example response (JSON diff)**: + +```http +HTTP/1.1 200 OK +Content-Type: text/html; charset=UTF-8 + +

    + +

    +``` + +The response is a textual respresentation of the diff, with the dashboard values being in JSON, similar to the diffs seen on sites like GitHub or GitLab. + +Status Codes: + +- **200** - Ok +- **400** - Bad request (invalid JSON sent) +- **401** - Unauthorized +- **404** - Not found + +**Example response (basic diff)**: + +```http +HTTP/1.1 200 OK +Content-Type: text/html; charset=UTF-8 + +
    + +
    +``` + +The response here is a summary of the changes, derived from the diff between the two JSON objects. + +Status Codes: + +- **200** - OK +- **400** - Bad request (invalid JSON sent) +- **401** - Unauthorized +- **404** - Not found diff --git a/docs/sources/reference/dashboard_history.md b/docs/sources/reference/dashboard_history.md new file mode 100644 index 00000000000..e21022e31ec --- /dev/null +++ b/docs/sources/reference/dashboard_history.md @@ -0,0 +1,40 @@ ++++ +title = "Dashboard Version History" +keywords = ["grafana", "dashboard", "documentation", "version", "history"] +type = "docs" +[menu.docs] +name = "Dashboard Version History" +parent = "dashboard_features" +weight = 100 ++++ + + +# Dashboard Version History + +Whenever you save a version of your dashboard, a copy of that version is saved so that previous versions of your dashboard are never lost. A list of these versions is available by clicking the dashboard menu dropdown, and clicking "Version history". + + + +The dashboard version history feature lets you compare and restore to previously saved dashboard versions. + +## Comparing two dashboard versions + +To compare two dashboard versions, select the two versions from the list that you wish to compare. Once selected, the "Compare versions" button will become clickable. Click the button to view the diff between the two versions. + + + +Upon clicking the button, you'll be brought to the diff view. By default, you'll see a textual summary of the changes, like in the image below. + + + +If you want to view the diff of the raw JSON that represents your dashboard, you can do that as well by clicking the "JSON Diff" tab on the left. + +If you want to restore to the version you're diffing against, you can do so by clicking the "Restore to version " button in the top right. + +## Restoring to a previouslty saved dashboard version + +If you need to restore to a previosuly saved dashboard version, you can do so by either clicking the "Restore" button on the right of a row in the dashboard version list, or by clicking the "Restore to version " button appearing in the diff view. Clicking the button will bring up the following popup prompting you to confirm the restoration. + + + +After restoring to a previous version, a new version will be created containing the same exact data as the previous version, only with a different version number. This is indicated in the "Notes column" for the row in the new dashboard version. This is done simply to ensure your previous dashboard versions aren't affected by the change. From 20a2334c87778bf6b208c27b91c783e23eca1681 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 3 Jul 2017 14:47:54 +0200 Subject: [PATCH 078/179] docs: spelling --- docs/sources/reference/dashboard_history.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sources/reference/dashboard_history.md b/docs/sources/reference/dashboard_history.md index e21022e31ec..0f91347ae65 100644 --- a/docs/sources/reference/dashboard_history.md +++ b/docs/sources/reference/dashboard_history.md @@ -29,12 +29,12 @@ Upon clicking the button, you'll be brought to the diff view. By default, you'll If you want to view the diff of the raw JSON that represents your dashboard, you can do that as well by clicking the "JSON Diff" tab on the left. -If you want to restore to the version you're diffing against, you can do so by clicking the "Restore to version " button in the top right. +If you want to restore to the version you are diffing against, you can do so by clicking the "Restore to version " button in the top right. -## Restoring to a previouslty saved dashboard version +## Restoring to a previously saved dashboard version -If you need to restore to a previosuly saved dashboard version, you can do so by either clicking the "Restore" button on the right of a row in the dashboard version list, or by clicking the "Restore to version " button appearing in the diff view. Clicking the button will bring up the following popup prompting you to confirm the restoration. +If you need to restore to a previously saved dashboard version, you can do so by either clicking the "Restore" button on the right of a row in the dashboard version list, or by clicking the "Restore to version " button appearing in the diff view. Clicking the button will bring up the following popup prompting you to confirm the restoration. -After restoring to a previous version, a new version will be created containing the same exact data as the previous version, only with a different version number. This is indicated in the "Notes column" for the row in the new dashboard version. This is done simply to ensure your previous dashboard versions aren't affected by the change. +After restoring to a previous version, a new version will be created containing the same exact data as the previous version, only with a different version number. This is indicated in the "Notes column" for the row in the new dashboard version. This is done simply to ensure your previous dashboard versions are not affected by the change. From a71423481bdfb24df0844a4fbd005abae79fb605 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 3 Jul 2017 18:07:51 +0200 Subject: [PATCH 079/179] changelog: update --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2e27dade77..4f6770a60e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ Pull Request: [#8472](https://github.com/grafana/grafana/pull/8472) * **Elasticsearch**: Added filter aggregation label [#8420](https://github.com/grafana/grafana/pull/8420), thx [@tianzk](github.com/tianzk) * **Sensu**: Added option for source and handler [#8405](https://github.com/grafana/grafana/pull/8405), thx [@joemiller](github.com/joemiller) * **CSV**: Configurable csv export datetime format [#8058](https://github.com/grafana/grafana/issues/8058), thx [@cederigo](github.com/cederigo) +* **Table Panel**: Column style that preserves formatting/indentation (like pre tag) [#6617](https://github.com/grafana/grafana/issues/6617) + +## Minor Enhancements + +* **Elasticsearch**: Add option for result set size in raw_document [#3426](https://github.com/grafana/grafana/issues/3426) [#8527](https://github.com/grafana/grafana/pull/8527), thx [@mk-dhia](github.com/mk-dhia) # 4.3.2 (2017-05-31) From 3ae5f7c632718b95e3e6e26408075288ad99e669 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 3 Jul 2017 20:40:37 +0200 Subject: [PATCH 080/179] docs: built-in variables, $__interval Fixes #8344. Documents the $__interval, $__interval_ms and $timeFilter variables. --- docs/sources/reference/templating.md | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/sources/reference/templating.md b/docs/sources/reference/templating.md index 0405251f44d..c6dfa9902bd 100644 --- a/docs/sources/reference/templating.md +++ b/docs/sources/reference/templating.md @@ -141,6 +141,42 @@ Use the `Interval` type to create a variable that represents a time span (eg. `1 This variable type is useful as a parameter to group by time (for InfluxDB), Date histogram interval (for Elasticsearch) or as a *summarize* function parameter (for Graphite). +Example using the template variable `myinterval` of type `Interval` in a graphite function: + +``` +summarize($myinterval, sum, false) +``` + +## Global Built-in Variables + +Grafana has global built-in variables that can be used in expressions in the query editor. + +### The $__interval Variable + +This $__interval variable is similar to the `auto` interval variable that is described above. It can be used as a parameter to group by time (for InfluxDB), Date histogram interval (for Elasticsearch) or as a *summarize* function parameter (for Graphite). + +Grafana automatically calculates an interval that can be used to group by time in queries. When there are more data points than can be shown on a graph then queries can be made more efficient by grouping by a larger interval. It is more efficient to group by 1 day than by 10s when looking at 3 months of data and the graph will look the same and the query will be faster. The `$__interval` is calculated using the time range and the width of the graph (the number of pixels). + +Approximate Calculation: `(from - to) / resolution` + +For example, when the time range is 1 hour and the graph is full screen, then the interval might be calculated to `2m` - points are grouped in 2 minute intervals. If the time range is 6 months and the graph is full screen, then the interval might be `1d` (1 day) - points are grouped by day. + +In the InfluxDB data source, the legacy variable `$interval` is the same variable. `$__interval` should be used instead. + +The InfluxDB and Elasticsearch data sources have `Group by time interval` fields that are used as the minimum limit for the `$__interval` variable. + +### The $__interval_ms Variable + +This variable is the `$__interval` variable in milliseconds (and not a time interval formatted string). For example, if the `$__interval` is `20m` then the `$__interval_ms` is `1200000`. + +### The $timeFilter or $__timeFilter Variable + +The `$timeFilter` variable returns the currently selected time range as an expression. For example, the time range interval `Last 7 days` expression is `time > now() - 7d`. + +This is used in the WHERE clause for the InfluxDB data source. Grafana adds it automatically to InfluxDB queries when in Query Editor Mode. It has to be added manually in Text Editor Mode: `WHERE $timeFilter`. + +The `$__timeFilter` is used in the MySQL data source. + ## Repeating Panels Template variables can be very useful to dynamically change your queries across a whole dashboard. If you want From a5afd8152d03a10ba8adeb1475872d3aaf9c1472 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 3 Jul 2017 21:32:12 +0200 Subject: [PATCH 081/179] docs: small update --- docs/sources/reference/templating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/reference/templating.md b/docs/sources/reference/templating.md index c6dfa9902bd..b2346903132 100644 --- a/docs/sources/reference/templating.md +++ b/docs/sources/reference/templating.md @@ -163,7 +163,7 @@ For example, when the time range is 1 hour and the graph is full screen, then th In the InfluxDB data source, the legacy variable `$interval` is the same variable. `$__interval` should be used instead. -The InfluxDB and Elasticsearch data sources have `Group by time interval` fields that are used as the minimum limit for the `$__interval` variable. +The InfluxDB and Elasticsearch data sources have `Group by time interval` fields that are used to hard code the interval or to set the minimum limit for the `$__interval` variable (by using the `>` syntax -> `>10m`). ### The $__interval_ms Variable From 109fd998edc26c167ea2a4213c780c1a7ac27eb7 Mon Sep 17 00:00:00 2001 From: Liang Jiameng Date: Tue, 4 Jul 2017 21:16:32 +0800 Subject: [PATCH 082/179] Add a new notifier : DingTalk (#8473) * add alerting notifier: DingDing * add alerting notifier: DingDing * add dingding unit test * add dingding unit test * delete debug code & format code style. * fix build failed: dingding_test.go --- pkg/metrics/metrics.go | 2 + pkg/services/alerting/notifiers/dingding.go | 90 +++++++++++++++++++ .../alerting/notifiers/dingding_test.go | 49 ++++++++++ 3 files changed, 141 insertions(+) create mode 100644 pkg/services/alerting/notifiers/dingding.go create mode 100644 pkg/services/alerting/notifiers/dingding_test.go diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index c23a53009a9..00354a00d03 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -44,6 +44,7 @@ var ( M_Alerting_Notification_Sent_Slack Counter M_Alerting_Notification_Sent_Email Counter M_Alerting_Notification_Sent_Webhook Counter + M_Alerting_Notification_Sent_DingDing Counter M_Alerting_Notification_Sent_PagerDuty Counter M_Alerting_Notification_Sent_LINE Counter M_Alerting_Notification_Sent_Victorops Counter @@ -116,6 +117,7 @@ func initMetricVars(settings *MetricSettings) { M_Alerting_Notification_Sent_Slack = RegCounter("alerting.notifications_sent", "type", "slack") M_Alerting_Notification_Sent_Email = RegCounter("alerting.notifications_sent", "type", "email") M_Alerting_Notification_Sent_Webhook = RegCounter("alerting.notifications_sent", "type", "webhook") + M_Alerting_Notification_Sent_DingDing = RegCounter("alerting.notifications_sent", "type", "dingding") M_Alerting_Notification_Sent_PagerDuty = RegCounter("alerting.notifications_sent", "type", "pagerduty") M_Alerting_Notification_Sent_Victorops = RegCounter("alerting.notifications_sent", "type", "victorops") M_Alerting_Notification_Sent_OpsGenie = RegCounter("alerting.notifications_sent", "type", "opsgenie") diff --git a/pkg/services/alerting/notifiers/dingding.go b/pkg/services/alerting/notifiers/dingding.go new file mode 100644 index 00000000000..ad5ccf554c3 --- /dev/null +++ b/pkg/services/alerting/notifiers/dingding.go @@ -0,0 +1,90 @@ +package notifiers + +import ( + "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/log" + "github.com/grafana/grafana/pkg/metrics" + m "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/alerting" +) + +func init() { + alerting.RegisterNotifier(&alerting.NotifierPlugin{ + Type: "dingding", + Name: "DingDing", + Description: "Sends HTTP POST request to DingDing", + Factory: NewDingDingNotifier, + OptionsTemplate: ` +

    DingDing settings

    +
    + Url + +
    + `, + }) + +} + +func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error) { + url := model.Settings.Get("url").MustString() + if url == "" { + return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} + } + + return &DingDingNotifier{ + NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings), + Url: url, + log: log.New("alerting.notifier.dingding"), + }, nil +} + +type DingDingNotifier struct { + NotifierBase + Url string + log log.Logger +} + +func (this *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { + this.log.Info("Sending dingding") + metrics.M_Alerting_Notification_Sent_DingDing.Inc(1) + + messageUrl, err := evalContext.GetRuleUrl() + if err != nil { + this.log.Error("Failed to get messageUrl", "error", err, "dingding", this.Name) + messageUrl = "" + } + this.log.Info("messageUrl:" + messageUrl) + + message := evalContext.Rule.Message + picUrl := evalContext.ImagePublicUrl + title := evalContext.GetNotificationTitle() + + bodyJSON, err := simplejson.NewJson([]byte(`{ + "msgtype": "link", + "link": { + "text": "` + message + `", + "title": "` + title + `", + "picUrl": "` + picUrl + `", + "messageUrl": "` + messageUrl + `" + } + }`)) + + if err != nil { + this.log.Error("Failed to create Json data", "error", err, "dingding", this.Name) + } + + body, _ := bodyJSON.MarshalJSON() + + cmd := &m.SendWebhookSync{ + Url: this.Url, + Body: string(body), + } + + if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil { + this.log.Error("Failed to send DingDing", "error", err, "dingding", this.Name) + return err + } + + return nil +} diff --git a/pkg/services/alerting/notifiers/dingding_test.go b/pkg/services/alerting/notifiers/dingding_test.go new file mode 100644 index 00000000000..3ca267dbf5b --- /dev/null +++ b/pkg/services/alerting/notifiers/dingding_test.go @@ -0,0 +1,49 @@ +package notifiers + +import ( + "testing" + + "github.com/grafana/grafana/pkg/components/simplejson" + m "github.com/grafana/grafana/pkg/models" + . "github.com/smartystreets/goconvey/convey" +) + +func TestDingDingNotifier(t *testing.T) { + Convey("Line notifier tests", t, func() { + Convey("empty settings should return error", func() { + json := `{ }` + + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "dingding_testing", + Type: "dingding", + Settings: settingsJSON, + } + + _, err := NewDingDingNotifier(model) + So(err, ShouldNotBeNil) + + }) + Convey("settings should trigger incident", func() { + json := ` + { + "url": "https://www.google.com" + }` + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "dingding_testing", + Type: "dingding", + Settings: settingsJSON, + } + + not, err := NewDingDingNotifier(model) + notifier := not.(*DingDingNotifier) + + So(err, ShouldBeNil) + So(notifier.Name, ShouldEqual, "dingding_testing") + So(notifier.Type, ShouldEqual, "dingding") + So(notifier.Url, ShouldEqual, "https://www.google.com") + }) + + }) +} From 205be91a842cb2c8ad8dbcf88ed917018ae2b79c Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 4 Jul 2017 15:25:44 +0200 Subject: [PATCH 083/179] changelog: note for DingDing notifier --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f6770a60e5..98460916156 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Pull Request: [#8472](https://github.com/grafana/grafana/pull/8472) * **Sensu**: Added option for source and handler [#8405](https://github.com/grafana/grafana/pull/8405), thx [@joemiller](github.com/joemiller) * **CSV**: Configurable csv export datetime format [#8058](https://github.com/grafana/grafana/issues/8058), thx [@cederigo](github.com/cederigo) * **Table Panel**: Column style that preserves formatting/indentation (like pre tag) [#6617](https://github.com/grafana/grafana/issues/6617) +* **DingDing**: Add DingDing Alert Notifier [#8473](https://github.com/grafana/grafana/pull/8473) thx [@jiamliang](https://github.com/jiamliang) ## Minor Enhancements From f773a9b4c368a4ba5f0e7c22be82ca7adf24e6f1 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 4 Jul 2017 21:17:43 +0200 Subject: [PATCH 084/179] docs: small change --- docs/sources/alerting/notifications.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/sources/alerting/notifications.md b/docs/sources/alerting/notifications.md index cd1316eb479..3119390b275 100644 --- a/docs/sources/alerting/notifications.md +++ b/docs/sources/alerting/notifications.md @@ -112,6 +112,8 @@ Grafana also supports the following Notification Channels: - LINE +- DingDing + # Enable images in notifications {#external-image-store} Grafana can render the panel associated with the alert rule and include that in the notification. Most Notification Channels require that this image be publicly accessable (Slack and PagerDuty for example). In order to include images in alert notifications, Grafana can upload the image to an image store. It currently supports From 74093c700f850cf43e68adb79c499a1abdb0fb66 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 4 Jul 2017 16:33:37 +0200 Subject: [PATCH 085/179] api: adds no-cache header for GET requests Fixes #5356. Internet Explorer aggressively caches GET requests which means that all API calls fetching data are cached. This fix adds a Cache-Control header with the value no-cache to all GET requests to the API. --- pkg/api/http_server.go | 2 ++ pkg/middleware/middleware.go | 8 ++++++++ pkg/middleware/middleware_test.go | 11 +++++++++++ 3 files changed, 21 insertions(+) diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index 0468b5cbe8a..4873062a933 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -171,6 +171,8 @@ func (hs *HttpServer) newMacaron() *macaron.Macaron { m.Use(middleware.ValidateHostHeader(setting.Domain)) } + m.Use(middleware.AddDefaultResponseHeaders()) + return m } diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go index 5aafe12d374..2a1d3e080a5 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -245,3 +245,11 @@ func (ctx *Context) HasHelpFlag(flag m.HelpFlags1) bool { func (ctx *Context) TimeRequest(timer metrics.Timer) { ctx.Data["perfmon.timer"] = timer } + +func AddDefaultResponseHeaders() macaron.Handler { + return func(ctx *Context) { + if ctx.IsApiRequest() && ctx.Req.Method == "GET" { + ctx.Resp.Header().Add("Cache-Control", "no-cache") + } + } +} diff --git a/pkg/middleware/middleware_test.go b/pkg/middleware/middleware_test.go index a1836a6744e..f18261e478d 100644 --- a/pkg/middleware/middleware_test.go +++ b/pkg/middleware/middleware_test.go @@ -30,6 +30,16 @@ func TestMiddlewareContext(t *testing.T) { So(sc.resp.Code, ShouldEqual, 200) }) + middlewareScenario("middleware should add Cache-Control header for GET requests to API", func(sc *scenarioContext) { + sc.fakeReq("GET", "/api/search").exec() + So(sc.resp.Header().Get("Cache-Control"), ShouldEqual, "no-cache") + }) + + middlewareScenario("middleware should not add Cache-Control header to for non-API GET requests", func(sc *scenarioContext) { + sc.fakeReq("GET", "/").exec() + So(sc.resp.Header().Get("Cache-Control"), ShouldBeEmpty) + }) + middlewareScenario("Non api request should init session", func(sc *scenarioContext) { sc.fakeReq("GET", "/").exec() So(sc.resp.Header().Get("Set-Cookie"), ShouldContainSubstring, "grafana_sess") @@ -327,6 +337,7 @@ func middlewareScenario(desc string, fn scenarioFunc) { startSessionGC = func() {} sc.m.Use(Sessioner(&session.Options{})) sc.m.Use(OrgRedirect()) + sc.m.Use(AddDefaultResponseHeaders()) sc.defaultHandler = func(c *Context) { sc.context = c From 1da98f5e1ec1c1cd26c9f648fd3ed4a208952b36 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 4 Jul 2017 21:48:39 +0200 Subject: [PATCH 086/179] Revert "Histogram fix (#8727)" This reverts commit 8634c9d457d6e624d762a476e817a401bebcf442. --- .../app/plugins/panel/graph/axes_editor.html | 6 ---- public/app/plugins/panel/graph/axes_editor.ts | 6 ---- public/app/plugins/panel/graph/graph.ts | 29 ++++------------- public/app/plugins/panel/graph/histogram.ts | 11 ++----- public/app/plugins/panel/graph/module.ts | 3 +- .../panel/graph/specs/histogram_specs.ts | 32 +++---------------- 6 files changed, 14 insertions(+), 73 deletions(-) diff --git a/public/app/plugins/panel/graph/axes_editor.html b/public/app/plugins/panel/graph/axes_editor.html index 1e577fe392e..b0ab759bf18 100644 --- a/public/app/plugins/panel/graph/axes_editor.html +++ b/public/app/plugins/panel/graph/axes_editor.html @@ -67,12 +67,6 @@
    -
    - -
    - -
    -
    diff --git a/public/app/plugins/panel/graph/axes_editor.ts b/public/app/plugins/panel/graph/axes_editor.ts index 155265e5987..adb3d1d6706 100644 --- a/public/app/plugins/panel/graph/axes_editor.ts +++ b/public/app/plugins/panel/graph/axes_editor.ts @@ -10,7 +10,6 @@ export class AxesEditorCtrl { xAxisModes: any; xAxisStatOptions: any; xNameSegment: any; - histogramValues: any; /** @ngInject **/ constructor(private $scope, private $q) { @@ -35,11 +34,6 @@ export class AxesEditorCtrl { // 'Data field': 'field', }; - this.histogramValues = { - 'Percent': 'percent', - 'Count': 'count' - }; - this.xAxisStatOptions = [ {text: 'Avg', value: 'avg'}, {text: 'Min', value: 'min'}, diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 8c928fb6a41..16d259c210e 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -312,13 +312,10 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { let histMax = _.max(_.map(data, s => s.stats.max)); let ticks = panel.xaxis.buckets || panelWidth / 50; bucketSize = tickStep(histMin, histMax, ticks); + let histogram = convertValuesToHistogram(values, bucketSize); - let normalize = panel.xaxis.histogramValue === 'percent'; - let histogram = convertValuesToHistogram(values, bucketSize, normalize); - - let seriesLabel = panel.xaxis.histogramValue || "count"; data[0].data = histogram; - data[0].alias = data[0].label = data[0].id = seriesLabel; + data[0].alias = data[0].label = data[0].id = "count"; data = [data[0]]; options.series.bars.barWidth = bucketSize * 0.8; @@ -425,32 +422,21 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { function addXHistogramAxis(options, bucketSize) { let ticks, min, max; - let defaultTicks = panelWidth / 50; if (data.length && bucketSize) { ticks = _.map(data[0].data, point => point[0]); - min = _.min(ticks); - max = _.max(ticks); - - // Adjust tick step - let tickStep = bucketSize; - let ticks_num = Math.floor((max - min) / tickStep); - while (ticks_num > defaultTicks) { - tickStep = tickStep * 2; - ticks_num = Math.ceil((max - min) / tickStep); - } // Expand ticks for pretty view - min = Math.floor(min / tickStep) * tickStep; - max = Math.ceil(max / tickStep) * tickStep; + min = Math.max(0, _.min(ticks) - bucketSize); + max = _.max(ticks) + bucketSize; ticks = []; - for (let i = min; i <= max; i += tickStep) { + for (let i = min; i <= max; i += bucketSize) { ticks.push(i); } } else { // Set defaults if no data - ticks = defaultTicks / 2; + ticks = panelWidth / 100; min = 0; max = 1; } @@ -464,9 +450,6 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { label: "Histogram", ticks: ticks }; - - // Use 'short' format for histogram values - configureAxisMode(options.xaxis, 'short'); } function addXTableAxis(options) { diff --git a/public/app/plugins/panel/graph/histogram.ts b/public/app/plugins/panel/graph/histogram.ts index efb13c546f0..e6ad7ebb0f6 100644 --- a/public/app/plugins/panel/graph/histogram.ts +++ b/public/app/plugins/panel/graph/histogram.ts @@ -26,7 +26,7 @@ export function getSeriesValues(data: any): number[] { * @param values * @param bucketSize */ -export function convertValuesToHistogram(values: number[], bucketSize: number, normalize = false): any[] { +export function convertValuesToHistogram(values: number[], bucketSize: number): any[] { let histogram = {}; for (let i = 0; i < values.length; i++) { @@ -38,16 +38,9 @@ export function convertValuesToHistogram(values: number[], bucketSize: number, n } } - let histogam_series = _.map(histogram, (count, bound) => { - if (normalize && values.length) { - return [Number(bound), count / values.length]; - } - + return _.map(histogram, (count, bound) => { return [Number(bound), count]; }); - - // Sort by Y axis values - return _.sortBy(histogam_series, point => point[0]); } function getBucketBound(value: number, bucketSize: number): number { diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index fed739a60d7..e9ca8c5c4e2 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -58,8 +58,7 @@ class GraphCtrl extends MetricsPanelCtrl { mode: 'time', name: null, values: [], - buckets: null, - histogramValue: 'percent' + buckets: null }, // show/hide lines lines : true, diff --git a/public/app/plugins/panel/graph/specs/histogram_specs.ts b/public/app/plugins/panel/graph/specs/histogram_specs.ts index 4d5ad02aec9..71b3def8d1d 100644 --- a/public/app/plugins/panel/graph/specs/histogram_specs.ts +++ b/public/app/plugins/panel/graph/specs/histogram_specs.ts @@ -1,6 +1,7 @@ /// -import _ from 'lodash'; + import { describe, beforeEach, it, expect } from '../../../../../test/lib/common'; + import { convertValuesToHistogram, getSeriesValues } from '../histogram'; describe('Graph Histogam Converter', function () { @@ -10,13 +11,13 @@ describe('Graph Histogam Converter', function () { let bucketSize = 10; beforeEach(() => { - values = [1, 2, 10, 11, 17, 20, 29, 30, 31, 33]; + values = [1, 2, 10, 11, 17, 20, 29]; }); it('Should convert to series-like array', () => { bucketSize = 10; let expected = [ - [0, 2], [10, 3], [20, 2], [30, 3] + [0, 2], [10, 3], [20, 2] ]; let histogram = convertValuesToHistogram(values, bucketSize); @@ -26,35 +27,12 @@ describe('Graph Histogam Converter', function () { it('Should not add empty buckets', () => { bucketSize = 5; let expected = [ - [0, 2], [10, 2], [15, 1], [20, 1], [25, 1], [30, 3] + [0, 2], [10, 2], [15, 1], [20, 1], [25, 1] ]; let histogram = convertValuesToHistogram(values, bucketSize); expect(histogram).to.eql(expected); }); - - it('Should normalize values', () => { - bucketSize = 5; - let normalize = true; - let expected = [ - [0, 0.2], [10, 0.2], [15, 0.1], [20, 0.1], [25, 0.1], [30, 0.3] - ]; - - let histogram = convertValuesToHistogram(values, bucketSize, normalize); - expect(histogram).to.eql(expected); - }); - - it('Sum of normalized values should be 1', () => { - bucketSize = 5; - let normalize = true; - let expected = [ - [0, 0.2], [10, 0.2], [15, 0.1], [20, 0.1], [25, 0.1], [30, 0.3] - ]; - - let histogram = convertValuesToHistogram(values, bucketSize, normalize); - let sum = _.reduce(histogram, (sum, point) => sum + point[1], 0); - expect(sum).to.eql(1); - }); }); describe('Series to values converter', () => { From c1c1bcb874a9ec639fdea2f30656f2f1fbf69c54 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 27 Jun 2017 17:42:21 +0300 Subject: [PATCH 087/179] histogram: don't cut negative values, issue #8628 --- public/app/plugins/panel/graph/graph.ts | 2 +- public/app/plugins/panel/graph/histogram.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 16d259c210e..c8d8fbfb25f 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -427,7 +427,7 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { ticks = _.map(data[0].data, point => point[0]); // Expand ticks for pretty view - min = Math.max(0, _.min(ticks) - bucketSize); + min = _.min(ticks) - bucketSize; max = _.max(ticks) + bucketSize; ticks = []; diff --git a/public/app/plugins/panel/graph/histogram.ts b/public/app/plugins/panel/graph/histogram.ts index e6ad7ebb0f6..c60782942f2 100644 --- a/public/app/plugins/panel/graph/histogram.ts +++ b/public/app/plugins/panel/graph/histogram.ts @@ -38,9 +38,12 @@ export function convertValuesToHistogram(values: number[], bucketSize: number): } } - return _.map(histogram, (count, bound) => { + let histogam_series = _.map(histogram, (count, bound) => { return [Number(bound), count]; }); + + // Sort by Y axis values + return _.sortBy(histogam_series, point => point[0]); } function getBucketBound(value: number, bucketSize: number): number { From 934c0fea6f10d8de61e76e77e66be47cce62399f Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Wed, 28 Jun 2017 11:03:36 +0300 Subject: [PATCH 088/179] histogram: improved ticks rendering --- public/app/plugins/panel/graph/graph.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index c8d8fbfb25f..ac75aa28754 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -422,21 +422,32 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { function addXHistogramAxis(options, bucketSize) { let ticks, min, max; + let defaultTicks = panelWidth / 50; if (data.length && bucketSize) { ticks = _.map(data[0].data, point => point[0]); + min = _.min(ticks); + max = _.max(ticks); + + // Adjust tick step + let tickStep = bucketSize; + let ticks_num = Math.floor((max - min) / tickStep); + while (ticks_num > defaultTicks) { + tickStep = tickStep * 2; + ticks_num = Math.ceil((max - min) / tickStep); + } // Expand ticks for pretty view - min = _.min(ticks) - bucketSize; - max = _.max(ticks) + bucketSize; + min = Math.floor(min / tickStep) * tickStep; + max = Math.ceil(max / tickStep) * tickStep; ticks = []; - for (let i = min; i <= max; i += bucketSize) { + for (let i = min; i <= max; i += tickStep) { ticks.push(i); } } else { // Set defaults if no data - ticks = panelWidth / 100; + ticks = defaultTicks / 2; min = 0; max = 1; } @@ -450,6 +461,9 @@ coreModule.directive('grafanaGraph', function($rootScope, timeSrv, popoverSrv) { label: "Histogram", ticks: ticks }; + + // Use 'short' format for histogram values + configureAxisMode(options.xaxis, 'short'); } function addXTableAxis(options) { From d20455ab5fe9876b93ef68d68f46ebd4256a1d51 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 4 Jul 2017 22:45:33 +0200 Subject: [PATCH 089/179] changelog: note for histogram fix --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98460916156..160c83b8f3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ Pull Request: [#8472](https://github.com/grafana/grafana/pull/8472) * **Elasticsearch**: Add option for result set size in raw_document [#3426](https://github.com/grafana/grafana/issues/3426) [#8527](https://github.com/grafana/grafana/pull/8527), thx [@mk-dhia](github.com/mk-dhia) +## Bug Fixes + +* **Graph**: Bug fix for negative values in histogram mode [#8628](https://github.com/grafana/grafana/issues/8628) + # 4.3.2 (2017-05-31) ## Bug fixes From 1940b33dc129ec43937e0f2ba27c9839220f3489 Mon Sep 17 00:00:00 2001 From: Jesse White Date: Tue, 4 Jul 2017 16:55:13 -0400 Subject: [PATCH 090/179] fix: handling of http errors without any data (#8777) --- public/app/core/services/backend_srv.ts | 2 +- public/test/specs/backend_srv-specs.js | 33 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 public/test/specs/backend_srv-specs.js diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index f4c32ab82b1..bffdfa05914 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -179,7 +179,7 @@ export class BackendSrv { } // for Prometheus - if (!err.data.message && _.isString(err.data.error)) { + if (err.data && !err.data.message && _.isString(err.data.error)) { err.data.message = err.data.error; } diff --git a/public/test/specs/backend_srv-specs.js b/public/test/specs/backend_srv-specs.js new file mode 100644 index 00000000000..a151fec3f14 --- /dev/null +++ b/public/test/specs/backend_srv-specs.js @@ -0,0 +1,33 @@ +define([ + 'app/core/config', + 'app/core/services/backend_srv' +], function() { + 'use strict'; + + describe('backend_srv', function() { + var _backendSrv; + var _http; + var _httpBackend; + + beforeEach(module('grafana.core')); + beforeEach(module('grafana.services')); + beforeEach(inject(function ($httpBackend, $http, backendSrv) { + _httpBackend = $httpBackend; + _http = $http; + _backendSrv = backendSrv; + })); + + describe('when handling errors', function() { + it('should return the http status code', function(done) { + _httpBackend.whenGET('gateway-error').respond(502); + _backendSrv.datasourceRequest({ + url: 'gateway-error' + }).catch(function(err) { + expect(err.status).to.be(502); + done(); + }); + _httpBackend.flush(); + }); + }); + }); +}); From 35830571551d956623d1a334d6c4942758edc5f3 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 4 Jul 2017 23:42:22 +0200 Subject: [PATCH 091/179] release: v4.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6524892f20a..6b410f041fb 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Coding Instinct AB" }, "name": "grafana", - "version": "4.4.0-pre1", + "version": "4.4.0", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git" From 36a1ab48c52d4a33464870ccbb40da098c8244a4 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Wed, 5 Jul 2017 01:15:42 +0200 Subject: [PATCH 092/179] packaging: updates for v4.4.0 --- README.md | 1 + docs/sources/guides/whats-new-in-v4-4.md | 50 ++++++++++++++++++++++++ docs/sources/installation/debian.md | 6 +-- docs/sources/installation/rpm.md | 10 ++--- docs/sources/installation/windows.md | 2 +- packaging/publish/publish_both.sh | 2 +- 6 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 docs/sources/guides/whats-new-in-v4-4.md diff --git a/README.md b/README.md index 9d2aabebbf3..41f777d5dec 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Graphite, Elasticsearch, OpenTSDB, Prometheus and InfluxDB. - [What's New in Grafana 4.1](http://docs.grafana.org/guides/whats-new-in-v4-1/) - [What's New in Grafana 4.2](http://docs.grafana.org/guides/whats-new-in-v4-2/) - [What's New in Grafana 4.3](http://docs.grafana.org/guides/whats-new-in-v4-3/) +- [What's New in Grafana 4.4](http://docs.grafana.org/guides/whats-new-in-v4-4/) ## Features diff --git a/docs/sources/guides/whats-new-in-v4-4.md b/docs/sources/guides/whats-new-in-v4-4.md new file mode 100644 index 00000000000..c091a1f7ef1 --- /dev/null +++ b/docs/sources/guides/whats-new-in-v4-4.md @@ -0,0 +1,50 @@ ++++ +title = "What's New in Grafana v4.4" +description = "Feature & improvement highlights for Grafana v4.4" +keywords = ["grafana", "new", "documentation", "4.4.0"] +type = "docs" +[menu.docs] +name = "Version 4.4" +identifier = "v4.4" +parent = "whatsnew" +weight = -2 ++++ + +## What's New in Grafana v4.4 + +Grafana v4.4 is now [available for download](https://grafana.com/grafana/download/4.4.0). + +**Highlights**: + +- Dashboard History - version control for dashboards. + +## New Features + +**Dashboard History**: View dashboard version history, compare any two versions (summary & json diffs), restore to old version. This big feature +was contributed by **Walmart Labs**. Big thanks to them for this massive contribution! +Initial feature request: [#4638](https://github.com/grafana/grafana/issues/4638) +Pull Request: [#8472](https://github.com/grafana/grafana/pull/8472) + +## Enhancements +* **Elasticsearch**: Added filter aggregation label [#8420](https://github.com/grafana/grafana/pull/8420), thx [@tianzk](github.com/tianzk) +* **Sensu**: Added option for source and handler [#8405](https://github.com/grafana/grafana/pull/8405), thx [@joemiller](github.com/joemiller) +* **CSV**: Configurable csv export datetime format [#8058](https://github.com/grafana/grafana/issues/8058), thx [@cederigo](github.com/cederigo) +* **Table Panel**: Column style that preserves formatting/indentation (like pre tag) [#6617](https://github.com/grafana/grafana/issues/6617) +* **DingDing**: Add DingDing Alert Notifier [#8473](https://github.com/grafana/grafana/pull/8473) thx [@jiamliang](https://github.com/jiamliang) + +## Minor Enhancements + +* **Elasticsearch**: Add option for result set size in raw_document [#3426](https://github.com/grafana/grafana/issues/3426) [#8527](https://github.com/grafana/grafana/pull/8527), thx [@mk-dhia](github.com/mk-dhia) + +## Bug Fixes + +* **Graph**: Bug fix for negative values in histogram mode [#8628](https://github.com/grafana/grafana/issues/8628) + +## Download + +Head to the [v4.4 download page](https://grafana.com/grafana/download) for download links & instructions. + +## Thanks + +A big thanks to all the Grafana users who contribute by submitting PRs, bug reports, helping out on our [community site](https://community.grafana.com/) and providing feedback! + diff --git a/docs/sources/installation/debian.md b/docs/sources/installation/debian.md index 5fde442afbf..fb21f76b599 100644 --- a/docs/sources/installation/debian.md +++ b/docs/sources/installation/debian.md @@ -15,7 +15,7 @@ weight = 1 Description | Download ------------ | ------------- -Stable for Debian-based Linux | [grafana_4.3.1_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.3.1_amd64.deb) +Stable for Debian-based Linux | [grafana_4.4.0_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.4.0_amd64.deb) Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing installation. @@ -23,9 +23,9 @@ installation. ## Install Stable ```bash -wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.3.1_amd64.deb +wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.4.0_amd64.deb sudo apt-get install -y adduser libfontconfig -sudo dpkg -i grafana_4.3.1_amd64.deb +sudo dpkg -i grafana_4.4.0_amd64.deb ``` `) -var reFullname = regexp.MustCompile(`\s*.+?<\/fullname?>\s*`) +var reFullnameBlock = regexp.MustCompile(`(.+?)<\/fullname>`) +var reFullname = regexp.MustCompile(`(.*?)`) var reExamples = regexp.MustCompile(`.+?<\/examples?>`) var reEndNL = regexp.MustCompile(`\n+$`) // docstring rewrites a string to insert godocs formatting. func docstring(doc string) string { + doc = strings.TrimSpace(doc) + if doc == "" { + return "" + } + doc = reNewline.ReplaceAllString(doc, "") doc = reMultiSpace.ReplaceAllString(doc, " ") doc = reComments.ReplaceAllString(doc, "") + + var fullname string + parts := reFullnameBlock.FindStringSubmatch(doc) + if len(parts) > 1 { + fullname = parts[1] + } + // Remove full name block from doc string doc = reFullname.ReplaceAllString(doc, "") + doc = reExamples.ReplaceAllString(doc, "") doc = generateDoc(doc) doc = reEndNL.ReplaceAllString(doc, "") - if doc == "" { - return "\n" + doc = html.UnescapeString(doc) + + // Replace doc with full name if doc is empty. + doc = strings.TrimSpace(doc) + if len(doc) == 0 { + doc = fullname } - doc = html.UnescapeString(doc) return commentify(doc) } @@ -116,16 +133,26 @@ var style = map[string]string{ // commentify converts a string to a Go comment func commentify(doc string) string { + if len(doc) == 0 { + return "" + } + lines := strings.Split(doc, "\n") - out := []string{} - for i, line := range lines { + out := make([]string, 0, len(lines)) + for i := 0; i < len(lines); i++ { + line := lines[i] + if i > 0 && line == "" && lines[i-1] == "" { continue } - out = append(out, "// "+line) + out = append(out, line) } - return strings.Join(out, "\n") + "\n" + if len(out) > 0 { + out[0] = "// " + out[0] + return strings.Join(out, "\n// ") + } + return "" } // wrap returns a rewritten version of text to have line breaks diff --git a/vendor/github.com/aws/aws-sdk-go/private/model/api/example.go b/vendor/github.com/aws/aws-sdk-go/private/model/api/example.go new file mode 100644 index 00000000000..ad790399076 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/model/api/example.go @@ -0,0 +1,318 @@ +// +build codegen + +package api + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "sort" + "strings" + "text/template" + + "github.com/aws/aws-sdk-go/private/util" +) + +type Examples map[string][]Example + +// ExamplesDefinition is the structural representation of the examples-1.json file +type ExamplesDefinition struct { + *API `json:"-"` + Examples Examples `json:"examples"` +} + +// Example is a single entry within the examples-1.json file. +type Example struct { + API *API `json:"-"` + Operation *Operation `json:"-"` + OperationName string `json:"-"` + Index string `json:"-"` + Builder examplesBuilder `json:"-"` + VisitedErrors map[string]struct{} `json:"-"` + Title string `json:"title"` + Description string `json:"description"` + ID string `json:"id"` + Comments Comments `json:"comments"` + Input map[string]interface{} `json:"input"` + Output map[string]interface{} `json:"output"` +} + +type Comments struct { + Input map[string]interface{} `json:"input"` + Output map[string]interface{} `json:"output"` +} + +var exampleFuncMap = template.FuncMap{ + "commentify": commentify, + "wrap": wrap, + "generateExampleInput": generateExampleInput, + "generateTypes": generateTypes, +} + +var exampleCustomizations = map[string]template.FuncMap{} + +var exampleTmpls = template.Must(template.New("example").Funcs(exampleFuncMap).Parse(` +{{ generateTypes . }} +{{ commentify (wrap .Title 80 false) }} +// +{{ commentify (wrap .Description 80 false) }} +func Example{{ .API.StructName }}_{{ .MethodName }}() { + svc := {{ .API.PackageName }}.New(session.New()) + input := &{{ .Operation.InputRef.Shape.GoTypeWithPkgNameElem }} { + {{ generateExampleInput . -}} + } + + result, err := svc.{{ .OperationName }}(input) + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + switch aerr.Code() { + {{ range $_, $ref := .Operation.ErrorRefs -}} + {{ if not ($.HasVisitedError $ref) -}} + case {{ .API.PackageName }}.{{ $ref.Shape.ErrorCodeName }}: + fmt.Println({{ .API.PackageName }}.{{ $ref.Shape.ErrorCodeName }}, aerr.Error()) + {{ end -}} + {{ end -}} + default: + fmt.Println(aerr.Error()) + } + } else { + // Print the error, cast err to awserr.Error to get the Code and + // Message from an error. + fmt.Println(err.Error()) + } + return + } + + fmt.Println(result) +} +`)) + +// Names will return the name of the example. This will also be the name of the operation +// that is to be tested. +func (exs Examples) Names() []string { + names := make([]string, 0, len(exs)) + for k := range exs { + names = append(names, k) + } + + sort.Strings(names) + return names +} + +func (exs Examples) GoCode() string { + buf := bytes.NewBuffer(nil) + for _, opName := range exs.Names() { + examples := exs[opName] + for _, ex := range examples { + buf.WriteString(util.GoFmt(ex.GoCode())) + buf.WriteString("\n") + } + } + return buf.String() +} + +// ExampleCode will generate the example code for the given Example shape. +// TODO: Can delete +func (ex Example) GoCode() string { + var buf bytes.Buffer + m := exampleFuncMap + if fMap, ok := exampleCustomizations[ex.API.PackageName()]; ok { + m = fMap + } + tmpl := exampleTmpls.Funcs(m) + if err := tmpl.ExecuteTemplate(&buf, "example", &ex); err != nil { + panic(err) + } + + return strings.TrimSpace(buf.String()) +} + +func generateExampleInput(ex Example) string { + if ex.Operation.HasInput() { + return ex.Builder.BuildShape(&ex.Operation.InputRef, ex.Input, false) + } + return "" +} + +// generateTypes will generate no types for default examples, but customizations may +// require their own defined types. +func generateTypes(ex Example) string { + return "" +} + +// correctType will cast the value to the correct type when printing the string. +// This is due to the json decoder choosing numbers to be floats, but the shape may +// actually be an int. To counter this, we pass the shape's type and properly do the +// casting here. +func correctType(memName string, t string, value interface{}) string { + if value == nil { + return "" + } + + v := "" + switch value.(type) { + case string: + v = value.(string) + case int: + v = fmt.Sprintf("%d", value.(int)) + case float64: + if t == "integer" || t == "long" || t == "int64" { + v = fmt.Sprintf("%d", int(value.(float64))) + } else { + v = fmt.Sprintf("%f", value.(float64)) + } + case bool: + v = fmt.Sprintf("%t", value.(bool)) + } + + return convertToCorrectType(memName, t, v) +} + +func convertToCorrectType(memName, t, v string) string { + return fmt.Sprintf("%s: %s,\n", memName, getValue(t, v)) +} + +func getValue(t, v string) string { + if t[0] == '*' { + t = t[1:] + } + switch t { + case "string": + return fmt.Sprintf("aws.String(%q)", v) + case "integer", "long", "int64": + return fmt.Sprintf("aws.Int64(%s)", v) + case "float", "float64", "double": + return fmt.Sprintf("aws.Float64(%s)", v) + case "boolean": + return fmt.Sprintf("aws.Bool(%s)", v) + default: + panic("Unsupported type: " + t) + } +} + +// AttachExamples will create a new ExamplesDefinition from the examples file +// and reference the API object. +func (a *API) AttachExamples(filename string) { + p := ExamplesDefinition{API: a} + + f, err := os.Open(filename) + defer f.Close() + if err != nil { + panic(err) + } + err = json.NewDecoder(f).Decode(&p) + if err != nil { + panic(err) + } + + p.setup() +} + +var examplesBuilderCustomizations = map[string]examplesBuilder{ + "wafregional": wafregionalExamplesBuilder{}, +} + +func (p *ExamplesDefinition) setup() { + var builder examplesBuilder + ok := false + if builder, ok = examplesBuilderCustomizations[p.API.PackageName()]; !ok { + builder = defaultExamplesBuilder{} + } + + keys := p.Examples.Names() + for _, n := range keys { + examples := p.Examples[n] + for i, e := range examples { + n = p.ExportableName(n) + e.OperationName = n + e.API = p.API + e.Index = fmt.Sprintf("shared%02d", i) + + e.Builder = builder + + e.VisitedErrors = map[string]struct{}{} + op := p.API.Operations[e.OperationName] + e.OperationName = p.ExportableName(e.OperationName) + e.Operation = op + p.Examples[n][i] = e + } + } + + p.API.Examples = p.Examples +} + +var exampleHeader = template.Must(template.New("exampleHeader").Parse(` +import ( + {{ .Builder.Imports .API }} +) + +var _ time.Duration +var _ strings.Reader +var _ aws.Config + +func parseTime(layout, value string) *time.Time { + t, err := time.Parse(layout, value) + if err != nil { + panic(err) + } + return &t +} + +`)) + +type exHeader struct { + Builder examplesBuilder + API *API +} + +// ExamplesGoCode will return a code representation of the entry within the +// examples.json file. +func (a *API) ExamplesGoCode() string { + var buf bytes.Buffer + var builder examplesBuilder + ok := false + if builder, ok = examplesBuilderCustomizations[a.PackageName()]; !ok { + builder = defaultExamplesBuilder{} + } + + if err := exampleHeader.ExecuteTemplate(&buf, "exampleHeader", &exHeader{builder, a}); err != nil { + panic(err) + } + + code := a.Examples.GoCode() + if len(code) == 0 { + return "" + } + + buf.WriteString(code) + return buf.String() +} + +// TODO: In the operation docuentation where we list errors, this needs to be done +// there as well. +func (ex *Example) HasVisitedError(errRef *ShapeRef) bool { + errName := errRef.Shape.ErrorCodeName() + _, ok := ex.VisitedErrors[errName] + ex.VisitedErrors[errName] = struct{}{} + return ok +} + +func parseTimeString(ref *ShapeRef, memName, v string) string { + if ref.Location == "header" { + return fmt.Sprintf("%s: parseTime(%q, %q),\n", memName, "Mon, 2 Jan 2006 15:04:05 GMT", v) + } else { + switch ref.API.Metadata.Protocol { + case "json", "rest-json": + return fmt.Sprintf("%s: parseTime(%q, %q),\n", memName, "2006-01-02T15:04:05Z", v) + case "rest-xml", "ec2", "query": + return fmt.Sprintf("%s: parseTime(%q, %q),\n", memName, "2006-01-02T15:04:05Z", v) + default: + panic("Unsupported time type: " + ref.API.Metadata.Protocol) + } + } +} + +func (ex *Example) MethodName() string { + return fmt.Sprintf("%s_%s", ex.OperationName, ex.Index) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/model/api/examples_builder.go b/vendor/github.com/aws/aws-sdk-go/private/model/api/examples_builder.go new file mode 100644 index 00000000000..eece69c806d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/model/api/examples_builder.go @@ -0,0 +1,256 @@ +// +build codegen + +package api + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strings" +) + +type examplesBuilder interface { + BuildShape(*ShapeRef, map[string]interface{}, bool) string + BuildList(string, string, *ShapeRef, []interface{}) string + BuildComplex(string, string, *ShapeRef, map[string]interface{}) string + Imports(*API) string +} + +type defaultExamplesBuilder struct{} + +// BuildShape will recursively build the referenced shape based on the json object +// provided. +// isMap will dictate how the field name is specified. If isMap is true, we will expect +// the member name to be quotes like "Foo". +func (builder defaultExamplesBuilder) BuildShape(ref *ShapeRef, shapes map[string]interface{}, isMap bool) string { + order := make([]string, len(shapes)) + for k := range shapes { + order = append(order, k) + } + sort.Strings(order) + + ret := "" + for _, name := range order { + if name == "" { + continue + } + shape := shapes[name] + + // If the shape isn't a map, we want to export the value, since every field + // defined in our shapes are exported. + if len(name) > 0 && !isMap && strings.ToLower(name[0:1]) == name[0:1] { + name = strings.Title(name) + } + + memName := name + if isMap { + memName = fmt.Sprintf("%q", memName) + } + + switch v := shape.(type) { + case map[string]interface{}: + ret += builder.BuildComplex(name, memName, ref, v) + case []interface{}: + ret += builder.BuildList(name, memName, ref, v) + default: + ret += builder.BuildScalar(name, memName, ref, v) + } + } + return ret +} + +// BuildList will construct a list shape based off the service's definition +// of that list. +func (builder defaultExamplesBuilder) BuildList(name, memName string, ref *ShapeRef, v []interface{}) string { + ret := "" + + if len(v) == 0 || ref == nil { + return "" + } + + t := "" + dataType := "" + format := "" + isComplex := false + passRef := ref + isMap := false + + if ref.Shape.MemberRefs[name] != nil { + t = builder.GoType(&ref.Shape.MemberRefs[name].Shape.MemberRef, false) + dataType = ref.Shape.MemberRefs[name].Shape.MemberRef.Shape.Type + passRef = ref.Shape.MemberRefs[name] + if dataType == "map" { + t = fmt.Sprintf("map[string]%s", builder.GoType(&ref.Shape.MemberRefs[name].Shape.MemberRef.Shape.ValueRef, false)) + passRef = &ref.Shape.MemberRefs[name].Shape.MemberRef.Shape.ValueRef + isMap = true + } + } else if ref.Shape.MemberRef.Shape != nil && ref.Shape.MemberRef.Shape.MemberRefs[name] != nil { + t = builder.GoType(&ref.Shape.MemberRef.Shape.MemberRefs[name].Shape.MemberRef, false) + dataType = ref.Shape.MemberRef.Shape.MemberRefs[name].Shape.MemberRef.Shape.Type + passRef = &ref.Shape.MemberRef.Shape.MemberRefs[name].Shape.MemberRef + } else { + t = builder.GoType(&ref.Shape.MemberRef, false) + dataType = ref.Shape.MemberRef.Shape.Type + passRef = &ref.Shape.MemberRef + } + + switch v[0].(type) { + case string: + format = "%s" + case bool: + format = "%t" + case float64: + if dataType == "integer" || dataType == "int64" { + format = "%d" + } else { + format = "%f" + } + default: + if ref.Shape.MemberRefs[name] != nil { + } else { + passRef = ref.Shape.MemberRef.Shape.MemberRefs[name] + + // if passRef is nil that means we are either in a map or within a nested array + if passRef == nil { + passRef = &ref.Shape.MemberRef + } + } + isComplex = true + } + ret += fmt.Sprintf("%s: []%s {\n", memName, t) + for _, elem := range v { + if isComplex { + ret += fmt.Sprintf("{\n%s\n},\n", builder.BuildShape(passRef, elem.(map[string]interface{}), isMap)) + } else { + if dataType == "integer" || dataType == "int64" || dataType == "long" { + elem = int(elem.(float64)) + } + ret += fmt.Sprintf("%s,\n", getValue(t, fmt.Sprintf(format, elem))) + } + } + ret += "},\n" + return ret +} + +// BuildScalar will build atomic Go types. +func (builder defaultExamplesBuilder) BuildScalar(name, memName string, ref *ShapeRef, shape interface{}) string { + if ref == nil || ref.Shape == nil { + return "" + } else if ref.Shape.MemberRefs[name] == nil { + if ref.Shape.MemberRef.Shape != nil && ref.Shape.MemberRef.Shape.MemberRefs[name] != nil { + return correctType(memName, ref.Shape.MemberRef.Shape.MemberRefs[name].Shape.Type, shape) + } + if ref.Shape.Type != "structure" && ref.Shape.Type != "map" { + return correctType(memName, ref.Shape.Type, shape) + } + return "" + } + + switch v := shape.(type) { + case bool: + return convertToCorrectType(memName, ref.Shape.MemberRefs[name].Shape.Type, fmt.Sprintf("%t", v)) + case int: + if ref.Shape.MemberRefs[name].Shape.Type == "timestamp" { + return parseTimeString(ref, memName, fmt.Sprintf("%d", v)) + } + return convertToCorrectType(memName, ref.Shape.MemberRefs[name].Shape.Type, fmt.Sprintf("%d", v)) + case float64: + dataType := ref.Shape.MemberRefs[name].Shape.Type + if dataType == "integer" || dataType == "int64" || dataType == "long" { + return convertToCorrectType(memName, ref.Shape.MemberRefs[name].Shape.Type, fmt.Sprintf("%d", int(shape.(float64)))) + } + return convertToCorrectType(memName, ref.Shape.MemberRefs[name].Shape.Type, fmt.Sprintf("%f", v)) + case string: + t := ref.Shape.MemberRefs[name].Shape.Type + switch t { + case "timestamp": + return parseTimeString(ref, memName, fmt.Sprintf("%s", v)) + case "blob": + if (ref.Shape.MemberRefs[name].Streaming || ref.Shape.MemberRefs[name].Shape.Streaming) && ref.Shape.Payload == name { + return fmt.Sprintf("%s: aws.ReadSeekCloser(strings.NewReader(%q)),\n", memName, v) + } + + return fmt.Sprintf("%s: []byte(%q),\n", memName, v) + default: + return convertToCorrectType(memName, t, v) + } + default: + panic(fmt.Errorf("Unsupported scalar type: %v", reflect.TypeOf(v))) + } + return "" +} + +func (builder defaultExamplesBuilder) BuildComplex(name, memName string, ref *ShapeRef, v map[string]interface{}) string { + t := "" + if ref == nil { + return builder.BuildShape(nil, v, true) + } + + member := ref.Shape.MemberRefs[name] + + if member != nil && member.Shape != nil { + t = ref.Shape.MemberRefs[name].Shape.Type + } else { + t = ref.Shape.Type + } + + switch t { + case "structure": + passRef := ref.Shape.MemberRefs[name] + // passRef will be nil if the entry is a map. In that case + // we want to pass the reference, because the previous call + // passed the value reference. + if passRef == nil { + passRef = ref + } + return fmt.Sprintf(`%s: &%s{ + %s + }, + `, memName, builder.GoType(passRef, true), builder.BuildShape(passRef, v, false)) + case "map": + return fmt.Sprintf(`%s: %s{ + %s + }, + `, name, builder.GoType(ref.Shape.MemberRefs[name], false), builder.BuildShape(&ref.Shape.MemberRefs[name].Shape.ValueRef, v, true)) + } + + return "" +} + +func (builder defaultExamplesBuilder) GoType(ref *ShapeRef, elem bool) string { + prefix := "" + if ref.Shape.Type == "list" { + ref = &ref.Shape.MemberRef + prefix = "[]*" + } + + name := ref.GoTypeWithPkgName() + if elem { + name = ref.GoTypeElem() + if !strings.Contains(name, ".") { + name = strings.Join([]string{ref.API.PackageName(), name}, ".") + } + } + + if ref.Shape.Type != "structure" && ref.Shape.Type != "list" { + return name + } + + return prefix + name +} + +func (builder defaultExamplesBuilder) Imports(a *API) string { + buf := bytes.NewBuffer(nil) + buf.WriteString(`"fmt" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/session" + `) + + buf.WriteString(fmt.Sprintf("\"%s/%s\"", "github.com/aws/aws-sdk-go/service", a.PackageName())) + return buf.String() +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/model/api/examples_builder_customizations.go b/vendor/github.com/aws/aws-sdk-go/private/model/api/examples_builder_customizations.go new file mode 100644 index 00000000000..058e999cb1f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/model/api/examples_builder_customizations.go @@ -0,0 +1,28 @@ +// +build codegen + +package api + +import ( + "bytes" + "fmt" +) + +type wafregionalExamplesBuilder struct { + defaultExamplesBuilder +} + +func (builder wafregionalExamplesBuilder) Imports(a *API) string { + buf := bytes.NewBuffer(nil) + buf.WriteString(`"fmt" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/waf" + `) + + buf.WriteString(fmt.Sprintf("\"%s/%s\"", "github.com/aws/aws-sdk-go/service", a.PackageName())) + return buf.String() +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/model/api/shape.go b/vendor/github.com/aws/aws-sdk-go/private/model/api/shape.go index f42521c2911..dd0fbee55af 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/model/api/shape.go +++ b/vendor/github.com/aws/aws-sdk-go/private/model/api/shape.go @@ -33,6 +33,8 @@ type ShapeRef struct { Deprecated bool `json:"deprecated"` OrigShapeName string `json:"-"` + + GenerateGetter bool } // ErrorInfo represents the error block of a shape's structure @@ -145,6 +147,14 @@ func (s *Shape) GoTypeWithPkgName() string { return goType(s, true) } +func (s *Shape) GoTypeWithPkgNameElem() string { + t := goType(s, true) + if strings.HasPrefix(t, "*") { + return t[1:] + } + return t +} + // GenAccessors returns if the shape's reference should have setters generated. func (s *ShapeRef) UseIndirection() bool { switch s.Shape.Type { @@ -244,11 +254,11 @@ func goType(s *Shape, withPkgName bool) string { } return "*" + s.ShapeName case "map": - return "map[string]" + s.ValueRef.GoType() + return "map[string]" + goType(s.ValueRef.Shape, withPkgName) case "jsonvalue": return "aws.JSONValue" case "list": - return "[]" + s.MemberRef.GoType() + return "[]" + goType(s.MemberRef.Shape, withPkgName) case "boolean": return "*bool" case "string", "character": @@ -392,16 +402,18 @@ func (ref *ShapeRef) GoTags(toplevel bool, isRequired bool) string { if ref.Shape.Payload != "" { tags = append(tags, ShapeTag{"payload", ref.Shape.Payload}) } - if ref.XMLNamespace.Prefix != "" { - tags = append(tags, ShapeTag{"xmlPrefix", ref.XMLNamespace.Prefix}) - } else if ref.Shape.XMLNamespace.Prefix != "" { - tags = append(tags, ShapeTag{"xmlPrefix", ref.Shape.XMLNamespace.Prefix}) - } - if ref.XMLNamespace.URI != "" { - tags = append(tags, ShapeTag{"xmlURI", ref.XMLNamespace.URI}) - } else if ref.Shape.XMLNamespace.URI != "" { - tags = append(tags, ShapeTag{"xmlURI", ref.Shape.XMLNamespace.URI}) - } + } + + if ref.XMLNamespace.Prefix != "" { + tags = append(tags, ShapeTag{"xmlPrefix", ref.XMLNamespace.Prefix}) + } else if ref.Shape.XMLNamespace.Prefix != "" { + tags = append(tags, ShapeTag{"xmlPrefix", ref.Shape.XMLNamespace.Prefix}) + } + + if ref.XMLNamespace.URI != "" { + tags = append(tags, ShapeTag{"xmlURI", ref.XMLNamespace.URI}) + } else if ref.Shape.XMLNamespace.URI != "" { + tags = append(tags, ShapeTag{"xmlURI", ref.Shape.XMLNamespace.URI}) } if ref.IdempotencyToken || ref.Shape.IdempotencyToken { @@ -521,14 +533,23 @@ type {{ .ShapeName }} struct { {{ range $_, $name := $context.MemberNames -}} {{ $elem := index $context.MemberRefs $name -}} + {{ $isBlob := $context.WillRefBeBase64Encoded $name -}} {{ $isRequired := $context.IsRequired $name -}} {{ $doc := $elem.Docstring -}} - {{ $doc }} - {{ if $isRequired -}} + {{ if $doc -}} + {{ $doc }} + {{ end -}} + {{ if $isBlob -}} {{ if $doc -}} // {{ end -}} + // {{ $name }} is automatically base64 encoded/decoded by the SDK. + {{ end -}} + {{ if $isRequired -}} + {{ if or $doc $isBlob -}} + // + {{ end -}} // {{ $name }} is a required field {{ end -}} {{ $name }} {{ $context.GoStructType $name $elem }} {{ $elem.GoTags false $isRequired }} @@ -561,6 +582,19 @@ func (s *{{ $builderShapeName }}) Set{{ $name }}(v {{ $context.GoStructValueType return s } +{{ if $elem.GenerateGetter -}} +func (s *{{ $builderShapeName }}) get{{ $name }}() (v {{ $context.GoStructValueType $name $elem }}) { + {{ if $elem.UseIndirection -}} + if s.{{ $name }} == nil { + return v + } + return *s.{{ $name }} + {{ else -}} + return s.{{ $name }} + {{ end -}} +} +{{- end }} + {{ end }} {{ end }} `)) @@ -634,3 +668,17 @@ func (s *Shape) removeRef(ref *ShapeRef) { } } } + +func (s *Shape) WillRefBeBase64Encoded(refName string) bool { + payloadRefName := s.Payload + if payloadRefName == refName { + return false + } + + ref, ok := s.MemberRefs[refName] + if !ok { + panic(fmt.Sprintf("shape %s does not contain %q refName", s.ShapeName, refName)) + } + + return ref.Shape.Type == "blob" +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/model/cli/gen-api/main.go b/vendor/github.com/aws/aws-sdk-go/private/model/cli/gen-api/main.go index a0d549fffe9..005a74d6adc 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/model/cli/gen-api/main.go +++ b/vendor/github.com/aws/aws-sdk-go/private/model/cli/gen-api/main.go @@ -62,6 +62,20 @@ func newGenerateInfo(modelFile, svcPath, svcImportPath string) *generateInfo { fmt.Println("waiters-2.json error:", err) } + examplesFile := strings.Replace(modelFile, "api-2.json", "examples-1.json", -1) + if _, err := os.Stat(examplesFile); err == nil { + g.API.AttachExamples(examplesFile) + } else if !os.IsNotExist(err) { + fmt.Println("examples-1.json error:", err) + } + + // pkgDocAddonsFile := strings.Replace(modelFile, "api-2.json", "go-pkg-doc.gotmpl", -1) + // if _, err := os.Stat(pkgDocAddonsFile); err == nil { + // g.API.AttachPackageDocAddons(pkgDocAddonsFile) + // } else if !os.IsNotExist(err) { + // fmt.Println("go-pkg-doc.gotmpl error:", err) + // } + g.API.Setup() if svc := os.Getenv("SERVICES"); svc != "" { @@ -175,13 +189,14 @@ func writeServiceFiles(g *generateInfo, filename string) { fmt.Printf("Generating %s (%s)...\n", g.API.PackageName(), g.API.Metadata.APIVersion) - // write api.go and service.go files + // write files for service client and API + Must(writeServiceDocFile(g)) Must(writeAPIFile(g)) - Must(writeExamplesFile(g)) Must(writeServiceFile(g)) Must(writeInterfaceFile(g)) Must(writeWaitersFile(g)) Must(writeAPIErrorsFile(g)) + Must(writeExamplesFile(g)) } // Must will panic if the error passed in is not nil. @@ -192,6 +207,7 @@ func Must(err error) { } const codeLayout = `// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + %s package %s @@ -202,14 +218,28 @@ func writeGoFile(file string, layout string, args ...interface{}) error { return ioutil.WriteFile(file, []byte(util.GoFmt(fmt.Sprintf(layout, args...))), 0664) } +// writeServiceDocFile generates the documentation for service package. +func writeServiceDocFile(g *generateInfo) error { + return writeGoFile(filepath.Join(g.PackageDir, "doc.go"), + codeLayout, + strings.TrimSpace(g.API.ServicePackageDoc()), + g.API.PackageName(), + "", + ) +} + // writeExamplesFile writes out the service example file. func writeExamplesFile(g *generateInfo) error { - return writeGoFile(filepath.Join(g.PackageDir, "examples_test.go"), - codeLayout, - "", - g.API.PackageName()+"_test", - g.API.ExampleGoCode(), - ) + code := g.API.ExamplesGoCode() + if len(code) > 0 { + return writeGoFile(filepath.Join(g.PackageDir, "examples_test.go"), + codeLayout, + "", + g.API.PackageName()+"_test", + code, + ) + } + return nil } // writeServiceFile writes out the service initialization file. @@ -252,18 +282,17 @@ func writeWaitersFile(g *generateInfo) error { ) } -// writeAPIFile writes out the service api file. +// writeAPIFile writes out the service API file. func writeAPIFile(g *generateInfo) error { return writeGoFile(filepath.Join(g.PackageDir, "api.go"), codeLayout, - fmt.Sprintf("\n// Package %s provides a client for %s.", - g.API.PackageName(), g.API.Metadata.ServiceFullName), + "", g.API.PackageName(), g.API.APIGoCode(), ) } -// writeAPIErrorsFile writes out the service api errors file. +// writeAPIErrorsFile writes out the service API errors file. func writeAPIErrorsFile(g *generateInfo) error { return writeGoFile(filepath.Join(g.PackageDir, "errors.go"), codeLayout, diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go index c74c191967a..7091b456d18 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go @@ -131,7 +131,6 @@ func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag refl continue } - mTag := field.Tag if mTag.Get("location") != "" { // skip non-body members continue diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go index 64b6ddd3e18..87584628a2b 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go @@ -15,7 +15,10 @@ import ( // needs to match the shape of the XML expected to be decoded. // If the shape doesn't match unmarshaling will fail. func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { - n, _ := XMLToStruct(d, nil) + n, err := XMLToStruct(d, nil) + if err != nil { + return err + } if n.Children != nil { for _, root := range n.Children { for _, c := range root { @@ -23,7 +26,7 @@ func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { c = wrappedChild[0] // pull out wrapped element } - err := parse(reflect.ValueOf(v), c, "") + err = parse(reflect.ValueOf(v), c, "") if err != nil { if err == io.EOF { return nil diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go index 3112512a210..3e970b629da 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go @@ -40,11 +40,16 @@ func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) { out := &XMLNode{} for { tok, err := d.Token() - if tok == nil || err == io.EOF { - break - } if err != nil { - return out, err + if err == io.EOF { + break + } else { + return out, err + } + } + + if tok == nil { + break } switch typed := tok.(type) { diff --git a/vendor/github.com/aws/aws-sdk-go/sdk.go b/vendor/github.com/aws/aws-sdk-go/sdk.go deleted file mode 100644 index afa465a2255..00000000000 --- a/vendor/github.com/aws/aws-sdk-go/sdk.go +++ /dev/null @@ -1,7 +0,0 @@ -// Package sdk is the official AWS SDK for the Go programming language. -// -// See our Developer Guide for information for on getting started and using -// the SDK. -// -// https://github.com/aws/aws-sdk-go/wiki -package sdk diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/api.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/api.go index 917da5aa38a..4a9d1406ed4 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/api.go @@ -1,6 +1,5 @@ // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. -// Package cloudwatch provides a client for Amazon CloudWatch. package cloudwatch import ( @@ -96,6 +95,93 @@ func (c *CloudWatch) DeleteAlarmsWithContext(ctx aws.Context, input *DeleteAlarm return out, req.Send() } +const opDeleteDashboards = "DeleteDashboards" + +// DeleteDashboardsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteDashboards operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See DeleteDashboards for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteDashboards method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteDashboardsRequest method. +// req, resp := client.DeleteDashboardsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteDashboards +func (c *CloudWatch) DeleteDashboardsRequest(input *DeleteDashboardsInput) (req *request.Request, output *DeleteDashboardsOutput) { + op := &request.Operation{ + Name: opDeleteDashboards, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteDashboardsInput{} + } + + output = &DeleteDashboardsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteDashboards API operation for Amazon CloudWatch. +// +// Deletes all dashboards that you specify. You may specify up to 100 dashboards +// to delete. If there is an error during this call, no dashboards are deleted. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon CloudWatch's +// API operation DeleteDashboards for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidParameterValueException "InvalidParameterValue" +// The value of an input parameter is bad or out-of-range. +// +// * ErrCodeDashboardNotFoundError "ResourceNotFound" +// The specified dashboard does not exist. +// +// * ErrCodeInternalServiceFault "InternalServiceError" +// Request processing has failed due to some unknown error, exception, or failure. +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteDashboards +func (c *CloudWatch) DeleteDashboards(input *DeleteDashboardsInput) (*DeleteDashboardsOutput, error) { + req, out := c.DeleteDashboardsRequest(input) + return out, req.Send() +} + +// DeleteDashboardsWithContext is the same as DeleteDashboards with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteDashboards for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatch) DeleteDashboardsWithContext(ctx aws.Context, input *DeleteDashboardsInput, opts ...request.Option) (*DeleteDashboardsOutput, error) { + req, out := c.DeleteDashboardsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeAlarmHistory = "DescribeAlarmHistory" // DescribeAlarmHistoryRequest generates a "aws/request.Request" representing the @@ -151,8 +237,7 @@ func (c *CloudWatch) DescribeAlarmHistoryRequest(input *DescribeAlarmHistoryInpu // by date range or item type. If an alarm name is not specified, the histories // for all alarms are returned. // -// Note that Amazon CloudWatch retains the history of an alarm even if you delete -// the alarm. +// CloudWatch retains the history of an alarm even if you delete the alarm. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -420,8 +505,8 @@ func (c *CloudWatch) DescribeAlarmsForMetricRequest(input *DescribeAlarmsForMetr // DescribeAlarmsForMetric API operation for Amazon CloudWatch. // -// Retrieves the alarms for the specified metric. Specify a statistic, period, -// or unit to filter the results. +// Retrieves the alarms for the specified metric. To filter the results, specify +// a statistic, period, or unit. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -606,6 +691,96 @@ func (c *CloudWatch) EnableAlarmActionsWithContext(ctx aws.Context, input *Enabl return out, req.Send() } +const opGetDashboard = "GetDashboard" + +// GetDashboardRequest generates a "aws/request.Request" representing the +// client's request for the GetDashboard operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See GetDashboard for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the GetDashboard method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the GetDashboardRequest method. +// req, resp := client.GetDashboardRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetDashboard +func (c *CloudWatch) GetDashboardRequest(input *GetDashboardInput) (req *request.Request, output *GetDashboardOutput) { + op := &request.Operation{ + Name: opGetDashboard, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDashboardInput{} + } + + output = &GetDashboardOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDashboard API operation for Amazon CloudWatch. +// +// Displays the details of the dashboard that you specify. +// +// To copy an existing dashboard, use GetDashboard, and then use the data returned +// within DashboardBody as the template for the new dashboard when you call +// PutDashboard to create the copy. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon CloudWatch's +// API operation GetDashboard for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidParameterValueException "InvalidParameterValue" +// The value of an input parameter is bad or out-of-range. +// +// * ErrCodeDashboardNotFoundError "ResourceNotFound" +// The specified dashboard does not exist. +// +// * ErrCodeInternalServiceFault "InternalServiceError" +// Request processing has failed due to some unknown error, exception, or failure. +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetDashboard +func (c *CloudWatch) GetDashboard(input *GetDashboardInput) (*GetDashboardOutput, error) { + req, out := c.GetDashboardRequest(input) + return out, req.Send() +} + +// GetDashboardWithContext is the same as GetDashboard with the addition of +// the ability to pass a context and additional request options. +// +// See GetDashboard for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatch) GetDashboardWithContext(ctx aws.Context, input *GetDashboardInput, opts ...request.Option) (*GetDashboardOutput, error) { + req, out := c.GetDashboardRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opGetMetricStatistics = "GetMetricStatistics" // GetMetricStatisticsRequest generates a "aws/request.Request" representing the @@ -653,43 +828,54 @@ func (c *CloudWatch) GetMetricStatisticsRequest(input *GetMetricStatisticsInput) // // Gets statistics for the specified metric. // -// Amazon CloudWatch retains metric data as follows: -// -// * Data points with a period of 60 seconds (1 minute) are available for -// 15 days -// -// * Data points with a period of 300 seconds (5 minute) are available for -// 63 days -// -// * Data points with a period of 3600 seconds (1 hour) are available for -// 455 days (15 months) -// -// Note that CloudWatch started retaining 5-minute and 1-hour metric data as -// of 9 July 2016. -// // The maximum number of data points returned from a single call is 1,440. If -// you request more than 1,440 data points, Amazon CloudWatch returns an error. -// To reduce the number of data points, you can narrow the specified time range +// you request more than 1,440 data points, CloudWatch returns an error. To +// reduce the number of data points, you can narrow the specified time range // and make multiple requests across adjacent time ranges, or you can increase -// the specified period. A period can be as short as one minute (60 seconds). -// Note that data points are not returned in chronological order. +// the specified period. Data points are not returned in chronological order. // -// Amazon CloudWatch aggregates data points based on the length of the period -// that you specify. For example, if you request statistics with a one-hour -// period, Amazon CloudWatch aggregates all data points with time stamps that -// fall within each one-hour period. Therefore, the number of values aggregated -// by CloudWatch is larger than the number of data points returned. +// CloudWatch aggregates data points based on the length of the period that +// you specify. For example, if you request statistics with a one-hour period, +// CloudWatch aggregates all data points with time stamps that fall within each +// one-hour period. Therefore, the number of values aggregated by CloudWatch +// is larger than the number of data points returned. // // CloudWatch needs raw data points to calculate percentile statistics. If you -// publish data using a statistic set instead, you cannot retrieve percentile -// statistics for this data unless one of the following conditions is true: +// publish data using a statistic set instead, you can only retrieve percentile +// statistics for this data if one of the following conditions is true: // -// * The SampleCount of the statistic set is 1 +// * The SampleCount value of the statistic set is 1. // -// * The Min and the Max of the statistic set are equal +// * The Min and the Max values of the statistic set are equal. // -// For a list of metrics and dimensions supported by AWS services, see the Amazon -// CloudWatch Metrics and Dimensions Reference (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CW_Support_For_AWS.html) +// Amazon CloudWatch retains metric data as follows: +// +// * Data points with a period of less than 60 seconds are available for +// 3 hours. These data points are high-resolution metrics and are available +// only for custom metrics that have been defined with a StorageResolution +// of 1. +// +// * Data points with a period of 60 seconds (1-minute) are available for +// 15 days. +// +// * Data points with a period of 300 seconds (5-minute) are available for +// 63 days. +// +// * Data points with a period of 3600 seconds (1 hour) are available for +// 455 days (15 months). +// +// Data points that are initially published with a shorter period are aggregated +// together for long-term storage. For example, if you collect data using a +// period of 1 minute, the data remains available for 15 days with 1-minute +// resolution. After 15 days, this data is still available, but is aggregated +// and retrievable only with a resolution of 5 minutes. After 63 days, the data +// is further aggregated and is available with a resolution of 1 hour. +// +// CloudWatch started retaining 5-minute and 1-hour metric data as of July 9, +// 2016. +// +// For information about metrics and dimensions supported by AWS services, see +// the Amazon CloudWatch Metrics and Dimensions Reference (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CW_Support_For_AWS.html) // in the Amazon CloudWatch User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -707,7 +893,7 @@ func (c *CloudWatch) GetMetricStatisticsRequest(input *GetMetricStatisticsInput) // An input parameter that is required is missing. // // * ErrCodeInvalidParameterCombinationException "InvalidParameterCombination" -// Parameters that cannot be used together were used together. +// Parameters were used together that cannot be used together. // // * ErrCodeInternalServiceFault "InternalServiceError" // Request processing has failed due to some unknown error, exception, or failure. @@ -734,6 +920,91 @@ func (c *CloudWatch) GetMetricStatisticsWithContext(ctx aws.Context, input *GetM return out, req.Send() } +const opListDashboards = "ListDashboards" + +// ListDashboardsRequest generates a "aws/request.Request" representing the +// client's request for the ListDashboards operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See ListDashboards for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the ListDashboards method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the ListDashboardsRequest method. +// req, resp := client.ListDashboardsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListDashboards +func (c *CloudWatch) ListDashboardsRequest(input *ListDashboardsInput) (req *request.Request, output *ListDashboardsOutput) { + op := &request.Operation{ + Name: opListDashboards, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ListDashboardsInput{} + } + + output = &ListDashboardsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListDashboards API operation for Amazon CloudWatch. +// +// Returns a list of the dashboards for your account. If you include DashboardNamePrefix, +// only those dashboards with names starting with the prefix are listed. Otherwise, +// all dashboards in your account are listed. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon CloudWatch's +// API operation ListDashboards for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidParameterValueException "InvalidParameterValue" +// The value of an input parameter is bad or out-of-range. +// +// * ErrCodeInternalServiceFault "InternalServiceError" +// Request processing has failed due to some unknown error, exception, or failure. +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListDashboards +func (c *CloudWatch) ListDashboards(input *ListDashboardsInput) (*ListDashboardsOutput, error) { + req, out := c.ListDashboardsRequest(input) + return out, req.Send() +} + +// ListDashboardsWithContext is the same as ListDashboards with the addition of +// the ability to pass a context and additional request options. +// +// See ListDashboards for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatch) ListDashboardsWithContext(ctx aws.Context, input *ListDashboardsInput, opts ...request.Option) (*ListDashboardsOutput, error) { + req, out := c.ListDashboardsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opListMetrics = "ListMetrics" // ListMetricsRequest generates a "aws/request.Request" representing the @@ -881,6 +1152,107 @@ func (c *CloudWatch) ListMetricsPagesWithContext(ctx aws.Context, input *ListMet return p.Err() } +const opPutDashboard = "PutDashboard" + +// PutDashboardRequest generates a "aws/request.Request" representing the +// client's request for the PutDashboard operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See PutDashboard for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the PutDashboard method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the PutDashboardRequest method. +// req, resp := client.PutDashboardRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutDashboard +func (c *CloudWatch) PutDashboardRequest(input *PutDashboardInput) (req *request.Request, output *PutDashboardOutput) { + op := &request.Operation{ + Name: opPutDashboard, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutDashboardInput{} + } + + output = &PutDashboardOutput{} + req = c.newRequest(op, input, output) + return +} + +// PutDashboard API operation for Amazon CloudWatch. +// +// Creates a dashboard if it does not already exist, or updates an existing +// dashboard. If you update a dashboard, the entire contents are replaced with +// what you specify here. +// +// You can have up to 500 dashboards per account. All dashboards in your account +// are global, not region-specific. +// +// A simple way to create a dashboard using PutDashboard is to copy an existing +// dashboard. To copy an existing dashboard using the console, you can load +// the dashboard and then use the View/edit source command in the Actions menu +// to display the JSON block for that dashboard. Another way to copy a dashboard +// is to use GetDashboard, and then use the data returned within DashboardBody +// as the template for the new dashboard when you call PutDashboard. +// +// When you create a dashboard with PutDashboard, a good practice is to add +// a text widget at the top of the dashboard with a message that the dashboard +// was created by script and should not be changed in the console. This message +// could also point console users to the location of the DashboardBody script +// or the CloudFormation template used to create the dashboard. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon CloudWatch's +// API operation PutDashboard for usage and error information. +// +// Returned Error Codes: +// * ErrCodeDashboardInvalidInputError "InvalidParameterInput" +// Some part of the dashboard data is invalid. +// +// * ErrCodeInternalServiceFault "InternalServiceError" +// Request processing has failed due to some unknown error, exception, or failure. +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutDashboard +func (c *CloudWatch) PutDashboard(input *PutDashboardInput) (*PutDashboardOutput, error) { + req, out := c.PutDashboardRequest(input) + return out, req.Send() +} + +// PutDashboardWithContext is the same as PutDashboard with the addition of +// the ability to pass a context and additional request options. +// +// See PutDashboard for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatch) PutDashboardWithContext(ctx aws.Context, input *PutDashboardInput, opts ...request.Option) (*PutDashboardOutput, error) { + req, out := c.PutDashboardRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opPutMetricAlarm = "PutMetricAlarm" // PutMetricAlarmRequest generates a "aws/request.Request" representing the @@ -939,8 +1311,7 @@ func (c *CloudWatch) PutMetricAlarmRequest(input *PutMetricAlarmInput) (req *req // When you update an existing alarm, its state is left unchanged, but the update // completely overwrites the previous configuration of the alarm. // -// If you are an AWS Identity and Access Management (IAM) user, you must have -// Amazon EC2 permissions for some operations: +// If you are an IAM user, you must have Amazon EC2 permissions for some operations: // // * ec2:DescribeInstanceStatus and ec2:DescribeInstances for all alarms // on EC2 instance status metrics @@ -953,23 +1324,22 @@ func (c *CloudWatch) PutMetricAlarmRequest(input *PutMetricAlarmInput) (req *req // with recover actions // // If you have read/write permissions for Amazon CloudWatch but not for Amazon -// EC2, you can still create an alarm, but the stop or terminate actions won't -// be performed. However, if you are later granted the required permissions, -// the alarm actions that you created earlier will be performed. +// EC2, you can still create an alarm, but the stop or terminate actions are +// not performed. However, if you are later granted the required permissions, +// the alarm actions that you created earlier are performed. // -// If you are using an IAM role (for example, an Amazon EC2 instance profile), -// you cannot stop or terminate the instance using alarm actions. However, you -// can still see the alarm state and perform any other actions such as Amazon -// SNS notifications or Auto Scaling policies. +// If you are using an IAM role (for example, an EC2 instance profile), you +// cannot stop or terminate the instance using alarm actions. However, you can +// still see the alarm state and perform any other actions such as Amazon SNS +// notifications or Auto Scaling policies. // -// If you are using temporary security credentials granted using the AWS Security -// Token Service (AWS STS), you cannot stop or terminate an Amazon EC2 instance -// using alarm actions. +// If you are using temporary security credentials granted using AWS STS, you +// cannot stop or terminate an EC2 instance using alarm actions. // -// Note that you must create at least one stop, terminate, or reboot alarm using -// the Amazon EC2 or CloudWatch console to create the EC2ActionsAccess IAM role. -// After this IAM role is created, you can create stop, terminate, or reboot -// alarms using a command-line interface or an API. +// You must create at least one stop, terminate, or reboot alarm using either +// the Amazon EC2 or CloudWatch consoles to create the EC2ActionsAccess IAM +// role. After this IAM role is created, you can create stop, terminate, or +// reboot alarms using a command-line interface or API. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -1051,22 +1421,21 @@ func (c *CloudWatch) PutMetricDataRequest(input *PutMetricDataInput) (req *reque // PutMetricData API operation for Amazon CloudWatch. // -// Publishes metric data points to Amazon CloudWatch. Amazon CloudWatch associates +// Publishes metric data points to Amazon CloudWatch. CloudWatch associates // the data points with the specified metric. If the specified metric does not -// exist, Amazon CloudWatch creates the metric. When Amazon CloudWatch creates -// a metric, it can take up to fifteen minutes for the metric to appear in calls -// to ListMetrics. +// exist, CloudWatch creates the metric. When CloudWatch creates a metric, it +// can take up to fifteen minutes for the metric to appear in calls to ListMetrics. // // Each PutMetricData request is limited to 40 KB in size for HTTP POST requests. // -// Although the Value parameter accepts numbers of type Double, Amazon CloudWatch -// rejects values that are either too small or too large. Values must be in -// the range of 8.515920e-109 to 1.174271e+108 (Base 10) or 2e-360 to 2e360 -// (Base 2). In addition, special values (e.g., NaN, +Infinity, -Infinity) are +// Although the Value parameter accepts numbers of type Double, CloudWatch rejects +// values that are either too small or too large. Values must be in the range +// of 8.515920e-109 to 1.174271e+108 (Base 10) or 2e-360 to 2e360 (Base 2). +// In addition, special values (for example, NaN, +Infinity, -Infinity) are // not supported. // // You can use up to 10 dimensions per metric to further clarify what data the -// metric collects. For more information on specifying dimensions, see Publishing +// metric collects. For more information about specifying dimensions, see Publishing // Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html) // in the Amazon CloudWatch User Guide. // @@ -1075,12 +1444,12 @@ func (c *CloudWatch) PutMetricDataRequest(input *PutMetricDataInput) (req *reque // submitted. // // CloudWatch needs raw data points to calculate percentile statistics. If you -// publish data using a statistic set instead, you cannot retrieve percentile -// statistics for this data unless one of the following conditions is true: +// publish data using a statistic set instead, you can only retrieve percentile +// statistics for this data if one of the following conditions is true: // -// * The SampleCount of the statistic set is 1 +// * The SampleCount value of the statistic set is 1 // -// * The Min and the Max of the statistic set are equal +// * The Min and the Max values of the statistic set are equal // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -1097,7 +1466,7 @@ func (c *CloudWatch) PutMetricDataRequest(input *PutMetricDataInput) (req *reque // An input parameter that is required is missing. // // * ErrCodeInvalidParameterCombinationException "InvalidParameterCombination" -// Parameters that cannot be used together were used together. +// Parameters were used together that cannot be used together. // // * ErrCodeInternalServiceFault "InternalServiceError" // Request processing has failed due to some unknown error, exception, or failure. @@ -1175,10 +1544,10 @@ func (c *CloudWatch) SetAlarmStateRequest(input *SetAlarmStateInput) (req *reque // state differs from the previous value, the action configured for the appropriate // state is invoked. For example, if your alarm is configured to send an Amazon // SNS message when an alarm is triggered, temporarily changing the alarm state -// to ALARM sends an Amazon SNS message. The alarm returns to its actual state -// (often within seconds). Because the alarm state change happens very quickly, -// it is typically only visible in the alarm's History tab in the Amazon CloudWatch -// console or through DescribeAlarmHistory. +// to ALARM sends an SNS message. The alarm returns to its actual state (often +// within seconds). Because the alarm state change happens quickly, it is typically +// only visible in the alarm's History tab in the Amazon CloudWatch console +// or through DescribeAlarmHistory. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -1277,8 +1646,95 @@ func (s *AlarmHistoryItem) SetTimestamp(v time.Time) *AlarmHistoryItem { return s } -// Encapsulates the statistical data that Amazon CloudWatch computes from metric -// data. +// Represents a specific dashboard. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DashboardEntry +type DashboardEntry struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the dashboard. + DashboardArn *string `type:"string"` + + // The name of the dashboard. + DashboardName *string `type:"string"` + + // The time stamp of when the dashboard was last modified, either by an API + // call or through the console. This number is expressed as the number of milliseconds + // since Jan 1, 1970 00:00:00 UTC. + LastModified *time.Time `type:"timestamp" timestampFormat:"iso8601"` + + // The size of the dashboard, in bytes. + Size *int64 `type:"long"` +} + +// String returns the string representation +func (s DashboardEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DashboardEntry) GoString() string { + return s.String() +} + +// SetDashboardArn sets the DashboardArn field's value. +func (s *DashboardEntry) SetDashboardArn(v string) *DashboardEntry { + s.DashboardArn = &v + return s +} + +// SetDashboardName sets the DashboardName field's value. +func (s *DashboardEntry) SetDashboardName(v string) *DashboardEntry { + s.DashboardName = &v + return s +} + +// SetLastModified sets the LastModified field's value. +func (s *DashboardEntry) SetLastModified(v time.Time) *DashboardEntry { + s.LastModified = &v + return s +} + +// SetSize sets the Size field's value. +func (s *DashboardEntry) SetSize(v int64) *DashboardEntry { + s.Size = &v + return s +} + +// An error or warning for the operation. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DashboardValidationMessage +type DashboardValidationMessage struct { + _ struct{} `type:"structure"` + + // The data path related to the message. + DataPath *string `type:"string"` + + // A message describing the error or warning. + Message *string `type:"string"` +} + +// String returns the string representation +func (s DashboardValidationMessage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DashboardValidationMessage) GoString() string { + return s.String() +} + +// SetDataPath sets the DataPath field's value. +func (s *DashboardValidationMessage) SetDataPath(v string) *DashboardValidationMessage { + s.DataPath = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *DashboardValidationMessage) SetMessage(v string) *DashboardValidationMessage { + s.Message = &v + return s +} + +// Encapsulates the statistical data that CloudWatch computes from metric data. // Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/Datapoint type Datapoint struct { _ struct{} `type:"structure"` @@ -1421,6 +1877,45 @@ func (s DeleteAlarmsOutput) GoString() string { return s.String() } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteDashboardsInput +type DeleteDashboardsInput struct { + _ struct{} `type:"structure"` + + // The dashboards to be deleted. + DashboardNames []*string `type:"list"` +} + +// String returns the string representation +func (s DeleteDashboardsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDashboardsInput) GoString() string { + return s.String() +} + +// SetDashboardNames sets the DashboardNames field's value. +func (s *DeleteDashboardsInput) SetDashboardNames(v []*string) *DeleteDashboardsInput { + s.DashboardNames = v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DeleteDashboardsOutput +type DeleteDashboardsOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteDashboardsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDashboardsOutput) GoString() string { + return s.String() +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/DescribeAlarmHistoryInput type DescribeAlarmHistoryInput struct { _ struct{} `type:"structure"` @@ -1563,7 +2058,7 @@ type DescribeAlarmsForMetricInput struct { Namespace *string `min:"1" type:"string" required:"true"` // The period, in seconds, over which the statistic is applied. - Period *int64 `min:"60" type:"integer"` + Period *int64 `min:"1" type:"integer"` // The statistic for the metric, other than percentiles. For percentile statistics, // use ExtendedStatistics. @@ -1598,8 +2093,8 @@ func (s *DescribeAlarmsForMetricInput) Validate() error { if s.Namespace != nil && len(*s.Namespace) < 1 { invalidParams.Add(request.NewErrParamMinLen("Namespace", 1)) } - if s.Period != nil && *s.Period < 60 { - invalidParams.Add(request.NewErrParamMinValue("Period", 60)) + if s.Period != nil && *s.Period < 1 { + invalidParams.Add(request.NewErrParamMinValue("Period", 1)) } if s.Dimensions != nil { for i, v := range s.Dimensions { @@ -1691,8 +2186,8 @@ type DescribeAlarmsInput struct { // The action name prefix. ActionPrefix *string `min:"1" type:"string"` - // The alarm name prefix. You cannot specify AlarmNames if this parameter is - // specified. + // The alarm name prefix. If this parameter is specified, you cannot specify + // AlarmNames. AlarmNamePrefix *string `min:"1" type:"string"` // The names of the alarms. @@ -2030,31 +2525,100 @@ func (s EnableAlarmActionsOutput) GoString() string { return s.String() } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetDashboardInput +type GetDashboardInput struct { + _ struct{} `type:"structure"` + + // The name of the dashboard to be described. + DashboardName *string `type:"string"` +} + +// String returns the string representation +func (s GetDashboardInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDashboardInput) GoString() string { + return s.String() +} + +// SetDashboardName sets the DashboardName field's value. +func (s *GetDashboardInput) SetDashboardName(v string) *GetDashboardInput { + s.DashboardName = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetDashboardOutput +type GetDashboardOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the dashboard. + DashboardArn *string `type:"string"` + + // The detailed information about the dashboard, including what widgets are + // included and their location on the dashboard. For more information about + // the DashboardBody syntax, see CloudWatch-Dashboard-Body-Structure. + DashboardBody *string `type:"string"` + + // The name of the dashboard. + DashboardName *string `type:"string"` +} + +// String returns the string representation +func (s GetDashboardOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDashboardOutput) GoString() string { + return s.String() +} + +// SetDashboardArn sets the DashboardArn field's value. +func (s *GetDashboardOutput) SetDashboardArn(v string) *GetDashboardOutput { + s.DashboardArn = &v + return s +} + +// SetDashboardBody sets the DashboardBody field's value. +func (s *GetDashboardOutput) SetDashboardBody(v string) *GetDashboardOutput { + s.DashboardBody = &v + return s +} + +// SetDashboardName sets the DashboardName field's value. +func (s *GetDashboardOutput) SetDashboardName(v string) *GetDashboardOutput { + s.DashboardName = &v + return s +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/GetMetricStatisticsInput type GetMetricStatisticsInput struct { _ struct{} `type:"structure"` // The dimensions. If the metric contains multiple dimensions, you must include // a value for each dimension. CloudWatch treats each unique combination of - // dimensions as a separate metric. You can't retrieve statistics using combinations - // of dimensions that were not specially published. You must specify the same - // dimensions that were used when the metrics were created. For an example, - // see Dimension Combinations (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#dimension-combinations) - // in the Amazon CloudWatch User Guide. For more information on specifying dimensions, - // see Publishing Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html) + // dimensions as a separate metric. If a specific combination of dimensions + // was not published, you can't retrieve statistics for it. You must specify + // the same dimensions that were used when the metrics were created. For an + // example, see Dimension Combinations (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#dimension-combinations) + // in the Amazon CloudWatch User Guide. For more information about specifying + // dimensions, see Publishing Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html) // in the Amazon CloudWatch User Guide. Dimensions []*Dimension `type:"list"` // The time stamp that determines the last data point to return. // - // The value specified is exclusive; results will include data points up to - // the specified time stamp. The time stamp must be in ISO 8601 UTC format (for - // example, 2016-10-10T23:00:00Z). + // The value specified is exclusive; results include data points up to the specified + // time stamp. The time stamp must be in ISO 8601 UTC format (for example, 2016-10-10T23:00:00Z). // // EndTime is a required field EndTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` - // The percentile statistics. Specify values between p0.0 and p100. + // The percentile statistics. Specify values between p0.0 and p100. When calling + // GetMetricStatistics, you must specify either Statistics or ExtendedStatistics, + // but not both. ExtendedStatistics []*string `min:"1" type:"list"` // The name of the metric, with or without spaces. @@ -2067,14 +2631,20 @@ type GetMetricStatisticsInput struct { // Namespace is a required field Namespace *string `min:"1" type:"string" required:"true"` - // The granularity, in seconds, of the returned data points. A period can be - // as short as one minute (60 seconds) and must be a multiple of 60. The default - // value is 60. + // The granularity, in seconds, of the returned data points. For metrics with + // regular resolution, a period can be as short as one minute (60 seconds) and + // must be a multiple of 60. For high-resolution metrics that are collected + // at intervals of less than one minute, the period can be 1, 5, 10, 30, 60, + // or any multiple of 60. High-resolution metrics are those metrics stored by + // a PutMetricData call that includes a StorageResolution of 1 second. // - // If the StartTime parameter specifies a time stamp that is greater than 15 - // days ago, you must specify the period as follows or no data points in that + // If the StartTime parameter specifies a time stamp that is greater than 3 + // hours ago, you must specify the period as follows or no data points in that // time range is returned: // + // * Start time between 3 hours and 15 days ago - Use a multiple of 60 seconds + // (1 minute). + // // * Start time between 15 and 63 days ago - Use a multiple of 300 seconds // (5 minutes). // @@ -2082,11 +2652,10 @@ type GetMetricStatisticsInput struct { // (1 hour). // // Period is a required field - Period *int64 `min:"60" type:"integer" required:"true"` + Period *int64 `min:"1" type:"integer" required:"true"` - // The time stamp that determines the first data point to return. Note that - // start times are evaluated relative to the time that CloudWatch receives the - // request. + // The time stamp that determines the first data point to return. Start times + // are evaluated relative to the time that CloudWatch receives the request. // // The value specified is inclusive; results include data points with the specified // time stamp. The time stamp must be in ISO 8601 UTC format (for example, 2016-10-03T23:00:00Z). @@ -2102,11 +2671,20 @@ type GetMetricStatisticsInput struct { // * Start time greater than 63 days ago - Round down to the nearest 1-hour // clock interval. For example, 12:32:34 is rounded down to 12:00:00. // + // If you set Period to 5, 10, or 30, the start time of your request is rounded + // down to the nearest time that corresponds to even 5-, 10-, or 30-second divisions + // of a minute. For example, if you make a query at (HH:mm:ss) 01:05:23 for + // the previous 10-second period, the start time of your request is rounded + // down and you receive data from 01:05:10 to 01:05:20. If you make a query + // at 15:07:17 for the previous 5 minutes of data, using a period of 5 seconds, + // you receive data timestamped between 15:02:15 and 15:07:15. + // // StartTime is a required field StartTime *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` // The metric statistics, other than percentile. For percentile statistics, - // use ExtendedStatistic. + // use ExtendedStatistics. When calling GetMetricStatistics, you must specify + // either Statistics or ExtendedStatistics, but not both. Statistics []*string `min:"1" type:"list"` // The unit for a given metric. Metrics may be reported in multiple units. Not @@ -2149,8 +2727,8 @@ func (s *GetMetricStatisticsInput) Validate() error { if s.Period == nil { invalidParams.Add(request.NewErrParamRequired("Period")) } - if s.Period != nil && *s.Period < 60 { - invalidParams.Add(request.NewErrParamMinValue("Period", 60)) + if s.Period != nil && *s.Period < 1 { + invalidParams.Add(request.NewErrParamMinValue("Period", 1)) } if s.StartTime == nil { invalidParams.Add(request.NewErrParamRequired("StartTime")) @@ -2262,6 +2840,75 @@ func (s *GetMetricStatisticsOutput) SetLabel(v string) *GetMetricStatisticsOutpu return s } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListDashboardsInput +type ListDashboardsInput struct { + _ struct{} `type:"structure"` + + // If you specify this parameter, only the dashboards with names starting with + // the specified string are listed. The maximum length is 255, and valid characters + // are A-Z, a-z, 0-9, ".", "-", and "_". + DashboardNamePrefix *string `type:"string"` + + // The token returned by a previous call to indicate that there is more data + // available. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s ListDashboardsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListDashboardsInput) GoString() string { + return s.String() +} + +// SetDashboardNamePrefix sets the DashboardNamePrefix field's value. +func (s *ListDashboardsInput) SetDashboardNamePrefix(v string) *ListDashboardsInput { + s.DashboardNamePrefix = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListDashboardsInput) SetNextToken(v string) *ListDashboardsInput { + s.NextToken = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListDashboardsOutput +type ListDashboardsOutput struct { + _ struct{} `type:"structure"` + + // The list of matching dashboards. + DashboardEntries []*DashboardEntry `type:"list"` + + // The token that marks the start of the next batch of returned results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s ListDashboardsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListDashboardsOutput) GoString() string { + return s.String() +} + +// SetDashboardEntries sets the DashboardEntries field's value. +func (s *ListDashboardsOutput) SetDashboardEntries(v []*DashboardEntry) *ListDashboardsOutput { + s.DashboardEntries = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListDashboardsOutput) SetNextToken(v string) *ListDashboardsOutput { + s.NextToken = &v + return s +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/ListMetricsInput type ListMetricsInput struct { _ struct{} `type:"structure"` @@ -2448,6 +3095,10 @@ type MetricAlarm struct { // The dimensions for the metric associated with the alarm. Dimensions []*Dimension `type:"list"` + // Used only for alarms based on percentiles. If ignore, the alarm state does + // not change during periods with too few data points to be statistically significant. + // If evaluate or this parameter is not used, the alarm is always evaluated + // and possibly changes state no matter how many data points are available. EvaluateLowSampleCountPercentile *string `min:"1" type:"string"` // The number of periods over which data is compared to the specified threshold. @@ -2473,7 +3124,7 @@ type MetricAlarm struct { OKActions []*string `type:"list"` // The period, in seconds, over which the statistic is applied. - Period *int64 `min:"60" type:"integer"` + Period *int64 `min:"1" type:"integer"` // An explanation for the alarm state, in text format. StateReason *string `type:"string"` @@ -2494,6 +3145,8 @@ type MetricAlarm struct { // The value to compare with the specified statistic. Threshold *float64 `type:"double"` + // Sets how this alarm is to handle missing data points. If this parameter is + // omitted, the default behavior of missing is used. TreatMissingData *string `min:"1" type:"string"` // The unit of the metric associated with the alarm. @@ -2671,6 +3324,17 @@ type MetricDatum struct { // The statistical values for the metric. StatisticValues *StatisticSet `type:"structure"` + // Valid values are 1 and 60. Setting this to 1 specifies this metric as a high-resolution + // metric, so that CloudWatch stores the metric with sub-minute resolution down + // to one second. Setting this to 60 specifies this metric as a regular-resolution + // metric, which CloudWatch stores at 1-minute resolution. Currently, high resolution + // is available only for custom metrics. For more information about high-resolution + // metrics, see High-Resolution Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics) + // in the Amazon CloudWatch User Guide. + // + // This field is optional, if you do not specify it the default of 60 is used. + StorageResolution *int64 `min:"1" type:"integer"` + // The time the metric data was received, expressed as the number of milliseconds // since Jan 1, 1970 00:00:00 UTC. Timestamp *time.Time `type:"timestamp" timestampFormat:"iso8601"` @@ -2680,11 +3344,11 @@ type MetricDatum struct { // The value for the metric. // - // Although the parameter accepts numbers of type Double, Amazon CloudWatch - // rejects values that are either too small or too large. Values must be in - // the range of 8.515920e-109 to 1.174271e+108 (Base 10) or 2e-360 to 2e360 - // (Base 2). In addition, special values (for example, NaN, +Infinity, -Infinity) - // are not supported. + // Although the parameter accepts numbers of type Double, CloudWatch rejects + // values that are either too small or too large. Values must be in the range + // of 8.515920e-109 to 1.174271e+108 (Base 10) or 2e-360 to 2e360 (Base 2). + // In addition, special values (for example, NaN, +Infinity, -Infinity) are + // not supported. Value *float64 `type:"double"` } @@ -2707,6 +3371,9 @@ func (s *MetricDatum) Validate() error { if s.MetricName != nil && len(*s.MetricName) < 1 { invalidParams.Add(request.NewErrParamMinLen("MetricName", 1)) } + if s.StorageResolution != nil && *s.StorageResolution < 1 { + invalidParams.Add(request.NewErrParamMinValue("StorageResolution", 1)) + } if s.Dimensions != nil { for i, v := range s.Dimensions { if v == nil { @@ -2747,6 +3414,12 @@ func (s *MetricDatum) SetStatisticValues(v *StatisticSet) *MetricDatum { return s } +// SetStorageResolution sets the StorageResolution field's value. +func (s *MetricDatum) SetStorageResolution(v int64) *MetricDatum { + s.StorageResolution = &v + return s +} + // SetTimestamp sets the Timestamp field's value. func (s *MetricDatum) SetTimestamp(v time.Time) *MetricDatum { s.Timestamp = &v @@ -2765,6 +3438,77 @@ func (s *MetricDatum) SetValue(v float64) *MetricDatum { return s } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutDashboardInput +type PutDashboardInput struct { + _ struct{} `type:"structure"` + + // The detailed information about the dashboard in JSON format, including the + // widgets to include and their location on the dashboard. + // + // For more information about the syntax, see CloudWatch-Dashboard-Body-Structure. + DashboardBody *string `type:"string"` + + // The name of the dashboard. If a dashboard with this name already exists, + // this call modifies that dashboard, replacing its current contents. Otherwise, + // a new dashboard is created. The maximum length is 255, and valid characters + // are A-Z, a-z, 0-9, "-", and "_". + DashboardName *string `type:"string"` +} + +// String returns the string representation +func (s PutDashboardInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutDashboardInput) GoString() string { + return s.String() +} + +// SetDashboardBody sets the DashboardBody field's value. +func (s *PutDashboardInput) SetDashboardBody(v string) *PutDashboardInput { + s.DashboardBody = &v + return s +} + +// SetDashboardName sets the DashboardName field's value. +func (s *PutDashboardInput) SetDashboardName(v string) *PutDashboardInput { + s.DashboardName = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutDashboardOutput +type PutDashboardOutput struct { + _ struct{} `type:"structure"` + + // If the input for PutDashboard was correct and the dashboard was successfully + // created or modified, this result is empty. + // + // If this result includes only warning messages, then the input was valid enough + // for the dashboard to be created or modified, but some elements of the dashboard + // may not render. + // + // If this result includes error messages, the input was not valid and the operation + // failed. + DashboardValidationMessages []*DashboardValidationMessage `type:"list"` +} + +// String returns the string representation +func (s PutDashboardOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutDashboardOutput) GoString() string { + return s.String() +} + +// SetDashboardValidationMessages sets the DashboardValidationMessages field's value. +func (s *PutDashboardOutput) SetDashboardValidationMessages(v []*DashboardValidationMessage) *PutDashboardOutput { + s.DashboardValidationMessages = v + return s +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01/PutMetricAlarmInput type PutMetricAlarmInput struct { _ struct{} `type:"structure"` @@ -2802,9 +3546,9 @@ type PutMetricAlarmInput struct { Dimensions []*Dimension `type:"list"` // Used only for alarms based on percentiles. If you specify ignore, the alarm - // state will not change during periods with too few data points to be statistically - // significant. If you specify evaluate or omit this parameter, the alarm will - // always be evaluated and possibly change state no matter how many data points + // state does not change during periods with too few data points to be statistically + // significant. If you specify evaluate or omit this parameter, the alarm is + // always evaluated and possibly changes state no matter how many data points // are available. For more information, see Percentile-Based CloudWatch Alarms // and Low Data Samples (http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#percentiles-with-low-samples). // @@ -2812,6 +3556,8 @@ type PutMetricAlarmInput struct { EvaluateLowSampleCountPercentile *string `min:"1" type:"string"` // The number of periods over which data is compared to the specified threshold. + // An alarm's total current evaluation period can be no longer than one day, + // so this number multiplied by Period cannot be more than 86,400 seconds. // // EvaluationPeriods is a required field EvaluationPeriods *int64 `min:"1" type:"integer" required:"true"` @@ -2853,10 +3599,24 @@ type PutMetricAlarmInput struct { // | arn:aws:swf:us-east-1:{customer-account}:action/actions/AWS_EC2.InstanceId.Reboot/1.0 OKActions []*string `type:"list"` - // The period, in seconds, over which the specified statistic is applied. + // The period, in seconds, over which the specified statistic is applied. Valid + // values are 10, 30, and any multiple of 60. + // + // Be sure to specify 10 or 30 only for metrics that are stored by a PutMetricData + // call with a StorageResolution of 1. If you specify a Period of 10 or 30 for + // a metric that does not have sub-minute resolution, the alarm still attempts + // to gather data at the period rate that you specify. In this case, it does + // not receive data for the attempts that do not correspond to a one-minute + // data resolution, and the alarm may often lapse into INSUFFICENT_DATA status. + // Specifying 10 or 30 also sets this alarm as a high-resolution alarm, which + // has a higher charge than other alarms. For more information about pricing, + // see Amazon CloudWatch Pricing (https://aws.amazon.com/cloudwatch/pricing/). + // + // An alarm's total current evaluation period can be no longer than one day, + // so Period multiplied by EvaluationPeriods cannot be more than 86,400 seconds. // // Period is a required field - Period *int64 `min:"60" type:"integer" required:"true"` + Period *int64 `min:"1" type:"integer" required:"true"` // The statistic for the metric associated with the alarm, other than percentile. // For percentile statistics, use ExtendedStatistic. @@ -2882,8 +3642,7 @@ type PutMetricAlarmInput struct { // Percent, are aggregated separately. // // If you specify a unit, you must use a unit that is appropriate for the metric. - // Otherwise, the Amazon CloudWatch alarm can get stuck in the INSUFFICIENT - // DATA state. + // Otherwise, the CloudWatch alarm can get stuck in the INSUFFICIENT DATA state. Unit *string `type:"string" enum:"StandardUnit"` } @@ -2933,8 +3692,8 @@ func (s *PutMetricAlarmInput) Validate() error { if s.Period == nil { invalidParams.Add(request.NewErrParamRequired("Period")) } - if s.Period != nil && *s.Period < 60 { - invalidParams.Add(request.NewErrParamMinValue("Period", 60)) + if s.Period != nil && *s.Period < 1 { + invalidParams.Add(request.NewErrParamMinValue("Period", 1)) } if s.Threshold == nil { invalidParams.Add(request.NewErrParamRequired("Threshold")) diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface.go index 51dcb03fbd7..38d3dc60de3 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface.go @@ -64,6 +64,10 @@ type CloudWatchAPI interface { DeleteAlarmsWithContext(aws.Context, *cloudwatch.DeleteAlarmsInput, ...request.Option) (*cloudwatch.DeleteAlarmsOutput, error) DeleteAlarmsRequest(*cloudwatch.DeleteAlarmsInput) (*request.Request, *cloudwatch.DeleteAlarmsOutput) + DeleteDashboards(*cloudwatch.DeleteDashboardsInput) (*cloudwatch.DeleteDashboardsOutput, error) + DeleteDashboardsWithContext(aws.Context, *cloudwatch.DeleteDashboardsInput, ...request.Option) (*cloudwatch.DeleteDashboardsOutput, error) + DeleteDashboardsRequest(*cloudwatch.DeleteDashboardsInput) (*request.Request, *cloudwatch.DeleteDashboardsOutput) + DescribeAlarmHistory(*cloudwatch.DescribeAlarmHistoryInput) (*cloudwatch.DescribeAlarmHistoryOutput, error) DescribeAlarmHistoryWithContext(aws.Context, *cloudwatch.DescribeAlarmHistoryInput, ...request.Option) (*cloudwatch.DescribeAlarmHistoryOutput, error) DescribeAlarmHistoryRequest(*cloudwatch.DescribeAlarmHistoryInput) (*request.Request, *cloudwatch.DescribeAlarmHistoryOutput) @@ -90,10 +94,18 @@ type CloudWatchAPI interface { EnableAlarmActionsWithContext(aws.Context, *cloudwatch.EnableAlarmActionsInput, ...request.Option) (*cloudwatch.EnableAlarmActionsOutput, error) EnableAlarmActionsRequest(*cloudwatch.EnableAlarmActionsInput) (*request.Request, *cloudwatch.EnableAlarmActionsOutput) + GetDashboard(*cloudwatch.GetDashboardInput) (*cloudwatch.GetDashboardOutput, error) + GetDashboardWithContext(aws.Context, *cloudwatch.GetDashboardInput, ...request.Option) (*cloudwatch.GetDashboardOutput, error) + GetDashboardRequest(*cloudwatch.GetDashboardInput) (*request.Request, *cloudwatch.GetDashboardOutput) + GetMetricStatistics(*cloudwatch.GetMetricStatisticsInput) (*cloudwatch.GetMetricStatisticsOutput, error) GetMetricStatisticsWithContext(aws.Context, *cloudwatch.GetMetricStatisticsInput, ...request.Option) (*cloudwatch.GetMetricStatisticsOutput, error) GetMetricStatisticsRequest(*cloudwatch.GetMetricStatisticsInput) (*request.Request, *cloudwatch.GetMetricStatisticsOutput) + ListDashboards(*cloudwatch.ListDashboardsInput) (*cloudwatch.ListDashboardsOutput, error) + ListDashboardsWithContext(aws.Context, *cloudwatch.ListDashboardsInput, ...request.Option) (*cloudwatch.ListDashboardsOutput, error) + ListDashboardsRequest(*cloudwatch.ListDashboardsInput) (*request.Request, *cloudwatch.ListDashboardsOutput) + ListMetrics(*cloudwatch.ListMetricsInput) (*cloudwatch.ListMetricsOutput, error) ListMetricsWithContext(aws.Context, *cloudwatch.ListMetricsInput, ...request.Option) (*cloudwatch.ListMetricsOutput, error) ListMetricsRequest(*cloudwatch.ListMetricsInput) (*request.Request, *cloudwatch.ListMetricsOutput) @@ -101,6 +113,10 @@ type CloudWatchAPI interface { ListMetricsPages(*cloudwatch.ListMetricsInput, func(*cloudwatch.ListMetricsOutput, bool) bool) error ListMetricsPagesWithContext(aws.Context, *cloudwatch.ListMetricsInput, func(*cloudwatch.ListMetricsOutput, bool) bool, ...request.Option) error + PutDashboard(*cloudwatch.PutDashboardInput) (*cloudwatch.PutDashboardOutput, error) + PutDashboardWithContext(aws.Context, *cloudwatch.PutDashboardInput, ...request.Option) (*cloudwatch.PutDashboardOutput, error) + PutDashboardRequest(*cloudwatch.PutDashboardInput) (*request.Request, *cloudwatch.PutDashboardOutput) + PutMetricAlarm(*cloudwatch.PutMetricAlarmInput) (*cloudwatch.PutMetricAlarmOutput, error) PutMetricAlarmWithContext(aws.Context, *cloudwatch.PutMetricAlarmInput, ...request.Option) (*cloudwatch.PutMetricAlarmOutput, error) PutMetricAlarmRequest(*cloudwatch.PutMetricAlarmInput) (*request.Request, *cloudwatch.PutMetricAlarmOutput) diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/doc.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/doc.go new file mode 100644 index 00000000000..ef2f5025036 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/doc.go @@ -0,0 +1,94 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package cloudwatch provides the client and types for making API +// requests to Amazon CloudWatch. +// +// Amazon CloudWatch monitors your Amazon Web Services (AWS) resources and the +// applications you run on AWS in real time. You can use CloudWatch to collect +// and track metrics, which are the variables you want to measure for your resources +// and applications. +// +// CloudWatch alarms send notifications or automatically change the resources +// you are monitoring based on rules that you define. For example, you can monitor +// the CPU usage and disk reads and writes of your Amazon EC2 instances. Then, +// use this data to determine whether you should launch additional instances +// to handle increased load. You can also use this data to stop under-used instances +// to save money. +// +// In addition to monitoring the built-in metrics that come with AWS, you can +// monitor your own custom metrics. With CloudWatch, you gain system-wide visibility +// into resource utilization, application performance, and operational health. +// +// See https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01 for more information on this service. +// +// See cloudwatch package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/cloudwatch/ +// +// Using the Client +// +// To use the client for Amazon CloudWatch you will first need +// to create a new instance of it. +// +// When creating a client for an AWS service you'll first need to have a Session +// already created. The Session provides configuration that can be shared +// between multiple service clients. Additional configuration can be applied to +// the Session and service's client when they are constructed. The aws package's +// Config type contains several fields such as Region for the AWS Region the +// client should make API requests too. The optional Config value can be provided +// as the variadic argument for Sessions and client creation. +// +// Once the service's client is created you can use it to make API requests the +// AWS service. These clients are safe to use concurrently. +// +// // Create a session to share configuration, and load external configuration. +// sess := session.Must(session.NewSession()) +// +// // Create the service's client with the session. +// svc := cloudwatch.New(sess) +// +// See the SDK's documentation for more information on how to use service clients. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws package's Config type for more information on configuration options. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon CloudWatch client CloudWatch for more +// information on creating the service's client. +// https://docs.aws.amazon.com/sdk-for-go/api/service/cloudwatch/#New +// +// Once the client is created you can make an API request to the service. +// Each API method takes a input parameter, and returns the service response +// and an error. +// +// The API method will document which error codes the service can be returned +// by the operation if the service models the API operation's errors. These +// errors will also be available as const strings prefixed with "ErrCode". +// +// result, err := svc.DeleteAlarms(params) +// if err != nil { +// // Cast err to awserr.Error to handle specific error codes. +// aerr, ok := err.(awserr.Error) +// if ok && aerr.Code() == { +// // Specific error code handling +// } +// return err +// } +// +// fmt.Println("DeleteAlarms result:") +// fmt.Println(result) +// +// Using the Client with Context +// +// The service's client also provides methods to make API requests with a Context +// value. This allows you to control the timeout, and cancellation of pending +// requests. These methods also take request Option as variadic parameter to apply +// additional configuration to the API request. +// +// ctx := context.Background() +// +// result, err := svc.DeleteAlarmsWithContext(ctx, params) +// +// See the request package documentation for more information on using Context pattern +// with the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/request/ +package cloudwatch diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/errors.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/errors.go index 6eb8cb37fe2..0029aa38f7b 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/errors.go @@ -4,6 +4,18 @@ package cloudwatch const ( + // ErrCodeDashboardInvalidInputError for service response error code + // "InvalidParameterInput". + // + // Some part of the dashboard data is invalid. + ErrCodeDashboardInvalidInputError = "InvalidParameterInput" + + // ErrCodeDashboardNotFoundError for service response error code + // "ResourceNotFound". + // + // The specified dashboard does not exist. + ErrCodeDashboardNotFoundError = "ResourceNotFound" + // ErrCodeInternalServiceFault for service response error code // "InternalServiceError". // @@ -25,7 +37,7 @@ const ( // ErrCodeInvalidParameterCombinationException for service response error code // "InvalidParameterCombination". // - // Parameters that cannot be used together were used together. + // Parameters were used together that cannot be used together. ErrCodeInvalidParameterCombinationException = "InvalidParameterCombination" // ErrCodeInvalidParameterValueException for service response error code diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/service.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/service.go index 8bffc874e07..4b0aa76edcd 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/service.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatch/service.go @@ -11,24 +11,12 @@ import ( "github.com/aws/aws-sdk-go/private/protocol/query" ) -// Amazon CloudWatch monitors your Amazon Web Services (AWS) resources and the -// applications you run on AWS in real-time. You can use CloudWatch to collect -// and track metrics, which are the variables you want to measure for your resources -// and applications. +// CloudWatch provides the API operation methods for making requests to +// Amazon CloudWatch. See this package's package overview docs +// for details on the service. // -// CloudWatch alarms send notifications or automatically make changes to the -// resources you are monitoring based on rules that you define. For example, -// you can monitor the CPU usage and disk reads and writes of your Amazon Elastic -// Compute Cloud (Amazon EC2) instances and then use this data to determine -// whether you should launch additional instances to handle increased load. -// You can also use this data to stop under-used instances to save money. -// -// In addition to monitoring the built-in metrics that come with AWS, you can -// monitor your own custom metrics. With CloudWatch, you gain system-wide visibility -// into resource utilization, application performance, and operational health. -// The service client's operations are safe to be used concurrently. -// It is not safe to mutate any of the client's properties though. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/monitoring-2010-08-01 +// CloudWatch methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. type CloudWatch struct { *client.Client } diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index 63e7dbc70c3..87b13f313b0 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -1,6 +1,5 @@ // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. -// Package ec2 provides a client for Amazon Elastic Compute Cloud. package ec2 import ( @@ -137,8 +136,8 @@ func (c *EC2) AcceptVpcPeeringConnectionRequest(input *AcceptVpcPeeringConnectio // // Accept a VPC peering connection request. To accept a request, the VPC peering // connection must be in the pending-acceptance state, and you must be the owner -// of the peer VPC. Use the DescribeVpcPeeringConnections request to view your -// outstanding VPC peering connection requests. +// of the peer VPC. Use DescribeVpcPeeringConnections to view your outstanding +// VPC peering connection requests. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -546,12 +545,17 @@ func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *reques // // [EC2-Classic, VPC in an EC2-VPC-only account] If the Elastic IP address is // already associated with a different instance, it is disassociated from that -// instance and associated with the specified instance. +// instance and associated with the specified instance. If you associate an +// Elastic IP address with an instance that has an existing Elastic IP address, +// the existing address is disassociated from the instance, but remains allocated +// to your account. // // [VPC in an EC2-Classic account] If you don't specify a private IP address, // the Elastic IP address is associated with the primary IP address. If the // Elastic IP address is already associated with a different instance or a network -// interface, you get an error unless you allow reassociation. +// interface, you get an error unless you allow reassociation. You cannot associate +// an Elastic IP address with an instance or network interface that has an existing +// Elastic IP address. // // This is an idempotent operation. If you perform the operation more than once, // Amazon EC2 doesn't return an error, and you may be charged for each time @@ -2363,7 +2367,8 @@ func (c *EC2) CopyImageRequest(input *CopyImageInput) (req *request.Request, out // region. You specify the destination region by using its endpoint when making // the request. // -// For more information, see Copying AMIs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/CopyingAMIs.html) +// For more information about the prerequisites and limits when copying an AMI, +// see Copying an AMI (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/CopyingAMIs.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -2587,6 +2592,93 @@ func (c *EC2) CreateCustomerGatewayWithContext(ctx aws.Context, input *CreateCus return out, req.Send() } +const opCreateDefaultVpc = "CreateDefaultVpc" + +// CreateDefaultVpcRequest generates a "aws/request.Request" representing the +// client's request for the CreateDefaultVpc operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See CreateDefaultVpc for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateDefaultVpc method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateDefaultVpcRequest method. +// req, resp := client.CreateDefaultVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpc +func (c *EC2) CreateDefaultVpcRequest(input *CreateDefaultVpcInput) (req *request.Request, output *CreateDefaultVpcOutput) { + op := &request.Operation{ + Name: opCreateDefaultVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDefaultVpcInput{} + } + + output = &CreateDefaultVpcOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDefaultVpc API operation for Amazon Elastic Compute Cloud. +// +// Creates a default VPC with a size /16 IPv4 CIDR block and a default subnet +// in each Availability Zone. For more information about the components of a +// default VPC, see Default VPC and Default Subnets (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html) +// in the Amazon Virtual Private Cloud User Guide. You cannot specify the components +// of the default VPC yourself. +// +// You can create a default VPC if you deleted your previous default VPC. You +// cannot have more than one default VPC per region. +// +// If your account supports EC2-Classic, you cannot use this action to create +// a default VPC in a region that supports EC2-Classic. If you want a default +// VPC in a region that supports EC2-Classic, see "I really want a default VPC +// for my existing EC2 account. Is that possible?" in the Default VPCs FAQ (http://aws.amazon.com/vpc/faqs/#Default_VPCs). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateDefaultVpc for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpc +func (c *EC2) CreateDefaultVpc(input *CreateDefaultVpcInput) (*CreateDefaultVpcOutput, error) { + req, out := c.CreateDefaultVpcRequest(input) + return out, req.Send() +} + +// CreateDefaultVpcWithContext is the same as CreateDefaultVpc with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDefaultVpc for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateDefaultVpcWithContext(ctx aws.Context, input *CreateDefaultVpcInput, opts ...request.Option) (*CreateDefaultVpcOutput, error) { + req, out := c.CreateDefaultVpcRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateDhcpOptions = "CreateDhcpOptions" // CreateDhcpOptionsRequest generates a "aws/request.Request" representing the @@ -2645,16 +2737,16 @@ func (c *EC2) CreateDhcpOptionsRequest(input *CreateDhcpOptionsInput) (req *requ // to receive a custom DNS hostname as specified in domain-name, you must // set domain-name-servers to a custom DNS server. // -// * domain-name - If you're using AmazonProvidedDNS in "us-east-1", specify -// "ec2.internal". If you're using AmazonProvidedDNS in another region, specify -// "region.compute.internal" (for example, "ap-northeast-1.compute.internal"). -// Otherwise, specify a domain name (for example, "MyCompany.com"). This -// value is used to complete unqualified DNS hostnames. Important: Some Linux -// operating systems accept multiple domain names separated by spaces. However, -// Windows and other Linux operating systems treat the value as a single -// domain, which results in unexpected behavior. If your DHCP options set -// is associated with a VPC that has instances with multiple operating systems, -// specify only one domain name. +// * domain-name - If you're using AmazonProvidedDNS in us-east-1, specify +// ec2.internal. If you're using AmazonProvidedDNS in another region, specify +// region.compute.internal (for example, ap-northeast-1.compute.internal). +// Otherwise, specify a domain name (for example, MyCompany.com). This value +// is used to complete unqualified DNS hostnames. Important: Some Linux operating +// systems accept multiple domain names separated by spaces. However, Windows +// and other Linux operating systems treat the value as a single domain, +// which results in unexpected behavior. If your DHCP options set is associated +// with a VPC that has instances with multiple operating systems, specify +// only one domain name. // // * ntp-servers - The IP addresses of up to four Network Time Protocol (NTP) // servers. @@ -2863,6 +2955,88 @@ func (c *EC2) CreateFlowLogsWithContext(ctx aws.Context, input *CreateFlowLogsIn return out, req.Send() } +const opCreateFpgaImage = "CreateFpgaImage" + +// CreateFpgaImageRequest generates a "aws/request.Request" representing the +// client's request for the CreateFpgaImage operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See CreateFpgaImage for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateFpgaImage method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateFpgaImageRequest method. +// req, resp := client.CreateFpgaImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage +func (c *EC2) CreateFpgaImageRequest(input *CreateFpgaImageInput) (req *request.Request, output *CreateFpgaImageOutput) { + op := &request.Operation{ + Name: opCreateFpgaImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateFpgaImageInput{} + } + + output = &CreateFpgaImageOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateFpgaImage API operation for Amazon Elastic Compute Cloud. +// +// Creates an Amazon FPGA Image (AFI) from the specified design checkpoint (DCP). +// +// The create operation is asynchronous. To verify that the AFI is ready for +// use, check the output logs. +// +// An AFI contains the FPGA bitstream that is ready to download to an FPGA. +// You can securely deploy an AFI on one or more FPGA-accelerated instances. +// For more information, see the AWS FPGA Hardware Development Kit (https://github.com/aws/aws-fpga/). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateFpgaImage for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage +func (c *EC2) CreateFpgaImage(input *CreateFpgaImageInput) (*CreateFpgaImageOutput, error) { + req, out := c.CreateFpgaImageRequest(input) + return out, req.Send() +} + +// CreateFpgaImageWithContext is the same as CreateFpgaImage with the addition of +// the ability to pass a context and additional request options. +// +// See CreateFpgaImage for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateFpgaImageWithContext(ctx aws.Context, input *CreateFpgaImageInput, opts ...request.Option) (*CreateFpgaImageOutput, error) { + req, out := c.CreateFpgaImageRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateImage = "CreateImage" // CreateImageRequest generates a "aws/request.Request" representing the @@ -3523,6 +3697,85 @@ func (c *EC2) CreateNetworkInterfaceWithContext(ctx aws.Context, input *CreateNe return out, req.Send() } +const opCreateNetworkInterfacePermission = "CreateNetworkInterfacePermission" + +// CreateNetworkInterfacePermissionRequest generates a "aws/request.Request" representing the +// client's request for the CreateNetworkInterfacePermission operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See CreateNetworkInterfacePermission for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the CreateNetworkInterfacePermission method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the CreateNetworkInterfacePermissionRequest method. +// req, resp := client.CreateNetworkInterfacePermissionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermission +func (c *EC2) CreateNetworkInterfacePermissionRequest(input *CreateNetworkInterfacePermissionInput) (req *request.Request, output *CreateNetworkInterfacePermissionOutput) { + op := &request.Operation{ + Name: opCreateNetworkInterfacePermission, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateNetworkInterfacePermissionInput{} + } + + output = &CreateNetworkInterfacePermissionOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateNetworkInterfacePermission API operation for Amazon Elastic Compute Cloud. +// +// Grants an AWS authorized partner account permission to attach the specified +// network interface to an instance in their account. +// +// You can grant permission to a single AWS account only, and only one account +// at a time. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateNetworkInterfacePermission for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermission +func (c *EC2) CreateNetworkInterfacePermission(input *CreateNetworkInterfacePermissionInput) (*CreateNetworkInterfacePermissionOutput, error) { + req, out := c.CreateNetworkInterfacePermissionRequest(input) + return out, req.Send() +} + +// CreateNetworkInterfacePermissionWithContext is the same as CreateNetworkInterfacePermission with the addition of +// the ability to pass a context and additional request options. +// +// See CreateNetworkInterfacePermission for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateNetworkInterfacePermissionWithContext(ctx aws.Context, input *CreateNetworkInterfacePermissionInput, opts ...request.Option) (*CreateNetworkInterfacePermissionOutput, error) { + req, out := c.CreateNetworkInterfacePermissionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreatePlacementGroup = "CreatePlacementGroup" // CreatePlacementGroupRequest generates a "aws/request.Request" representing the @@ -4216,7 +4469,7 @@ func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *request.Reques // If you've associated an IPv6 CIDR block with your VPC, you can create a subnet // with an IPv6 CIDR block that uses a /64 prefix length. // -// AWS reserves both the first four and the last IP address in each subnet's +// AWS reserves both the first four and the last IPv4 address in each subnet's // CIDR block. They're not available for use. // // If you add more than one subnet to a VPC, they're set up in a star topology @@ -4665,8 +4918,8 @@ func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectio // peering connection. The VPC peering connection request expires after 7 days, // after which it cannot be accepted or rejected. // -// A CreateVpcPeeringConnection request between VPCs with overlapping CIDR blocks -// results in the VPC peering connection having a status of failed. +// If you try to create a VPC peering connection between VPCs that have overlapping +// CIDR blocks, the VPC peering connection status goes to failed. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -5729,6 +5982,84 @@ func (c *EC2) DeleteNetworkInterfaceWithContext(ctx aws.Context, input *DeleteNe return out, req.Send() } +const opDeleteNetworkInterfacePermission = "DeleteNetworkInterfacePermission" + +// DeleteNetworkInterfacePermissionRequest generates a "aws/request.Request" representing the +// client's request for the DeleteNetworkInterfacePermission operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See DeleteNetworkInterfacePermission for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DeleteNetworkInterfacePermission method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DeleteNetworkInterfacePermissionRequest method. +// req, resp := client.DeleteNetworkInterfacePermissionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermission +func (c *EC2) DeleteNetworkInterfacePermissionRequest(input *DeleteNetworkInterfacePermissionInput) (req *request.Request, output *DeleteNetworkInterfacePermissionOutput) { + op := &request.Operation{ + Name: opDeleteNetworkInterfacePermission, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteNetworkInterfacePermissionInput{} + } + + output = &DeleteNetworkInterfacePermissionOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteNetworkInterfacePermission API operation for Amazon Elastic Compute Cloud. +// +// Deletes a permission for a network interface. By default, you cannot delete +// the permission if the account for which you're removing the permission has +// attached the network interface to an instance. However, you can force delete +// the permission, regardless of any attachment. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DeleteNetworkInterfacePermission for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermission +func (c *EC2) DeleteNetworkInterfacePermission(input *DeleteNetworkInterfacePermissionInput) (*DeleteNetworkInterfacePermissionOutput, error) { + req, out := c.DeleteNetworkInterfacePermissionRequest(input) + return out, req.Send() +} + +// DeleteNetworkInterfacePermissionWithContext is the same as DeleteNetworkInterfacePermission with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteNetworkInterfacePermission for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DeleteNetworkInterfacePermissionWithContext(ctx aws.Context, input *DeleteNetworkInterfacePermissionInput, opts ...request.Option) (*DeleteNetworkInterfacePermissionOutput, error) { + req, out := c.DeleteNetworkInterfacePermissionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDeletePlacementGroup = "DeletePlacementGroup" // DeletePlacementGroupRequest generates a "aws/request.Request" representing the @@ -7740,6 +8071,82 @@ func (c *EC2) DescribeEgressOnlyInternetGatewaysWithContext(ctx aws.Context, inp return out, req.Send() } +const opDescribeElasticGpus = "DescribeElasticGpus" + +// DescribeElasticGpusRequest generates a "aws/request.Request" representing the +// client's request for the DescribeElasticGpus operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See DescribeElasticGpus for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeElasticGpus method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeElasticGpusRequest method. +// req, resp := client.DescribeElasticGpusRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpus +func (c *EC2) DescribeElasticGpusRequest(input *DescribeElasticGpusInput) (req *request.Request, output *DescribeElasticGpusOutput) { + op := &request.Operation{ + Name: opDescribeElasticGpus, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeElasticGpusInput{} + } + + output = &DescribeElasticGpusOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeElasticGpus API operation for Amazon Elastic Compute Cloud. +// +// Describes the Elastic GPUs associated with your instances. For more information +// about Elastic GPUs, see Amazon EC2 Elastic GPUs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-gpus.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeElasticGpus for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpus +func (c *EC2) DescribeElasticGpus(input *DescribeElasticGpusInput) (*DescribeElasticGpusOutput, error) { + req, out := c.DescribeElasticGpusRequest(input) + return out, req.Send() +} + +// DescribeElasticGpusWithContext is the same as DescribeElasticGpus with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeElasticGpus for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeElasticGpusWithContext(ctx aws.Context, input *DescribeElasticGpusInput, opts ...request.Option) (*DescribeElasticGpusOutput, error) { + req, out := c.DescribeElasticGpusRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeExportTasks = "DescribeExportTasks" // DescribeExportTasksRequest generates a "aws/request.Request" representing the @@ -7892,6 +8299,83 @@ func (c *EC2) DescribeFlowLogsWithContext(ctx aws.Context, input *DescribeFlowLo return out, req.Send() } +const opDescribeFpgaImages = "DescribeFpgaImages" + +// DescribeFpgaImagesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeFpgaImages operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See DescribeFpgaImages for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeFpgaImages method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeFpgaImagesRequest method. +// req, resp := client.DescribeFpgaImagesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImages +func (c *EC2) DescribeFpgaImagesRequest(input *DescribeFpgaImagesInput) (req *request.Request, output *DescribeFpgaImagesOutput) { + op := &request.Operation{ + Name: opDescribeFpgaImages, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeFpgaImagesInput{} + } + + output = &DescribeFpgaImagesOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeFpgaImages API operation for Amazon Elastic Compute Cloud. +// +// Describes one or more available Amazon FPGA Images (AFIs). These include +// public AFIs, private AFIs that you own, and AFIs owned by other AWS accounts +// for which you have load permissions. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeFpgaImages for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImages +func (c *EC2) DescribeFpgaImages(input *DescribeFpgaImagesInput) (*DescribeFpgaImagesOutput, error) { + req, out := c.DescribeFpgaImagesRequest(input) + return out, req.Send() +} + +// DescribeFpgaImagesWithContext is the same as DescribeFpgaImages with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeFpgaImages for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeFpgaImagesWithContext(ctx aws.Context, input *DescribeFpgaImagesInput, opts ...request.Option) (*DescribeFpgaImagesOutput, error) { + req, out := c.DescribeFpgaImagesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeHostReservationOfferings = "DescribeHostReservationOfferings" // DescribeHostReservationOfferingsRequest generates a "aws/request.Request" representing the @@ -8818,7 +9302,8 @@ func (c *EC2) DescribeInstanceStatusRequest(input *DescribeInstanceStatusInput) // DescribeInstanceStatus API operation for Amazon Elastic Compute Cloud. // // Describes the status of one or more instances. By default, only running instances -// are described, unless specified otherwise. +// are described, unless you specifically indicate to return the status of all +// instances. // // Instance status includes the following components: // @@ -9578,6 +10063,81 @@ func (c *EC2) DescribeNetworkInterfaceAttributeWithContext(ctx aws.Context, inpu return out, req.Send() } +const opDescribeNetworkInterfacePermissions = "DescribeNetworkInterfacePermissions" + +// DescribeNetworkInterfacePermissionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeNetworkInterfacePermissions operation. The "output" return +// value can be used to capture response data after the request's "Send" method +// is called. +// +// See DescribeNetworkInterfacePermissions for usage and error information. +// +// Creating a request object using this method should be used when you want to inject +// custom logic into the request's lifecycle using a custom handler, or if you want to +// access properties on the request object before or after sending the request. If +// you just want the service response, call the DescribeNetworkInterfacePermissions method directly +// instead. +// +// Note: You must call the "Send" method on the returned request object in order +// to execute the request. +// +// // Example sending a request using the DescribeNetworkInterfacePermissionsRequest method. +// req, resp := client.DescribeNetworkInterfacePermissionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissions +func (c *EC2) DescribeNetworkInterfacePermissionsRequest(input *DescribeNetworkInterfacePermissionsInput) (req *request.Request, output *DescribeNetworkInterfacePermissionsOutput) { + op := &request.Operation{ + Name: opDescribeNetworkInterfacePermissions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeNetworkInterfacePermissionsInput{} + } + + output = &DescribeNetworkInterfacePermissionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeNetworkInterfacePermissions API operation for Amazon Elastic Compute Cloud. +// +// Describes the permissions for your network interfaces. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeNetworkInterfacePermissions for usage and error information. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissions +func (c *EC2) DescribeNetworkInterfacePermissions(input *DescribeNetworkInterfacePermissionsInput) (*DescribeNetworkInterfacePermissionsOutput, error) { + req, out := c.DescribeNetworkInterfacePermissionsRequest(input) + return out, req.Send() +} + +// DescribeNetworkInterfacePermissionsWithContext is the same as DescribeNetworkInterfacePermissions with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeNetworkInterfacePermissions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeNetworkInterfacePermissionsWithContext(ctx aws.Context, input *DescribeNetworkInterfacePermissionsInput, opts ...request.Option) (*DescribeNetworkInterfacePermissionsOutput, error) { + req, out := c.DescribeNetworkInterfacePermissionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeNetworkInterfaces = "DescribeNetworkInterfaces" // DescribeNetworkInterfacesRequest generates a "aws/request.Request" representing the @@ -12549,8 +13109,8 @@ func (c *EC2) DescribeVpcClassicLinkDnsSupportRequest(input *DescribeVpcClassicL // the DNS hostname of a linked EC2-Classic instance resolves to its private // IP address when addressed from an instance in the VPC to which it's linked. // Similarly, the DNS hostname of an instance in a VPC resolves to its private -// IP address when addressed from a linked EC2-Classic instance. For more information -// about ClassicLink, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) +// IP address when addressed from a linked EC2-Classic instance. For more information, +// see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -13166,7 +13726,7 @@ func (c *EC2) DetachInternetGatewayRequest(input *DetachInternetGatewayInput) (r // // Detaches an Internet gateway from a VPC, disabling connectivity between the // Internet and the VPC. The VPC must not contain any running instances with -// Elastic IP addresses. +// Elastic IP addresses or public IPv4 addresses. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -23364,6 +23924,59 @@ func (s *CreateCustomerGatewayOutput) SetCustomerGateway(v *CustomerGateway) *Cr return s } +// Contains the parameters for CreateDefaultVpc. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcRequest +type CreateDefaultVpcInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` +} + +// String returns the string representation +func (s CreateDefaultVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDefaultVpcInput) GoString() string { + return s.String() +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateDefaultVpcInput) SetDryRun(v bool) *CreateDefaultVpcInput { + s.DryRun = &v + return s +} + +// Contains the output of CreateDefaultVpc. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcResult +type CreateDefaultVpcOutput struct { + _ struct{} `type:"structure"` + + // Information about the VPC. + Vpc *Vpc `locationName:"vpc" type:"structure"` +} + +// String returns the string representation +func (s CreateDefaultVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDefaultVpcOutput) GoString() string { + return s.String() +} + +// SetVpc sets the Vpc field's value. +func (s *CreateDefaultVpcOutput) SetVpc(v *Vpc) *CreateDefaultVpcOutput { + s.Vpc = v + return s +} + // Contains the parameters for CreateDhcpOptions. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptionsRequest type CreateDhcpOptionsInput struct { @@ -23689,6 +24302,128 @@ func (s *CreateFlowLogsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *CreateFlo return s } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageRequest +type CreateFpgaImageInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier that you provide to ensure the idempotency + // of the request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // A description for the AFI. + Description *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The location of the encrypted design checkpoint in Amazon S3. The input must + // be a tarball. + // + // InputStorageLocation is a required field + InputStorageLocation *StorageLocation `type:"structure" required:"true"` + + // The location in Amazon S3 for the output logs. + LogsStorageLocation *StorageLocation `type:"structure"` + + // A name for the AFI. + Name *string `type:"string"` +} + +// String returns the string representation +func (s CreateFpgaImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFpgaImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateFpgaImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateFpgaImageInput"} + if s.InputStorageLocation == nil { + invalidParams.Add(request.NewErrParamRequired("InputStorageLocation")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateFpgaImageInput) SetClientToken(v string) *CreateFpgaImageInput { + s.ClientToken = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *CreateFpgaImageInput) SetDescription(v string) *CreateFpgaImageInput { + s.Description = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateFpgaImageInput) SetDryRun(v bool) *CreateFpgaImageInput { + s.DryRun = &v + return s +} + +// SetInputStorageLocation sets the InputStorageLocation field's value. +func (s *CreateFpgaImageInput) SetInputStorageLocation(v *StorageLocation) *CreateFpgaImageInput { + s.InputStorageLocation = v + return s +} + +// SetLogsStorageLocation sets the LogsStorageLocation field's value. +func (s *CreateFpgaImageInput) SetLogsStorageLocation(v *StorageLocation) *CreateFpgaImageInput { + s.LogsStorageLocation = v + return s +} + +// SetName sets the Name field's value. +func (s *CreateFpgaImageInput) SetName(v string) *CreateFpgaImageInput { + s.Name = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageResult +type CreateFpgaImageOutput struct { + _ struct{} `type:"structure"` + + // The global FPGA image identifier (AGFI ID). + FpgaImageGlobalId *string `locationName:"fpgaImageGlobalId" type:"string"` + + // The FPGA image identifier (AFI ID). + FpgaImageId *string `locationName:"fpgaImageId" type:"string"` +} + +// String returns the string representation +func (s CreateFpgaImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateFpgaImageOutput) GoString() string { + return s.String() +} + +// SetFpgaImageGlobalId sets the FpgaImageGlobalId field's value. +func (s *CreateFpgaImageOutput) SetFpgaImageGlobalId(v string) *CreateFpgaImageOutput { + s.FpgaImageGlobalId = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *CreateFpgaImageOutput) SetFpgaImageId(v string) *CreateFpgaImageOutput { + s.FpgaImageId = &v + return s +} + // Contains the parameters for CreateImage. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageRequest type CreateImageInput struct { @@ -24575,6 +25310,115 @@ func (s *CreateNetworkInterfaceOutput) SetNetworkInterface(v *NetworkInterface) return s } +// Contains the parameters for CreateNetworkInterfacePermission. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionRequest +type CreateNetworkInterfacePermissionInput struct { + _ struct{} `type:"structure"` + + // The AWS account ID. + AwsAccountId *string `type:"string"` + + // The AWS service. Currently not supported. + AwsService *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the network interface. + // + // NetworkInterfaceId is a required field + NetworkInterfaceId *string `type:"string" required:"true"` + + // The type of permission to grant. + // + // Permission is a required field + Permission *string `type:"string" required:"true" enum:"InterfacePermissionType"` +} + +// String returns the string representation +func (s CreateNetworkInterfacePermissionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkInterfacePermissionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateNetworkInterfacePermissionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateNetworkInterfacePermissionInput"} + if s.NetworkInterfaceId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfaceId")) + } + if s.Permission == nil { + invalidParams.Add(request.NewErrParamRequired("Permission")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAwsAccountId sets the AwsAccountId field's value. +func (s *CreateNetworkInterfacePermissionInput) SetAwsAccountId(v string) *CreateNetworkInterfacePermissionInput { + s.AwsAccountId = &v + return s +} + +// SetAwsService sets the AwsService field's value. +func (s *CreateNetworkInterfacePermissionInput) SetAwsService(v string) *CreateNetworkInterfacePermissionInput { + s.AwsService = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateNetworkInterfacePermissionInput) SetDryRun(v bool) *CreateNetworkInterfacePermissionInput { + s.DryRun = &v + return s +} + +// SetNetworkInterfaceId sets the NetworkInterfaceId field's value. +func (s *CreateNetworkInterfacePermissionInput) SetNetworkInterfaceId(v string) *CreateNetworkInterfacePermissionInput { + s.NetworkInterfaceId = &v + return s +} + +// SetPermission sets the Permission field's value. +func (s *CreateNetworkInterfacePermissionInput) SetPermission(v string) *CreateNetworkInterfacePermissionInput { + s.Permission = &v + return s +} + +// Contains the output of CreateNetworkInterfacePermission. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionResult +type CreateNetworkInterfacePermissionOutput struct { + _ struct{} `type:"structure"` + + // Information about the permission for the network interface. + InterfacePermission *NetworkInterfacePermission `locationName:"interfacePermission" type:"structure"` +} + +// String returns the string representation +func (s CreateNetworkInterfacePermissionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateNetworkInterfacePermissionOutput) GoString() string { + return s.String() +} + +// SetInterfacePermission sets the InterfacePermission field's value. +func (s *CreateNetworkInterfacePermissionOutput) SetInterfacePermission(v *NetworkInterfacePermission) *CreateNetworkInterfacePermissionOutput { + s.InterfacePermission = v + return s +} + // Contains the parameters for CreatePlacementGroup. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroupRequest type CreatePlacementGroupInput struct { @@ -27039,6 +27883,93 @@ func (s DeleteNetworkInterfaceOutput) GoString() string { return s.String() } +// Contains the parameters for DeleteNetworkInterfacePermission. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionRequest +type DeleteNetworkInterfacePermissionInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // Specify true to remove the permission even if the network interface is attached + // to an instance. + Force *bool `type:"boolean"` + + // The ID of the network interface permission. + // + // NetworkInterfacePermissionId is a required field + NetworkInterfacePermissionId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteNetworkInterfacePermissionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkInterfacePermissionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteNetworkInterfacePermissionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteNetworkInterfacePermissionInput"} + if s.NetworkInterfacePermissionId == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkInterfacePermissionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DeleteNetworkInterfacePermissionInput) SetDryRun(v bool) *DeleteNetworkInterfacePermissionInput { + s.DryRun = &v + return s +} + +// SetForce sets the Force field's value. +func (s *DeleteNetworkInterfacePermissionInput) SetForce(v bool) *DeleteNetworkInterfacePermissionInput { + s.Force = &v + return s +} + +// SetNetworkInterfacePermissionId sets the NetworkInterfacePermissionId field's value. +func (s *DeleteNetworkInterfacePermissionInput) SetNetworkInterfacePermissionId(v string) *DeleteNetworkInterfacePermissionInput { + s.NetworkInterfacePermissionId = &v + return s +} + +// Contains the output for DeleteNetworkInterfacePermission. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionResult +type DeleteNetworkInterfacePermissionOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds, otherwise returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s DeleteNetworkInterfacePermissionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteNetworkInterfacePermissionOutput) GoString() string { + return s.String() +} + +// SetReturn sets the Return field's value. +func (s *DeleteNetworkInterfacePermissionOutput) SetReturn(v bool) *DeleteNetworkInterfacePermissionOutput { + s.Return = &v + return s +} + // Contains the parameters for DeletePlacementGroup. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroupRequest type DeletePlacementGroupInput struct { @@ -28954,6 +29885,126 @@ func (s *DescribeEgressOnlyInternetGatewaysOutput) SetNextToken(v string) *Descr return s } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusRequest +type DescribeElasticGpusInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more Elastic GPU IDs. + ElasticGpuIds []*string `locationName:"ElasticGpuId" locationNameList:"item" type:"list"` + + // One or more filters. + // + // * availability-zone - The Availability Zone in which the Elastic GPU resides. + // + // * elastic-gpu-health - The status of the Elastic GPU (OK | IMPAIRED). + // + // * elastic-gpu-state - The state of the Elastic GPU (ATTACHED). + // + // * elastic-gpu-type - The type of Elastic GPU; for example, eg1.medium. + // + // * instance-id - The ID of the instance to which the Elastic GPU is associated. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. This + // value can be between 5 and 1000. + MaxResults *int64 `type:"integer"` + + // The token to request the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeElasticGpusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeElasticGpusInput) GoString() string { + return s.String() +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeElasticGpusInput) SetDryRun(v bool) *DescribeElasticGpusInput { + s.DryRun = &v + return s +} + +// SetElasticGpuIds sets the ElasticGpuIds field's value. +func (s *DescribeElasticGpusInput) SetElasticGpuIds(v []*string) *DescribeElasticGpusInput { + s.ElasticGpuIds = v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeElasticGpusInput) SetFilters(v []*Filter) *DescribeElasticGpusInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeElasticGpusInput) SetMaxResults(v int64) *DescribeElasticGpusInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeElasticGpusInput) SetNextToken(v string) *DescribeElasticGpusInput { + s.NextToken = &v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusResult +type DescribeElasticGpusOutput struct { + _ struct{} `type:"structure"` + + // Information about the Elastic GPUs. + ElasticGpuSet []*ElasticGpus `locationName:"elasticGpuSet" type:"list"` + + // The total number of items to return. If the total number of items available + // is more than the value specified in max-items then a Next-Token will be provided + // in the output that you can use to resume pagination. + MaxResults *int64 `locationName:"maxResults" type:"integer"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeElasticGpusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeElasticGpusOutput) GoString() string { + return s.String() +} + +// SetElasticGpuSet sets the ElasticGpuSet field's value. +func (s *DescribeElasticGpusOutput) SetElasticGpuSet(v []*ElasticGpus) *DescribeElasticGpusOutput { + s.ElasticGpuSet = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeElasticGpusOutput) SetMaxResults(v int64) *DescribeElasticGpusOutput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeElasticGpusOutput) SetNextToken(v string) *DescribeElasticGpusOutput { + s.NextToken = &v + return s +} + // Contains the parameters for DescribeExportTasks. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasksRequest type DescribeExportTasksInput struct { @@ -29105,6 +30156,164 @@ func (s *DescribeFlowLogsOutput) SetNextToken(v string) *DescribeFlowLogsOutput return s } +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesRequest +type DescribeFpgaImagesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * create-time - The creation time of the AFI. + // + // * fpga-image-id - The FPGA image identifier (AFI ID). + // + // * fpga-image-global-id - The global FPGA image identifier (AGFI ID). + // + // * name - The name of the AFI. + // + // * owner-id - The AWS account ID of the AFI owner. + // + // * product-code - The product code. + // + // * shell-version - The version of the AWS Shell that was used to create + // the bitstream. + // + // * state - The state of the AFI (pending | failed | available | unavailable). + // + // * tag:key=value - The key/value combination of a tag assigned to the resource. + // Specify the key of the tag in the filter name and the value of the tag + // in the filter value. For example, for the tag Purpose=X, specify tag:Purpose + // for the filter name and X for the filter value. + // + // * tag-key - The key of a tag assigned to the resource. This filter is + // independent of the tag-value filter. For example, if you use both the + // filter "tag-key=Purpose" and the filter "tag-value=X", you get any resources + // assigned both the tag key Purpose (regardless of what the tag's value + // is), and the tag value X (regardless of what the tag's key is). If you + // want to list only resources where Purpose is X, see the tag:key=value + // filter. + // + // * tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // + // * update-time - The time of the most recent update. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more AFI IDs. + FpgaImageIds []*string `locationName:"FpgaImageId" locationNameList:"item" type:"list"` + + // The maximum number of results to return in a single call. + MaxResults *int64 `min:"5" type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `min:"1" type:"string"` + + // Filters the AFI by owner. Specify an AWS account ID, self (owner is the sender + // of the request), or an AWS owner alias (valid values are amazon | aws-marketplace). + Owners []*string `locationName:"Owner" locationNameList:"Owner" type:"list"` +} + +// String returns the string representation +func (s DescribeFpgaImagesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFpgaImagesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeFpgaImagesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeFpgaImagesInput"} + if s.MaxResults != nil && *s.MaxResults < 5 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 5)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeFpgaImagesInput) SetDryRun(v bool) *DescribeFpgaImagesInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeFpgaImagesInput) SetFilters(v []*Filter) *DescribeFpgaImagesInput { + s.Filters = v + return s +} + +// SetFpgaImageIds sets the FpgaImageIds field's value. +func (s *DescribeFpgaImagesInput) SetFpgaImageIds(v []*string) *DescribeFpgaImagesInput { + s.FpgaImageIds = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeFpgaImagesInput) SetMaxResults(v int64) *DescribeFpgaImagesInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeFpgaImagesInput) SetNextToken(v string) *DescribeFpgaImagesInput { + s.NextToken = &v + return s +} + +// SetOwners sets the Owners field's value. +func (s *DescribeFpgaImagesInput) SetOwners(v []*string) *DescribeFpgaImagesInput { + s.Owners = v + return s +} + +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesResult +type DescribeFpgaImagesOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more FPGA images. + FpgaImages []*FpgaImage `locationName:"fpgaImageSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" min:"1" type:"string"` +} + +// String returns the string representation +func (s DescribeFpgaImagesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFpgaImagesOutput) GoString() string { + return s.String() +} + +// SetFpgaImages sets the FpgaImages field's value. +func (s *DescribeFpgaImagesOutput) SetFpgaImages(v []*FpgaImage) *DescribeFpgaImagesOutput { + s.FpgaImages = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeFpgaImagesOutput) SetNextToken(v string) *DescribeFpgaImagesOutput { + s.NextToken = &v + return s +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferingsRequest type DescribeHostReservationOfferingsInput struct { _ struct{} `type:"structure"` @@ -30587,18 +31796,6 @@ type DescribeInstancesInput struct { // // * architecture - The instance architecture (i386 | x86_64). // - // * association.public-ip - The address of the Elastic IP address (IPv4) - // bound to the network interface. - // - // * association.ip-owner-id - The owner of the Elastic IP address (IPv4) - // associated with the network interface. - // - // * association.allocation-id - The allocation ID returned when you allocated - // the Elastic IP address (IPv4) for your network interface. - // - // * association.association-id - The association ID returned when the network - // interface was associated with an IPv4 address. - // // * availability-zone - The Availability Zone of the instance. // // * block-device-mapping.attach-time - The attach time for an EBS volume @@ -30684,6 +31881,18 @@ type DescribeInstancesInput struct { // * network-interface.addresses.association.ip-owner-id - The owner ID of // the private IPv4 address associated with the network interface. // + // * network-interface.association.public-ip - The address of the Elastic + // IP address (IPv4) bound to the network interface. + // + // * network-interface.association.ip-owner-id - The owner of the Elastic + // IP address (IPv4) associated with the network interface. + // + // * network-interface.association.allocation-id - The allocation ID returned + // when you allocated the Elastic IP address (IPv4) for your network interface. + // + // * network-interface.association.association-id - The association ID returned + // when the network interface was associated with an IPv4 address. + // // * network-interface.attachment.attachment-id - The ID of the interface // attachment. // @@ -31425,7 +32634,7 @@ func (s *DescribeNetworkAclsOutput) SetNetworkAcls(v []*NetworkAcl) *DescribeNet type DescribeNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` - // The attribute of the network interface. + // The attribute of the network interface. This parameter is required. Attribute *string `locationName:"attribute" type:"string" enum:"NetworkInterfaceAttribute"` // Checks whether you have the required permissions for the action, without @@ -31542,6 +32751,107 @@ func (s *DescribeNetworkInterfaceAttributeOutput) SetSourceDestCheck(v *Attribut return s } +// Contains the parameters for DescribeNetworkInterfacePermissions. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsRequest +type DescribeNetworkInterfacePermissionsInput struct { + _ struct{} `type:"structure"` + + // One or more filters. + // + // * network-interface-permission.network-interface-permission-id - The ID + // of the permission. + // + // * network-interface-permission.network-interface-id - The ID of the network + // interface. + // + // * network-interface-permission.aws-account-id - The AWS account ID. + // + // * network-interface-permission.aws-service - The AWS service. + // + // * network-interface-permission.permission - The type of permission (INSTANCE-ATTACH + // | EIP-ASSOCIATE). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. If + // this parameter is not specified, up to 50 results are returned by default. + MaxResults *int64 `type:"integer"` + + // One or more network interface permission IDs. + NetworkInterfacePermissionIds []*string `locationName:"NetworkInterfacePermissionId" type:"list"` + + // The token to request the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeNetworkInterfacePermissionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfacePermissionsInput) GoString() string { + return s.String() +} + +// SetFilters sets the Filters field's value. +func (s *DescribeNetworkInterfacePermissionsInput) SetFilters(v []*Filter) *DescribeNetworkInterfacePermissionsInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeNetworkInterfacePermissionsInput) SetMaxResults(v int64) *DescribeNetworkInterfacePermissionsInput { + s.MaxResults = &v + return s +} + +// SetNetworkInterfacePermissionIds sets the NetworkInterfacePermissionIds field's value. +func (s *DescribeNetworkInterfacePermissionsInput) SetNetworkInterfacePermissionIds(v []*string) *DescribeNetworkInterfacePermissionsInput { + s.NetworkInterfacePermissionIds = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeNetworkInterfacePermissionsInput) SetNextToken(v string) *DescribeNetworkInterfacePermissionsInput { + s.NextToken = &v + return s +} + +// Contains the output for DescribeNetworkInterfacePermissions. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsResult +type DescribeNetworkInterfacePermissionsOutput struct { + _ struct{} `type:"structure"` + + // The network interface permissions. + NetworkInterfacePermissions []*NetworkInterfacePermission `locationName:"networkInterfacePermissions" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeNetworkInterfacePermissionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeNetworkInterfacePermissionsOutput) GoString() string { + return s.String() +} + +// SetNetworkInterfacePermissions sets the NetworkInterfacePermissions field's value. +func (s *DescribeNetworkInterfacePermissionsOutput) SetNetworkInterfacePermissions(v []*NetworkInterfacePermission) *DescribeNetworkInterfacePermissionsOutput { + s.NetworkInterfacePermissions = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeNetworkInterfacePermissionsOutput) SetNextToken(v string) *DescribeNetworkInterfacePermissionsOutput { + s.NextToken = &v + return s +} + // Contains the parameters for DescribeNetworkInterfaces. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacesRequest type DescribeNetworkInterfacesInput struct { @@ -32355,6 +33665,9 @@ type DescribeReservedInstancesOfferingsInput struct { // with a tenancy of dedicated is applied to instances that run in a VPC on // single-tenant hardware (i.e., Dedicated Instances). // + // Important: The host value cannot be used with this parameter. Use the default + // or dedicated values only. + // // Default: default InstanceTenancy *string `locationName:"instanceTenancy" type:"string" enum:"Tenancy"` @@ -32586,7 +33899,8 @@ type DescribeRouteTablesInput struct { // * association.subnet-id - The ID of the subnet involved in the association. // // * association.main - Indicates whether the route table is the main route - // table for the VPC (true | false). + // table for the VPC (true | false). Route tables that do not have an association + // ID are not returned in the response. // // * route-table-id - The ID of the route table. // @@ -33316,7 +34630,7 @@ type DescribeSnapshotsInput struct { // // * owner-alias - Value from an Amazon-maintained list (amazon | aws-marketplace // | microsoft) of snapshot owners. Not to be confused with the user-configured - // AWS account alias, which is set from the IAM consolew. + // AWS account alias, which is set from the IAM console. // // * owner-id - The ID of the AWS account that owns the snapshot. // @@ -34582,7 +35896,7 @@ func (s *DescribeTagsOutput) SetTags(v []*TagDescription) *DescribeTagsOutput { type DescribeVolumeAttributeInput struct { _ struct{} `type:"structure"` - // The instance attribute. + // The attribute of the volume. This parameter is required. Attribute *string `type:"string" enum:"VolumeAttributeName"` // Checks whether you have the required permissions for the action, without @@ -37503,6 +38817,193 @@ func (s *EgressOnlyInternetGateway) SetEgressOnlyInternetGatewayId(v string) *Eg return s } +// Describes the association between an instance and an Elastic GPU. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuAssociation +type ElasticGpuAssociation struct { + _ struct{} `type:"structure"` + + // The ID of the association. + ElasticGpuAssociationId *string `locationName:"elasticGpuAssociationId" type:"string"` + + // The state of the association between the instance and the Elastic GPU. + ElasticGpuAssociationState *string `locationName:"elasticGpuAssociationState" type:"string"` + + // The time the Elastic GPU was associated with the instance. + ElasticGpuAssociationTime *string `locationName:"elasticGpuAssociationTime" type:"string"` + + // The ID of the Elastic GPU. + ElasticGpuId *string `locationName:"elasticGpuId" type:"string"` +} + +// String returns the string representation +func (s ElasticGpuAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ElasticGpuAssociation) GoString() string { + return s.String() +} + +// SetElasticGpuAssociationId sets the ElasticGpuAssociationId field's value. +func (s *ElasticGpuAssociation) SetElasticGpuAssociationId(v string) *ElasticGpuAssociation { + s.ElasticGpuAssociationId = &v + return s +} + +// SetElasticGpuAssociationState sets the ElasticGpuAssociationState field's value. +func (s *ElasticGpuAssociation) SetElasticGpuAssociationState(v string) *ElasticGpuAssociation { + s.ElasticGpuAssociationState = &v + return s +} + +// SetElasticGpuAssociationTime sets the ElasticGpuAssociationTime field's value. +func (s *ElasticGpuAssociation) SetElasticGpuAssociationTime(v string) *ElasticGpuAssociation { + s.ElasticGpuAssociationTime = &v + return s +} + +// SetElasticGpuId sets the ElasticGpuId field's value. +func (s *ElasticGpuAssociation) SetElasticGpuId(v string) *ElasticGpuAssociation { + s.ElasticGpuId = &v + return s +} + +// Describes the status of an Elastic GPU. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuHealth +type ElasticGpuHealth struct { + _ struct{} `type:"structure"` + + // The health status. + Status *string `locationName:"status" type:"string" enum:"ElasticGpuStatus"` +} + +// String returns the string representation +func (s ElasticGpuHealth) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ElasticGpuHealth) GoString() string { + return s.String() +} + +// SetStatus sets the Status field's value. +func (s *ElasticGpuHealth) SetStatus(v string) *ElasticGpuHealth { + s.Status = &v + return s +} + +// A specification for an Elastic GPU. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuSpecification +type ElasticGpuSpecification struct { + _ struct{} `type:"structure"` + + // The type of Elastic GPU. + // + // Type is a required field + Type *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ElasticGpuSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ElasticGpuSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ElasticGpuSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ElasticGpuSpecification"} + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetType sets the Type field's value. +func (s *ElasticGpuSpecification) SetType(v string) *ElasticGpuSpecification { + s.Type = &v + return s +} + +// Describes an Elastic GPU. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpus +type ElasticGpus struct { + _ struct{} `type:"structure"` + + // The Availability Zone in the which the Elastic GPU resides. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The status of the Elastic GPU. + ElasticGpuHealth *ElasticGpuHealth `locationName:"elasticGpuHealth" type:"structure"` + + // The ID of the Elastic GPU. + ElasticGpuId *string `locationName:"elasticGpuId" type:"string"` + + // The state of the Elastic GPU. + ElasticGpuState *string `locationName:"elasticGpuState" type:"string" enum:"ElasticGpuState"` + + // The type of Elastic GPU. + ElasticGpuType *string `locationName:"elasticGpuType" type:"string"` + + // The ID of the instance to which the Elastic GPU is attached. + InstanceId *string `locationName:"instanceId" type:"string"` +} + +// String returns the string representation +func (s ElasticGpus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ElasticGpus) GoString() string { + return s.String() +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *ElasticGpus) SetAvailabilityZone(v string) *ElasticGpus { + s.AvailabilityZone = &v + return s +} + +// SetElasticGpuHealth sets the ElasticGpuHealth field's value. +func (s *ElasticGpus) SetElasticGpuHealth(v *ElasticGpuHealth) *ElasticGpus { + s.ElasticGpuHealth = v + return s +} + +// SetElasticGpuId sets the ElasticGpuId field's value. +func (s *ElasticGpus) SetElasticGpuId(v string) *ElasticGpus { + s.ElasticGpuId = &v + return s +} + +// SetElasticGpuState sets the ElasticGpuState field's value. +func (s *ElasticGpus) SetElasticGpuState(v string) *ElasticGpus { + s.ElasticGpuState = &v + return s +} + +// SetElasticGpuType sets the ElasticGpuType field's value. +func (s *ElasticGpus) SetElasticGpuType(v string) *ElasticGpus { + s.ElasticGpuType = &v + return s +} + +// SetInstanceId sets the InstanceId field's value. +func (s *ElasticGpus) SetInstanceId(v string) *ElasticGpus { + s.InstanceId = &v + return s +} + // Contains the parameters for EnableVgwRoutePropagation. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagationRequest type EnableVgwRoutePropagationInput struct { @@ -38178,6 +39679,182 @@ func (s *FlowLog) SetTrafficType(v string) *FlowLog { return s } +// Describes an Amazon FPGA image (AFI). +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImage +type FpgaImage struct { + _ struct{} `type:"structure"` + + // The date and time the AFI was created. + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` + + // The description of the AFI. + Description *string `locationName:"description" type:"string"` + + // The global FPGA image identifier (AGFI ID). + FpgaImageGlobalId *string `locationName:"fpgaImageGlobalId" type:"string"` + + // The FPGA image identifier (AFI ID). + FpgaImageId *string `locationName:"fpgaImageId" type:"string"` + + // The name of the AFI. + Name *string `locationName:"name" type:"string"` + + // The alias of the AFI owner. Possible values include self, amazon, and aws-marketplace. + OwnerAlias *string `locationName:"ownerAlias" type:"string"` + + // The AWS account ID of the AFI owner. + OwnerId *string `locationName:"ownerId" type:"string"` + + // Information about the PCI bus. + PciId *PciId `locationName:"pciId" type:"structure"` + + // The product codes for the AFI. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + + // The version of the AWS Shell that was used to create the bitstream. + ShellVersion *string `locationName:"shellVersion" type:"string"` + + // Information about the state of the AFI. + State *FpgaImageState `locationName:"state" type:"structure"` + + // Any tags assigned to the AFI. + Tags []*Tag `locationName:"tags" locationNameList:"item" type:"list"` + + // The time of the most recent update to the AFI. + UpdateTime *time.Time `locationName:"updateTime" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s FpgaImage) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FpgaImage) GoString() string { + return s.String() +} + +// SetCreateTime sets the CreateTime field's value. +func (s *FpgaImage) SetCreateTime(v time.Time) *FpgaImage { + s.CreateTime = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *FpgaImage) SetDescription(v string) *FpgaImage { + s.Description = &v + return s +} + +// SetFpgaImageGlobalId sets the FpgaImageGlobalId field's value. +func (s *FpgaImage) SetFpgaImageGlobalId(v string) *FpgaImage { + s.FpgaImageGlobalId = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *FpgaImage) SetFpgaImageId(v string) *FpgaImage { + s.FpgaImageId = &v + return s +} + +// SetName sets the Name field's value. +func (s *FpgaImage) SetName(v string) *FpgaImage { + s.Name = &v + return s +} + +// SetOwnerAlias sets the OwnerAlias field's value. +func (s *FpgaImage) SetOwnerAlias(v string) *FpgaImage { + s.OwnerAlias = &v + return s +} + +// SetOwnerId sets the OwnerId field's value. +func (s *FpgaImage) SetOwnerId(v string) *FpgaImage { + s.OwnerId = &v + return s +} + +// SetPciId sets the PciId field's value. +func (s *FpgaImage) SetPciId(v *PciId) *FpgaImage { + s.PciId = v + return s +} + +// SetProductCodes sets the ProductCodes field's value. +func (s *FpgaImage) SetProductCodes(v []*ProductCode) *FpgaImage { + s.ProductCodes = v + return s +} + +// SetShellVersion sets the ShellVersion field's value. +func (s *FpgaImage) SetShellVersion(v string) *FpgaImage { + s.ShellVersion = &v + return s +} + +// SetState sets the State field's value. +func (s *FpgaImage) SetState(v *FpgaImageState) *FpgaImage { + s.State = v + return s +} + +// SetTags sets the Tags field's value. +func (s *FpgaImage) SetTags(v []*Tag) *FpgaImage { + s.Tags = v + return s +} + +// SetUpdateTime sets the UpdateTime field's value. +func (s *FpgaImage) SetUpdateTime(v time.Time) *FpgaImage { + s.UpdateTime = &v + return s +} + +// Describes the state of the bitstream generation process for an Amazon FPGA +// image (AFI). +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImageState +type FpgaImageState struct { + _ struct{} `type:"structure"` + + // The state. The following are the possible values: + // + // * pending - AFI bitstream generation is in progress. + // + // * available - The AFI is available for use. + // + // * failed - AFI bitstream generation failed. + // + // * unavailable - The AFI is no longer available for use. + Code *string `locationName:"code" type:"string" enum:"FpgaImageStateCode"` + + // If the state is failed, this is the error message. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s FpgaImageState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FpgaImageState) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *FpgaImageState) SetCode(v string) *FpgaImageState { + s.Code = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *FpgaImageState) SetMessage(v string) *FpgaImageState { + s.Message = &v + return s +} + // Contains the parameters for GetConsoleOutput. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutputRequest type GetConsoleOutputInput struct { @@ -40968,6 +42645,9 @@ type Instance struct { // Optimized instance. EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + // The Elastic GPU associated with the instance. + ElasticGpuAssociations []*ElasticGpuAssociation `locationName:"elasticGpuAssociationSet" locationNameList:"item" type:"list"` + // Specifies whether enhanced networking with ENA is enabled. EnaSupport *bool `locationName:"enaSupport" type:"boolean"` @@ -41125,6 +42805,12 @@ func (s *Instance) SetEbsOptimized(v bool) *Instance { return s } +// SetElasticGpuAssociations sets the ElasticGpuAssociations field's value. +func (s *Instance) SetElasticGpuAssociations(v []*ElasticGpuAssociation) *Instance { + s.ElasticGpuAssociations = v + return s +} + // SetEnaSupport sets the EnaSupport field's value. func (s *Instance) SetEnaSupport(v bool) *Instance { s.EnaSupport = &v @@ -43281,7 +44967,7 @@ type ModifyInstanceAttributeInput struct { BlockDeviceMappings []*InstanceBlockDeviceMappingSpecification `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` // If the value is true, you can't terminate the instance using the Amazon EC2 - // console, CLI, or API; otherwise, you can. You cannot use this paramater for + // console, CLI, or API; otherwise, you can. You cannot use this parameter for // Spot Instances. DisableApiTermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` @@ -45584,6 +47270,110 @@ func (s *NetworkInterfaceIpv6Address) SetIpv6Address(v string) *NetworkInterface return s } +// Describes a permission for a network interface. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermission +type NetworkInterfacePermission struct { + _ struct{} `type:"structure"` + + // The AWS account ID. + AwsAccountId *string `locationName:"awsAccountId" type:"string"` + + // The AWS service. + AwsService *string `locationName:"awsService" type:"string"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The ID of the network interface permission. + NetworkInterfacePermissionId *string `locationName:"networkInterfacePermissionId" type:"string"` + + // The type of permission. + Permission *string `locationName:"permission" type:"string" enum:"InterfacePermissionType"` + + // Information about the state of the permission. + PermissionState *NetworkInterfacePermissionState `locationName:"permissionState" type:"structure"` +} + +// String returns the string representation +func (s NetworkInterfacePermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfacePermission) GoString() string { + return s.String() +} + +// SetAwsAccountId sets the AwsAccountId field's value. +func (s *NetworkInterfacePermission) SetAwsAccountId(v string) *NetworkInterfacePermission { + s.AwsAccountId = &v + return s +} + +// SetAwsService sets the AwsService field's value. +func (s *NetworkInterfacePermission) SetAwsService(v string) *NetworkInterfacePermission { + s.AwsService = &v + return s +} + +// SetNetworkInterfaceId sets the NetworkInterfaceId field's value. +func (s *NetworkInterfacePermission) SetNetworkInterfaceId(v string) *NetworkInterfacePermission { + s.NetworkInterfaceId = &v + return s +} + +// SetNetworkInterfacePermissionId sets the NetworkInterfacePermissionId field's value. +func (s *NetworkInterfacePermission) SetNetworkInterfacePermissionId(v string) *NetworkInterfacePermission { + s.NetworkInterfacePermissionId = &v + return s +} + +// SetPermission sets the Permission field's value. +func (s *NetworkInterfacePermission) SetPermission(v string) *NetworkInterfacePermission { + s.Permission = &v + return s +} + +// SetPermissionState sets the PermissionState field's value. +func (s *NetworkInterfacePermission) SetPermissionState(v *NetworkInterfacePermissionState) *NetworkInterfacePermission { + s.PermissionState = v + return s +} + +// Describes the state of a network interface permission. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermissionState +type NetworkInterfacePermissionState struct { + _ struct{} `type:"structure"` + + // The state of the permission. + State *string `locationName:"state" type:"string" enum:"NetworkInterfacePermissionStateCode"` + + // A status message, if applicable. + StatusMessage *string `locationName:"statusMessage" type:"string"` +} + +// String returns the string representation +func (s NetworkInterfacePermissionState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s NetworkInterfacePermissionState) GoString() string { + return s.String() +} + +// SetState sets the State field's value. +func (s *NetworkInterfacePermissionState) SetState(v string) *NetworkInterfacePermissionState { + s.State = &v + return s +} + +// SetStatusMessage sets the StatusMessage field's value. +func (s *NetworkInterfacePermissionState) SetStatusMessage(v string) *NetworkInterfacePermissionState { + s.StatusMessage = &v + return s +} + // Describes the private IPv4 address of a network interface. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePrivateIpAddress type NetworkInterfacePrivateIpAddress struct { @@ -45669,6 +47459,59 @@ func (s *NewDhcpConfiguration) SetValues(v []*string) *NewDhcpConfiguration { return s } +// Describes the data that identifies an Amazon FPGA image (AFI) on the PCI +// bus. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PciId +type PciId struct { + _ struct{} `type:"structure"` + + // The ID of the device. + DeviceId *string `type:"string"` + + // The ID of the subsystem. + SubsystemId *string `type:"string"` + + // The ID of the vendor for the subsystem. + SubsystemVendorId *string `type:"string"` + + // The ID of the vendor. + VendorId *string `type:"string"` +} + +// String returns the string representation +func (s PciId) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PciId) GoString() string { + return s.String() +} + +// SetDeviceId sets the DeviceId field's value. +func (s *PciId) SetDeviceId(v string) *PciId { + s.DeviceId = &v + return s +} + +// SetSubsystemId sets the SubsystemId field's value. +func (s *PciId) SetSubsystemId(v string) *PciId { + s.SubsystemId = &v + return s +} + +// SetSubsystemVendorId sets the SubsystemVendorId field's value. +func (s *PciId) SetSubsystemVendorId(v string) *PciId { + s.SubsystemVendorId = &v + return s +} + +// SetVendorId sets the VendorId field's value. +func (s *PciId) SetVendorId(v string) *PciId { + s.VendorId = &v + return s +} + // Describes the VPC peering connection options. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PeeringConnectionOptions type PeeringConnectionOptions struct { @@ -45780,6 +47623,9 @@ type Placement struct { // is not supported for the ImportInstance command. HostId *string `locationName:"hostId" type:"string"` + // Reserved for future use. + SpreadDomain *string `locationName:"spreadDomain" type:"string"` + // The tenancy of the instance (if the instance is running in a VPC). An instance // with a tenancy of dedicated runs on single-tenant hardware. The host tenancy // is not supported for the ImportInstance command. @@ -45820,6 +47666,12 @@ func (s *Placement) SetHostId(v string) *Placement { return s } +// SetSpreadDomain sets the SpreadDomain field's value. +func (s *Placement) SetSpreadDomain(v string) *Placement { + s.SpreadDomain = &v + return s +} + // SetTenancy sets the Tenancy field's value. func (s *Placement) SetTenancy(v string) *Placement { s.Tenancy = &v @@ -48199,7 +50051,7 @@ type RequestSpotInstancesInput struct { // Default: Instances are launched and terminated individually LaunchGroup *string `locationName:"launchGroup" type:"string"` - // Describes the launch specification for an instance. + // The launch specification. LaunchSpecification *RequestSpotLaunchSpecification `type:"structure"` // The maximum hourly price (bid) for any Spot instance launched to fulfill @@ -48388,7 +50240,9 @@ type RequestSpotLaunchSpecification struct { // The name of the key pair. KeyName *string `locationName:"keyName" type:"string"` - // Describes the monitoring of an instance. + // Indicates whether basic or detailed monitoring is enabled for the instance. + // + // Default: Disabled Monitoring *RunInstancesMonitoringEnabled `locationName:"monitoring" type:"structure"` // One or more network interfaces. If you specify a network interface, you must @@ -48401,8 +50255,12 @@ type RequestSpotLaunchSpecification struct { // The ID of the RAM disk. RamdiskId *string `locationName:"ramdiskId" type:"string"` + // One or more security group IDs. SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"item" type:"list"` + // One or more security groups. When requesting instances in a VPC, you must + // specify the IDs of the security groups. When requesting instances in EC2-Classic, + // you can specify the names or the IDs of the security groups. SecurityGroups []*string `locationName:"SecurityGroup" locationNameList:"item" type:"list"` // The ID of the subnet in which to launch the instance. @@ -50381,6 +52239,9 @@ type RunInstancesInput struct { // Default: false EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + // An Elastic GPU to associate with the instance. + ElasticGpuSpecification []*ElasticGpuSpecification `locationNameList:"item" type:"list"` + // The IAM instance profile. IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` @@ -50528,6 +52389,16 @@ func (s *RunInstancesInput) Validate() error { if s.MinCount == nil { invalidParams.Add(request.NewErrParamRequired("MinCount")) } + if s.ElasticGpuSpecification != nil { + for i, v := range s.ElasticGpuSpecification { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ElasticGpuSpecification", i), err.(request.ErrInvalidParams)) + } + } + } if s.Monitoring != nil { if err := s.Monitoring.Validate(); err != nil { invalidParams.AddNested("Monitoring", err.(request.ErrInvalidParams)) @@ -50586,6 +52457,12 @@ func (s *RunInstancesInput) SetEbsOptimized(v bool) *RunInstancesInput { return s } +// SetElasticGpuSpecification sets the ElasticGpuSpecification field's value. +func (s *RunInstancesInput) SetElasticGpuSpecification(v []*ElasticGpuSpecification) *RunInstancesInput { + s.ElasticGpuSpecification = v + return s +} + // SetIamInstanceProfile sets the IamInstanceProfile field's value. func (s *RunInstancesInput) SetIamInstanceProfile(v *IamInstanceProfileSpecification) *RunInstancesInput { s.IamInstanceProfile = v @@ -52719,6 +54596,9 @@ type SpotFleetLaunchSpecification struct { // subnets, separate them using commas; for example, "subnet-a61dafcf, subnet-65ea5f08". SubnetId *string `locationName:"subnetId" type:"string"` + // The tags to apply during creation. + TagSpecifications []*SpotFleetTagSpecification `locationName:"tagSpecificationSet" locationNameList:"item" type:"list"` + // The user data to make available to the instances. If you are using an AWS // SDK or command line tool, Base64-encoding is performed for you, and you can // load the text from a file. Otherwise, you must provide Base64-encoded text. @@ -52854,6 +54734,12 @@ func (s *SpotFleetLaunchSpecification) SetSubnetId(v string) *SpotFleetLaunchSpe return s } +// SetTagSpecifications sets the TagSpecifications field's value. +func (s *SpotFleetLaunchSpecification) SetTagSpecifications(v []*SpotFleetTagSpecification) *SpotFleetLaunchSpecification { + s.TagSpecifications = v + return s +} + // SetUserData sets the UserData field's value. func (s *SpotFleetLaunchSpecification) SetUserData(v string) *SpotFleetLaunchSpecification { s.UserData = &v @@ -53163,6 +55049,41 @@ func (s *SpotFleetRequestConfigData) SetValidUntil(v time.Time) *SpotFleetReques return s } +// The tags for a Spot fleet resource. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetTagSpecification +type SpotFleetTagSpecification struct { + _ struct{} `type:"structure"` + + // The type of resource. Currently, the only resource type that is supported + // is instance. + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The tags. + Tags []*Tag `locationName:"tag" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s SpotFleetTagSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotFleetTagSpecification) GoString() string { + return s.String() +} + +// SetResourceType sets the ResourceType field's value. +func (s *SpotFleetTagSpecification) SetResourceType(v string) *SpotFleetTagSpecification { + s.ResourceType = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *SpotFleetTagSpecification) SetTags(v []*Tag) *SpotFleetTagSpecification { + s.Tags = v + return s +} + // Describes a Spot instance request. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceRequest type SpotInstanceRequest struct { @@ -53953,6 +55874,40 @@ func (s *Storage) SetS3(v *S3Storage) *Storage { return s } +// Describes a storage location in Amazon S3. +// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StorageLocation +type StorageLocation struct { + _ struct{} `type:"structure"` + + // The name of the S3 bucket. + Bucket *string `type:"string"` + + // The key. + Key *string `type:"string"` +} + +// String returns the string representation +func (s StorageLocation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StorageLocation) GoString() string { + return s.String() +} + +// SetBucket sets the Bucket field's value. +func (s *StorageLocation) SetBucket(v string) *StorageLocation { + s.Bucket = &v + return s +} + +// SetKey sets the Key field's value. +func (s *StorageLocation) SetKey(v string) *StorageLocation { + s.Key = &v + return s +} + // Describes a subnet. // Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Subnet type Subnet struct { @@ -55963,15 +57918,15 @@ func (s *VpcIpv6CidrBlockAssociation) SetIpv6CidrBlockState(v *VpcCidrBlockState type VpcPeeringConnection struct { _ struct{} `type:"structure"` - // Information about the accepter VPC. CIDR block information is not returned - // when creating a VPC peering connection, or when describing a VPC peering - // connection that's in the initiating-request or pending-acceptance state. + // Information about the accepter VPC. CIDR block information is only returned + // when describing an active VPC peering connection. AccepterVpcInfo *VpcPeeringConnectionVpcInfo `locationName:"accepterVpcInfo" type:"structure"` // The time that an unaccepted VPC peering connection will expire. ExpirationTime *time.Time `locationName:"expirationTime" type:"timestamp" timestampFormat:"iso8601"` - // Information about the requester VPC. + // Information about the requester VPC. CIDR block information is only returned + // when describing an active VPC peering connection. RequesterVpcInfo *VpcPeeringConnectionVpcInfo `locationName:"requesterVpcInfo" type:"structure"` // The status of the VPC peering connection. @@ -56682,6 +58637,19 @@ const ( DomainTypeStandard = "standard" ) +const ( + // ElasticGpuStateAttached is a ElasticGpuState enum value + ElasticGpuStateAttached = "ATTACHED" +) + +const ( + // ElasticGpuStatusOk is a ElasticGpuStatus enum value + ElasticGpuStatusOk = "OK" + + // ElasticGpuStatusImpaired is a ElasticGpuStatus enum value + ElasticGpuStatusImpaired = "IMPAIRED" +) + const ( // EventCodeInstanceReboot is a EventCode enum value EventCodeInstanceReboot = "instance-reboot" @@ -56762,6 +58730,20 @@ const ( FlowLogsResourceTypeNetworkInterface = "NetworkInterface" ) +const ( + // FpgaImageStateCodePending is a FpgaImageStateCode enum value + FpgaImageStateCodePending = "pending" + + // FpgaImageStateCodeFailed is a FpgaImageStateCode enum value + FpgaImageStateCodeFailed = "failed" + + // FpgaImageStateCodeAvailable is a FpgaImageStateCode enum value + FpgaImageStateCodeAvailable = "available" + + // FpgaImageStateCodeUnavailable is a FpgaImageStateCode enum value + FpgaImageStateCodeUnavailable = "unavailable" +) + const ( // GatewayTypeIpsec1 is a GatewayType enum value GatewayTypeIpsec1 = "ipsec.1" @@ -57136,6 +59118,15 @@ const ( // InstanceTypeG28xlarge is a InstanceType enum value InstanceTypeG28xlarge = "g2.8xlarge" + // InstanceTypeG34xlarge is a InstanceType enum value + InstanceTypeG34xlarge = "g3.4xlarge" + + // InstanceTypeG38xlarge is a InstanceType enum value + InstanceTypeG38xlarge = "g3.8xlarge" + + // InstanceTypeG316xlarge is a InstanceType enum value + InstanceTypeG316xlarge = "g3.16xlarge" + // InstanceTypeCg14xlarge is a InstanceType enum value InstanceTypeCg14xlarge = "cg1.4xlarge" @@ -57167,6 +59158,14 @@ const ( InstanceTypeF116xlarge = "f1.16xlarge" ) +const ( + // InterfacePermissionTypeInstanceAttach is a InterfacePermissionType enum value + InterfacePermissionTypeInstanceAttach = "INSTANCE-ATTACH" + + // InterfacePermissionTypeEipAssociate is a InterfacePermissionType enum value + InterfacePermissionTypeEipAssociate = "EIP-ASSOCIATE" +) + const ( // ListingStateAvailable is a ListingState enum value ListingStateAvailable = "available" @@ -57248,6 +59247,20 @@ const ( NetworkInterfaceAttributeAttachment = "attachment" ) +const ( + // NetworkInterfacePermissionStateCodePending is a NetworkInterfacePermissionStateCode enum value + NetworkInterfacePermissionStateCodePending = "pending" + + // NetworkInterfacePermissionStateCodeGranted is a NetworkInterfacePermissionStateCode enum value + NetworkInterfacePermissionStateCodeGranted = "granted" + + // NetworkInterfacePermissionStateCodeRevoking is a NetworkInterfacePermissionStateCode enum value + NetworkInterfacePermissionStateCodeRevoking = "revoking" + + // NetworkInterfacePermissionStateCodeRevoked is a NetworkInterfacePermissionStateCode enum value + NetworkInterfacePermissionStateCodeRevoked = "revoked" +) + const ( // NetworkInterfaceStatusAvailable is a NetworkInterfaceStatus enum value NetworkInterfaceStatusAvailable = "available" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go new file mode 100644 index 00000000000..4aa6618b466 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go @@ -0,0 +1,83 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package ec2 provides the client and types for making API +// requests to Amazon Elastic Compute Cloud. +// +// Amazon Elastic Compute Cloud (Amazon EC2) provides resizable computing capacity +// in the Amazon Web Services (AWS) cloud. Using Amazon EC2 eliminates your +// need to invest in hardware up front, so you can develop and deploy applications +// faster. +// +// See https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15 for more information on this service. +// +// See ec2 package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/ +// +// Using the Client +// +// To use the client for Amazon Elastic Compute Cloud you will first need +// to create a new instance of it. +// +// When creating a client for an AWS service you'll first need to have a Session +// already created. The Session provides configuration that can be shared +// between multiple service clients. Additional configuration can be applied to +// the Session and service's client when they are constructed. The aws package's +// Config type contains several fields such as Region for the AWS Region the +// client should make API requests too. The optional Config value can be provided +// as the variadic argument for Sessions and client creation. +// +// Once the service's client is created you can use it to make API requests the +// AWS service. These clients are safe to use concurrently. +// +// // Create a session to share configuration, and load external configuration. +// sess := session.Must(session.NewSession()) +// +// // Create the service's client with the session. +// svc := ec2.New(sess) +// +// See the SDK's documentation for more information on how to use service clients. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws package's Config type for more information on configuration options. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon Elastic Compute Cloud client EC2 for more +// information on creating the service's client. +// https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#New +// +// Once the client is created you can make an API request to the service. +// Each API method takes a input parameter, and returns the service response +// and an error. +// +// The API method will document which error codes the service can be returned +// by the operation if the service models the API operation's errors. These +// errors will also be available as const strings prefixed with "ErrCode". +// +// result, err := svc.AcceptReservedInstancesExchangeQuote(params) +// if err != nil { +// // Cast err to awserr.Error to handle specific error codes. +// aerr, ok := err.(awserr.Error) +// if ok && aerr.Code() == { +// // Specific error code handling +// } +// return err +// } +// +// fmt.Println("AcceptReservedInstancesExchangeQuote result:") +// fmt.Println(result) +// +// Using the Client with Context +// +// The service's client also provides methods to make API requests with a Context +// value. This allows you to control the timeout, and cancellation of pending +// requests. These methods also take request Option as variadic parameter to apply +// additional configuration to the API request. +// +// ctx := context.Background() +// +// result, err := svc.AcceptReservedInstancesExchangeQuoteWithContext(ctx, params) +// +// See the request package documentation for more information on using Context pattern +// with the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/request/ +package ec2 diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go index cd0046c3993..77882a6b505 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/ec2iface/interface.go @@ -184,6 +184,10 @@ type EC2API interface { CreateCustomerGatewayWithContext(aws.Context, *ec2.CreateCustomerGatewayInput, ...request.Option) (*ec2.CreateCustomerGatewayOutput, error) CreateCustomerGatewayRequest(*ec2.CreateCustomerGatewayInput) (*request.Request, *ec2.CreateCustomerGatewayOutput) + CreateDefaultVpc(*ec2.CreateDefaultVpcInput) (*ec2.CreateDefaultVpcOutput, error) + CreateDefaultVpcWithContext(aws.Context, *ec2.CreateDefaultVpcInput, ...request.Option) (*ec2.CreateDefaultVpcOutput, error) + CreateDefaultVpcRequest(*ec2.CreateDefaultVpcInput) (*request.Request, *ec2.CreateDefaultVpcOutput) + CreateDhcpOptions(*ec2.CreateDhcpOptionsInput) (*ec2.CreateDhcpOptionsOutput, error) CreateDhcpOptionsWithContext(aws.Context, *ec2.CreateDhcpOptionsInput, ...request.Option) (*ec2.CreateDhcpOptionsOutput, error) CreateDhcpOptionsRequest(*ec2.CreateDhcpOptionsInput) (*request.Request, *ec2.CreateDhcpOptionsOutput) @@ -196,6 +200,10 @@ type EC2API interface { CreateFlowLogsWithContext(aws.Context, *ec2.CreateFlowLogsInput, ...request.Option) (*ec2.CreateFlowLogsOutput, error) CreateFlowLogsRequest(*ec2.CreateFlowLogsInput) (*request.Request, *ec2.CreateFlowLogsOutput) + CreateFpgaImage(*ec2.CreateFpgaImageInput) (*ec2.CreateFpgaImageOutput, error) + CreateFpgaImageWithContext(aws.Context, *ec2.CreateFpgaImageInput, ...request.Option) (*ec2.CreateFpgaImageOutput, error) + CreateFpgaImageRequest(*ec2.CreateFpgaImageInput) (*request.Request, *ec2.CreateFpgaImageOutput) + CreateImage(*ec2.CreateImageInput) (*ec2.CreateImageOutput, error) CreateImageWithContext(aws.Context, *ec2.CreateImageInput, ...request.Option) (*ec2.CreateImageOutput, error) CreateImageRequest(*ec2.CreateImageInput) (*request.Request, *ec2.CreateImageOutput) @@ -228,6 +236,10 @@ type EC2API interface { CreateNetworkInterfaceWithContext(aws.Context, *ec2.CreateNetworkInterfaceInput, ...request.Option) (*ec2.CreateNetworkInterfaceOutput, error) CreateNetworkInterfaceRequest(*ec2.CreateNetworkInterfaceInput) (*request.Request, *ec2.CreateNetworkInterfaceOutput) + CreateNetworkInterfacePermission(*ec2.CreateNetworkInterfacePermissionInput) (*ec2.CreateNetworkInterfacePermissionOutput, error) + CreateNetworkInterfacePermissionWithContext(aws.Context, *ec2.CreateNetworkInterfacePermissionInput, ...request.Option) (*ec2.CreateNetworkInterfacePermissionOutput, error) + CreateNetworkInterfacePermissionRequest(*ec2.CreateNetworkInterfacePermissionInput) (*request.Request, *ec2.CreateNetworkInterfacePermissionOutput) + CreatePlacementGroup(*ec2.CreatePlacementGroupInput) (*ec2.CreatePlacementGroupOutput, error) CreatePlacementGroupWithContext(aws.Context, *ec2.CreatePlacementGroupInput, ...request.Option) (*ec2.CreatePlacementGroupOutput, error) CreatePlacementGroupRequest(*ec2.CreatePlacementGroupInput) (*request.Request, *ec2.CreatePlacementGroupOutput) @@ -332,6 +344,10 @@ type EC2API interface { DeleteNetworkInterfaceWithContext(aws.Context, *ec2.DeleteNetworkInterfaceInput, ...request.Option) (*ec2.DeleteNetworkInterfaceOutput, error) DeleteNetworkInterfaceRequest(*ec2.DeleteNetworkInterfaceInput) (*request.Request, *ec2.DeleteNetworkInterfaceOutput) + DeleteNetworkInterfacePermission(*ec2.DeleteNetworkInterfacePermissionInput) (*ec2.DeleteNetworkInterfacePermissionOutput, error) + DeleteNetworkInterfacePermissionWithContext(aws.Context, *ec2.DeleteNetworkInterfacePermissionInput, ...request.Option) (*ec2.DeleteNetworkInterfacePermissionOutput, error) + DeleteNetworkInterfacePermissionRequest(*ec2.DeleteNetworkInterfacePermissionInput) (*request.Request, *ec2.DeleteNetworkInterfacePermissionOutput) + DeletePlacementGroup(*ec2.DeletePlacementGroupInput) (*ec2.DeletePlacementGroupOutput, error) DeletePlacementGroupWithContext(aws.Context, *ec2.DeletePlacementGroupInput, ...request.Option) (*ec2.DeletePlacementGroupOutput, error) DeletePlacementGroupRequest(*ec2.DeletePlacementGroupInput) (*request.Request, *ec2.DeletePlacementGroupOutput) @@ -432,6 +448,10 @@ type EC2API interface { DescribeEgressOnlyInternetGatewaysWithContext(aws.Context, *ec2.DescribeEgressOnlyInternetGatewaysInput, ...request.Option) (*ec2.DescribeEgressOnlyInternetGatewaysOutput, error) DescribeEgressOnlyInternetGatewaysRequest(*ec2.DescribeEgressOnlyInternetGatewaysInput) (*request.Request, *ec2.DescribeEgressOnlyInternetGatewaysOutput) + DescribeElasticGpus(*ec2.DescribeElasticGpusInput) (*ec2.DescribeElasticGpusOutput, error) + DescribeElasticGpusWithContext(aws.Context, *ec2.DescribeElasticGpusInput, ...request.Option) (*ec2.DescribeElasticGpusOutput, error) + DescribeElasticGpusRequest(*ec2.DescribeElasticGpusInput) (*request.Request, *ec2.DescribeElasticGpusOutput) + DescribeExportTasks(*ec2.DescribeExportTasksInput) (*ec2.DescribeExportTasksOutput, error) DescribeExportTasksWithContext(aws.Context, *ec2.DescribeExportTasksInput, ...request.Option) (*ec2.DescribeExportTasksOutput, error) DescribeExportTasksRequest(*ec2.DescribeExportTasksInput) (*request.Request, *ec2.DescribeExportTasksOutput) @@ -440,6 +460,10 @@ type EC2API interface { DescribeFlowLogsWithContext(aws.Context, *ec2.DescribeFlowLogsInput, ...request.Option) (*ec2.DescribeFlowLogsOutput, error) DescribeFlowLogsRequest(*ec2.DescribeFlowLogsInput) (*request.Request, *ec2.DescribeFlowLogsOutput) + DescribeFpgaImages(*ec2.DescribeFpgaImagesInput) (*ec2.DescribeFpgaImagesOutput, error) + DescribeFpgaImagesWithContext(aws.Context, *ec2.DescribeFpgaImagesInput, ...request.Option) (*ec2.DescribeFpgaImagesOutput, error) + DescribeFpgaImagesRequest(*ec2.DescribeFpgaImagesInput) (*request.Request, *ec2.DescribeFpgaImagesOutput) + DescribeHostReservationOfferings(*ec2.DescribeHostReservationOfferingsInput) (*ec2.DescribeHostReservationOfferingsOutput, error) DescribeHostReservationOfferingsWithContext(aws.Context, *ec2.DescribeHostReservationOfferingsInput, ...request.Option) (*ec2.DescribeHostReservationOfferingsOutput, error) DescribeHostReservationOfferingsRequest(*ec2.DescribeHostReservationOfferingsInput) (*request.Request, *ec2.DescribeHostReservationOfferingsOutput) @@ -525,6 +549,10 @@ type EC2API interface { DescribeNetworkInterfaceAttributeWithContext(aws.Context, *ec2.DescribeNetworkInterfaceAttributeInput, ...request.Option) (*ec2.DescribeNetworkInterfaceAttributeOutput, error) DescribeNetworkInterfaceAttributeRequest(*ec2.DescribeNetworkInterfaceAttributeInput) (*request.Request, *ec2.DescribeNetworkInterfaceAttributeOutput) + DescribeNetworkInterfacePermissions(*ec2.DescribeNetworkInterfacePermissionsInput) (*ec2.DescribeNetworkInterfacePermissionsOutput, error) + DescribeNetworkInterfacePermissionsWithContext(aws.Context, *ec2.DescribeNetworkInterfacePermissionsInput, ...request.Option) (*ec2.DescribeNetworkInterfacePermissionsOutput, error) + DescribeNetworkInterfacePermissionsRequest(*ec2.DescribeNetworkInterfacePermissionsInput) (*request.Request, *ec2.DescribeNetworkInterfacePermissionsOutput) + DescribeNetworkInterfaces(*ec2.DescribeNetworkInterfacesInput) (*ec2.DescribeNetworkInterfacesOutput, error) DescribeNetworkInterfacesWithContext(aws.Context, *ec2.DescribeNetworkInterfacesInput, ...request.Option) (*ec2.DescribeNetworkInterfacesOutput, error) DescribeNetworkInterfacesRequest(*ec2.DescribeNetworkInterfacesInput) (*request.Request, *ec2.DescribeNetworkInterfacesOutput) diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/service.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/service.go index e04220546f2..ba4433d388e 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/service.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/service.go @@ -11,13 +11,12 @@ import ( "github.com/aws/aws-sdk-go/private/protocol/ec2query" ) -// Amazon Elastic Compute Cloud (Amazon EC2) provides resizable computing capacity -// in the Amazon Web Services (AWS) cloud. Using Amazon EC2 eliminates your -// need to invest in hardware up front, so you can develop and deploy applications -// faster. -// The service client's operations are safe to be used concurrently. -// It is not safe to mutate any of the client's properties though. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15 +// EC2 provides the API operation methods for making requests to +// Amazon Elastic Compute Cloud. See this package's package overview docs +// for details on the service. +// +// EC2 methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. type EC2 struct { *client.Client } diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go index 3f0fc2fdc08..8a5fd8e17ef 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go @@ -1,6 +1,5 @@ // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. -// Package s3 provides a client for Amazon Simple Storage Service. package s3 import ( @@ -3223,17 +3222,15 @@ func (c *S3) HeadObjectRequest(input *HeadObjectInput) (req *request.Request, ou // object itself. This operation is useful if you're only interested in an object's // metadata. To use HEAD, you must have READ access to the object. // +// See http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#RESTErrorResponses +// for more information on returned errors. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation HeadObject for usage and error information. -// -// Returned Error Codes: -// * ErrCodeNoSuchKey "NoSuchKey" -// The specified key does not exist. -// // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject func (c *S3) HeadObject(input *HeadObjectInput) (*HeadObjectOutput, error) { req, out := c.HeadObjectRequest(input) @@ -6106,6 +6103,13 @@ func (s *AbortMultipartUploadInput) SetBucket(v string) *AbortMultipartUploadInp return s } +func (s *AbortMultipartUploadInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *AbortMultipartUploadInput) SetKey(v string) *AbortMultipartUploadInput { s.Key = &v @@ -6515,6 +6519,13 @@ func (s *AnalyticsS3BucketDestination) SetBucket(v string) *AnalyticsS3BucketDes return s } +func (s *AnalyticsS3BucketDestination) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetBucketAccountId sets the BucketAccountId field's value. func (s *AnalyticsS3BucketDestination) SetBucketAccountId(v string) *AnalyticsS3BucketDestination { s.BucketAccountId = &v @@ -6873,7 +6884,7 @@ type CompleteMultipartUploadInput struct { // Key is a required field Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` - MultipartUpload *CompletedMultipartUpload `locationName:"CompleteMultipartUpload" type:"structure"` + MultipartUpload *CompletedMultipartUpload `locationName:"CompleteMultipartUpload" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` // Confirms that the requester knows that she or he will be charged for the // request. Bucket owners need not specify this parameter in their requests. @@ -6923,6 +6934,13 @@ func (s *CompleteMultipartUploadInput) SetBucket(v string) *CompleteMultipartUpl return s } +func (s *CompleteMultipartUploadInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *CompleteMultipartUploadInput) SetKey(v string) *CompleteMultipartUploadInput { s.Key = &v @@ -6996,6 +7014,13 @@ func (s *CompleteMultipartUploadOutput) SetBucket(v string) *CompleteMultipartUp return s } +func (s *CompleteMultipartUploadOutput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetETag sets the ETag field's value. func (s *CompleteMultipartUploadOutput) SetETag(v string) *CompleteMultipartUploadOutput { s.ETag = &v @@ -7321,6 +7346,13 @@ func (s *CopyObjectInput) SetBucket(v string) *CopyObjectInput { return s } +func (s *CopyObjectInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetCacheControl sets the CacheControl field's value. func (s *CopyObjectInput) SetCacheControl(v string) *CopyObjectInput { s.CacheControl = &v @@ -7393,6 +7425,13 @@ func (s *CopyObjectInput) SetCopySourceSSECustomerKey(v string) *CopyObjectInput return s } +func (s *CopyObjectInput) getCopySourceSSECustomerKey() (v string) { + if s.CopySourceSSECustomerKey == nil { + return v + } + return *s.CopySourceSSECustomerKey +} + // SetCopySourceSSECustomerKeyMD5 sets the CopySourceSSECustomerKeyMD5 field's value. func (s *CopyObjectInput) SetCopySourceSSECustomerKeyMD5(v string) *CopyObjectInput { s.CopySourceSSECustomerKeyMD5 = &v @@ -7465,6 +7504,13 @@ func (s *CopyObjectInput) SetSSECustomerKey(v string) *CopyObjectInput { return s } +func (s *CopyObjectInput) getSSECustomerKey() (v string) { + if s.SSECustomerKey == nil { + return v + } + return *s.SSECustomerKey +} + // SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value. func (s *CopyObjectInput) SetSSECustomerKeyMD5(v string) *CopyObjectInput { s.SSECustomerKeyMD5 = &v @@ -7707,7 +7753,7 @@ type CreateBucketInput struct { // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` - CreateBucketConfiguration *CreateBucketConfiguration `locationName:"CreateBucketConfiguration" type:"structure"` + CreateBucketConfiguration *CreateBucketConfiguration `locationName:"CreateBucketConfiguration" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` // Allows grantee the read, write, read ACP, and write ACP permissions on the // bucket. @@ -7761,6 +7807,13 @@ func (s *CreateBucketInput) SetBucket(v string) *CreateBucketInput { return s } +func (s *CreateBucketInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetCreateBucketConfiguration sets the CreateBucketConfiguration field's value. func (s *CreateBucketInput) SetCreateBucketConfiguration(v *CreateBucketConfiguration) *CreateBucketInput { s.CreateBucketConfiguration = v @@ -7902,6 +7955,9 @@ type CreateMultipartUploadInput struct { // The type of storage to use for the object. Defaults to 'STANDARD'. StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string" enum:"StorageClass"` + // The tag-set for the object. The tag-set must be encoded as URL Query parameters + Tagging *string `location:"header" locationName:"x-amz-tagging" type:"string"` + // If the bucket is configured as a website, redirects requests for this object // to another object in the same bucket or to an external URL. Amazon S3 stores // the value of this header in the object metadata. @@ -7949,6 +8005,13 @@ func (s *CreateMultipartUploadInput) SetBucket(v string) *CreateMultipartUploadI return s } +func (s *CreateMultipartUploadInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetCacheControl sets the CacheControl field's value. func (s *CreateMultipartUploadInput) SetCacheControl(v string) *CreateMultipartUploadInput { s.CacheControl = &v @@ -8039,6 +8102,13 @@ func (s *CreateMultipartUploadInput) SetSSECustomerKey(v string) *CreateMultipar return s } +func (s *CreateMultipartUploadInput) getSSECustomerKey() (v string) { + if s.SSECustomerKey == nil { + return v + } + return *s.SSECustomerKey +} + // SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value. func (s *CreateMultipartUploadInput) SetSSECustomerKeyMD5(v string) *CreateMultipartUploadInput { s.SSECustomerKeyMD5 = &v @@ -8063,6 +8133,12 @@ func (s *CreateMultipartUploadInput) SetStorageClass(v string) *CreateMultipartU return s } +// SetTagging sets the Tagging field's value. +func (s *CreateMultipartUploadInput) SetTagging(v string) *CreateMultipartUploadInput { + s.Tagging = &v + return s +} + // SetWebsiteRedirectLocation sets the WebsiteRedirectLocation field's value. func (s *CreateMultipartUploadInput) SetWebsiteRedirectLocation(v string) *CreateMultipartUploadInput { s.WebsiteRedirectLocation = &v @@ -8140,6 +8216,13 @@ func (s *CreateMultipartUploadOutput) SetBucket(v string) *CreateMultipartUpload return s } +func (s *CreateMultipartUploadOutput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *CreateMultipartUploadOutput) SetKey(v string) *CreateMultipartUploadOutput { s.Key = &v @@ -8286,6 +8369,13 @@ func (s *DeleteBucketAnalyticsConfigurationInput) SetBucket(v string) *DeleteBuc return s } +func (s *DeleteBucketAnalyticsConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *DeleteBucketAnalyticsConfigurationInput) SetId(v string) *DeleteBucketAnalyticsConfigurationInput { s.Id = &v @@ -8344,6 +8434,13 @@ func (s *DeleteBucketCorsInput) SetBucket(v string) *DeleteBucketCorsInput { return s } +func (s *DeleteBucketCorsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCorsOutput type DeleteBucketCorsOutput struct { _ struct{} `type:"structure"` @@ -8396,6 +8493,13 @@ func (s *DeleteBucketInput) SetBucket(v string) *DeleteBucketInput { return s } +func (s *DeleteBucketInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfigurationRequest type DeleteBucketInventoryConfigurationInput struct { _ struct{} `type:"structure"` @@ -8443,6 +8547,13 @@ func (s *DeleteBucketInventoryConfigurationInput) SetBucket(v string) *DeleteBuc return s } +func (s *DeleteBucketInventoryConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *DeleteBucketInventoryConfigurationInput) SetId(v string) *DeleteBucketInventoryConfigurationInput { s.Id = &v @@ -8501,6 +8612,13 @@ func (s *DeleteBucketLifecycleInput) SetBucket(v string) *DeleteBucketLifecycleI return s } +func (s *DeleteBucketLifecycleInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycleOutput type DeleteBucketLifecycleOutput struct { _ struct{} `type:"structure"` @@ -8563,6 +8681,13 @@ func (s *DeleteBucketMetricsConfigurationInput) SetBucket(v string) *DeleteBucke return s } +func (s *DeleteBucketMetricsConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *DeleteBucketMetricsConfigurationInput) SetId(v string) *DeleteBucketMetricsConfigurationInput { s.Id = &v @@ -8636,6 +8761,13 @@ func (s *DeleteBucketPolicyInput) SetBucket(v string) *DeleteBucketPolicyInput { return s } +func (s *DeleteBucketPolicyInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicyOutput type DeleteBucketPolicyOutput struct { _ struct{} `type:"structure"` @@ -8688,6 +8820,13 @@ func (s *DeleteBucketReplicationInput) SetBucket(v string) *DeleteBucketReplicat return s } +func (s *DeleteBucketReplicationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplicationOutput type DeleteBucketReplicationOutput struct { _ struct{} `type:"structure"` @@ -8740,6 +8879,13 @@ func (s *DeleteBucketTaggingInput) SetBucket(v string) *DeleteBucketTaggingInput return s } +func (s *DeleteBucketTaggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTaggingOutput type DeleteBucketTaggingOutput struct { _ struct{} `type:"structure"` @@ -8792,6 +8938,13 @@ func (s *DeleteBucketWebsiteInput) SetBucket(v string) *DeleteBucketWebsiteInput return s } +func (s *DeleteBucketWebsiteInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsiteOutput type DeleteBucketWebsiteOutput struct { _ struct{} `type:"structure"` @@ -8926,6 +9079,13 @@ func (s *DeleteObjectInput) SetBucket(v string) *DeleteObjectInput { return s } +func (s *DeleteObjectInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *DeleteObjectInput) SetKey(v string) *DeleteObjectInput { s.Key = &v @@ -9044,6 +9204,13 @@ func (s *DeleteObjectTaggingInput) SetBucket(v string) *DeleteObjectTaggingInput return s } +func (s *DeleteObjectTaggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *DeleteObjectTaggingInput) SetKey(v string) *DeleteObjectTaggingInput { s.Key = &v @@ -9088,7 +9255,7 @@ type DeleteObjectsInput struct { Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Delete is a required field - Delete *Delete `locationName:"Delete" type:"structure" required:"true"` + Delete *Delete `locationName:"Delete" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` // The concatenation of the authentication device's serial number, a space, // and the value that is displayed on your authentication device. @@ -9138,6 +9305,13 @@ func (s *DeleteObjectsInput) SetBucket(v string) *DeleteObjectsInput { return s } +func (s *DeleteObjectsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetDelete sets the Delete field's value. func (s *DeleteObjectsInput) SetDelete(v *Delete) *DeleteObjectsInput { s.Delete = v @@ -9287,6 +9461,13 @@ func (s *Destination) SetBucket(v string) *Destination { return s } +func (s *Destination) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetStorageClass sets the StorageClass field's value. func (s *Destination) SetStorageClass(v string) *Destination { s.StorageClass = &v @@ -9457,6 +9638,13 @@ func (s *GetBucketAccelerateConfigurationInput) SetBucket(v string) *GetBucketAc return s } +func (s *GetBucketAccelerateConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfigurationOutput type GetBucketAccelerateConfigurationOutput struct { _ struct{} `type:"structure"` @@ -9518,6 +9706,13 @@ func (s *GetBucketAclInput) SetBucket(v string) *GetBucketAclInput { return s } +func (s *GetBucketAclInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAclOutput type GetBucketAclOutput struct { _ struct{} `type:"structure"` @@ -9597,6 +9792,13 @@ func (s *GetBucketAnalyticsConfigurationInput) SetBucket(v string) *GetBucketAna return s } +func (s *GetBucketAnalyticsConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *GetBucketAnalyticsConfigurationInput) SetId(v string) *GetBucketAnalyticsConfigurationInput { s.Id = &v @@ -9664,6 +9866,13 @@ func (s *GetBucketCorsInput) SetBucket(v string) *GetBucketCorsInput { return s } +func (s *GetBucketCorsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCorsOutput type GetBucketCorsOutput struct { _ struct{} `type:"structure"` @@ -9734,6 +9943,13 @@ func (s *GetBucketInventoryConfigurationInput) SetBucket(v string) *GetBucketInv return s } +func (s *GetBucketInventoryConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *GetBucketInventoryConfigurationInput) SetId(v string) *GetBucketInventoryConfigurationInput { s.Id = &v @@ -9801,6 +10017,13 @@ func (s *GetBucketLifecycleConfigurationInput) SetBucket(v string) *GetBucketLif return s } +func (s *GetBucketLifecycleConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfigurationOutput type GetBucketLifecycleConfigurationOutput struct { _ struct{} `type:"structure"` @@ -9861,6 +10084,13 @@ func (s *GetBucketLifecycleInput) SetBucket(v string) *GetBucketLifecycleInput { return s } +func (s *GetBucketLifecycleInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleOutput type GetBucketLifecycleOutput struct { _ struct{} `type:"structure"` @@ -9921,6 +10151,13 @@ func (s *GetBucketLocationInput) SetBucket(v string) *GetBucketLocationInput { return s } +func (s *GetBucketLocationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocationOutput type GetBucketLocationOutput struct { _ struct{} `type:"structure"` @@ -9981,6 +10218,13 @@ func (s *GetBucketLoggingInput) SetBucket(v string) *GetBucketLoggingInput { return s } +func (s *GetBucketLoggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLoggingOutput type GetBucketLoggingOutput struct { _ struct{} `type:"structure"` @@ -10051,6 +10295,13 @@ func (s *GetBucketMetricsConfigurationInput) SetBucket(v string) *GetBucketMetri return s } +func (s *GetBucketMetricsConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *GetBucketMetricsConfigurationInput) SetId(v string) *GetBucketMetricsConfigurationInput { s.Id = &v @@ -10120,6 +10371,13 @@ func (s *GetBucketNotificationConfigurationRequest) SetBucket(v string) *GetBuck return s } +func (s *GetBucketNotificationConfigurationRequest) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyRequest type GetBucketPolicyInput struct { _ struct{} `type:"structure"` @@ -10157,6 +10415,13 @@ func (s *GetBucketPolicyInput) SetBucket(v string) *GetBucketPolicyInput { return s } +func (s *GetBucketPolicyInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyOutput type GetBucketPolicyOutput struct { _ struct{} `type:"structure" payload:"Policy"` @@ -10218,6 +10483,13 @@ func (s *GetBucketReplicationInput) SetBucket(v string) *GetBucketReplicationInp return s } +func (s *GetBucketReplicationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplicationOutput type GetBucketReplicationOutput struct { _ struct{} `type:"structure" payload:"ReplicationConfiguration"` @@ -10280,6 +10552,13 @@ func (s *GetBucketRequestPaymentInput) SetBucket(v string) *GetBucketRequestPaym return s } +func (s *GetBucketRequestPaymentInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPaymentOutput type GetBucketRequestPaymentOutput struct { _ struct{} `type:"structure"` @@ -10341,6 +10620,13 @@ func (s *GetBucketTaggingInput) SetBucket(v string) *GetBucketTaggingInput { return s } +func (s *GetBucketTaggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTaggingOutput type GetBucketTaggingOutput struct { _ struct{} `type:"structure"` @@ -10402,6 +10688,13 @@ func (s *GetBucketVersioningInput) SetBucket(v string) *GetBucketVersioningInput return s } +func (s *GetBucketVersioningInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioningOutput type GetBucketVersioningOutput struct { _ struct{} `type:"structure"` @@ -10474,6 +10767,13 @@ func (s *GetBucketWebsiteInput) SetBucket(v string) *GetBucketWebsiteInput { return s } +func (s *GetBucketWebsiteInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsiteOutput type GetBucketWebsiteOutput struct { _ struct{} `type:"structure"` @@ -10576,6 +10876,13 @@ func (s *GetObjectAclInput) SetBucket(v string) *GetObjectAclInput { return s } +func (s *GetObjectAclInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *GetObjectAclInput) SetKey(v string) *GetObjectAclInput { s.Key = &v @@ -10749,6 +11056,13 @@ func (s *GetObjectInput) SetBucket(v string) *GetObjectInput { return s } +func (s *GetObjectInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetIfMatch sets the IfMatch field's value. func (s *GetObjectInput) SetIfMatch(v string) *GetObjectInput { s.IfMatch = &v @@ -10845,6 +11159,13 @@ func (s *GetObjectInput) SetSSECustomerKey(v string) *GetObjectInput { return s } +func (s *GetObjectInput) getSSECustomerKey() (v string) { + if s.SSECustomerKey == nil { + return v + } + return *s.SSECustomerKey +} + // SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value. func (s *GetObjectInput) SetSSECustomerKeyMD5(v string) *GetObjectInput { s.SSECustomerKeyMD5 = &v @@ -11189,6 +11510,13 @@ func (s *GetObjectTaggingInput) SetBucket(v string) *GetObjectTaggingInput { return s } +func (s *GetObjectTaggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *GetObjectTaggingInput) SetKey(v string) *GetObjectTaggingInput { s.Key = &v @@ -11285,6 +11613,13 @@ func (s *GetObjectTorrentInput) SetBucket(v string) *GetObjectTorrentInput { return s } +func (s *GetObjectTorrentInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *GetObjectTorrentInput) SetKey(v string) *GetObjectTorrentInput { s.Key = &v @@ -11373,7 +11708,7 @@ func (s *GlacierJobParameters) SetTier(v string) *GlacierJobParameters { type Grant struct { _ struct{} `type:"structure"` - Grantee *Grantee `type:"structure"` + Grantee *Grantee `type:"structure" xmlPrefix:"xsi" xmlURI:"http://www.w3.org/2001/XMLSchema-instance"` // Specifies the permission given to the grantee. Permission *string `type:"string" enum:"Permission"` @@ -11528,6 +11863,13 @@ func (s *HeadBucketInput) SetBucket(v string) *HeadBucketInput { return s } +func (s *HeadBucketInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucketOutput type HeadBucketOutput struct { _ struct{} `type:"structure"` @@ -11639,6 +11981,13 @@ func (s *HeadObjectInput) SetBucket(v string) *HeadObjectInput { return s } +func (s *HeadObjectInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetIfMatch sets the IfMatch field's value. func (s *HeadObjectInput) SetIfMatch(v string) *HeadObjectInput { s.IfMatch = &v @@ -11699,6 +12048,13 @@ func (s *HeadObjectInput) SetSSECustomerKey(v string) *HeadObjectInput { return s } +func (s *HeadObjectInput) getSSECustomerKey() (v string) { + if s.SSECustomerKey == nil { + return v + } + return *s.SSECustomerKey +} + // SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value. func (s *HeadObjectInput) SetSSECustomerKeyMD5(v string) *HeadObjectInput { s.SSECustomerKeyMD5 = &v @@ -12317,6 +12673,13 @@ func (s *InventoryS3BucketDestination) SetBucket(v string) *InventoryS3BucketDes return s } +func (s *InventoryS3BucketDestination) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetFormat sets the Format field's value. func (s *InventoryS3BucketDestination) SetFormat(v string) *InventoryS3BucketDestination { s.Format = &v @@ -12847,6 +13210,13 @@ func (s *ListBucketAnalyticsConfigurationsInput) SetBucket(v string) *ListBucket return s } +func (s *ListBucketAnalyticsConfigurationsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetContinuationToken sets the ContinuationToken field's value. func (s *ListBucketAnalyticsConfigurationsInput) SetContinuationToken(v string) *ListBucketAnalyticsConfigurationsInput { s.ContinuationToken = &v @@ -12953,6 +13323,13 @@ func (s *ListBucketInventoryConfigurationsInput) SetBucket(v string) *ListBucket return s } +func (s *ListBucketInventoryConfigurationsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetContinuationToken sets the ContinuationToken field's value. func (s *ListBucketInventoryConfigurationsInput) SetContinuationToken(v string) *ListBucketInventoryConfigurationsInput { s.ContinuationToken = &v @@ -13059,6 +13436,13 @@ func (s *ListBucketMetricsConfigurationsInput) SetBucket(v string) *ListBucketMe return s } +func (s *ListBucketMetricsConfigurationsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetContinuationToken sets the ContinuationToken field's value. func (s *ListBucketMetricsConfigurationsInput) SetContinuationToken(v string) *ListBucketMetricsConfigurationsInput { s.ContinuationToken = &v @@ -13234,6 +13618,13 @@ func (s *ListMultipartUploadsInput) SetBucket(v string) *ListMultipartUploadsInp return s } +func (s *ListMultipartUploadsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetDelimiter sets the Delimiter field's value. func (s *ListMultipartUploadsInput) SetDelimiter(v string) *ListMultipartUploadsInput { s.Delimiter = &v @@ -13331,6 +13722,13 @@ func (s *ListMultipartUploadsOutput) SetBucket(v string) *ListMultipartUploadsOu return s } +func (s *ListMultipartUploadsOutput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetCommonPrefixes sets the CommonPrefixes field's value. func (s *ListMultipartUploadsOutput) SetCommonPrefixes(v []*CommonPrefix) *ListMultipartUploadsOutput { s.CommonPrefixes = v @@ -13458,6 +13856,13 @@ func (s *ListObjectVersionsInput) SetBucket(v string) *ListObjectVersionsInput { return s } +func (s *ListObjectVersionsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetDelimiter sets the Delimiter field's value. func (s *ListObjectVersionsInput) SetDelimiter(v string) *ListObjectVersionsInput { s.Delimiter = &v @@ -13685,6 +14090,13 @@ func (s *ListObjectsInput) SetBucket(v string) *ListObjectsInput { return s } +func (s *ListObjectsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetDelimiter sets the Delimiter field's value. func (s *ListObjectsInput) SetDelimiter(v string) *ListObjectsInput { s.Delimiter = &v @@ -13897,6 +14309,13 @@ func (s *ListObjectsV2Input) SetBucket(v string) *ListObjectsV2Input { return s } +func (s *ListObjectsV2Input) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetContinuationToken sets the ContinuationToken field's value. func (s *ListObjectsV2Input) SetContinuationToken(v string) *ListObjectsV2Input { s.ContinuationToken = &v @@ -14146,6 +14565,13 @@ func (s *ListPartsInput) SetBucket(v string) *ListPartsInput { return s } +func (s *ListPartsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *ListPartsInput) SetKey(v string) *ListPartsInput { s.Key = &v @@ -14253,6 +14679,13 @@ func (s *ListPartsOutput) SetBucket(v string) *ListPartsOutput { return s } +func (s *ListPartsOutput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetInitiator sets the Initiator field's value. func (s *ListPartsOutput) SetInitiator(v *Initiator) *ListPartsOutput { s.Initiator = v @@ -15136,7 +15569,7 @@ type PutBucketAccelerateConfigurationInput struct { // Specifies the Accelerate Configuration you want to set for the bucket. // // AccelerateConfiguration is a required field - AccelerateConfiguration *AccelerateConfiguration `locationName:"AccelerateConfiguration" type:"structure" required:"true"` + AccelerateConfiguration *AccelerateConfiguration `locationName:"AccelerateConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` // Name of the bucket for which the accelerate configuration is set. // @@ -15182,6 +15615,13 @@ func (s *PutBucketAccelerateConfigurationInput) SetBucket(v string) *PutBucketAc return s } +func (s *PutBucketAccelerateConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfigurationOutput type PutBucketAccelerateConfigurationOutput struct { _ struct{} `type:"structure"` @@ -15204,7 +15644,7 @@ type PutBucketAclInput struct { // The canned ACL to apply to the bucket. ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"` - AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure"` + AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` @@ -15272,6 +15712,13 @@ func (s *PutBucketAclInput) SetBucket(v string) *PutBucketAclInput { return s } +func (s *PutBucketAclInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetGrantFullControl sets the GrantFullControl field's value. func (s *PutBucketAclInput) SetGrantFullControl(v string) *PutBucketAclInput { s.GrantFullControl = &v @@ -15324,7 +15771,7 @@ type PutBucketAnalyticsConfigurationInput struct { // The configuration and any analyses for the analytics filter. // // AnalyticsConfiguration is a required field - AnalyticsConfiguration *AnalyticsConfiguration `locationName:"AnalyticsConfiguration" type:"structure" required:"true"` + AnalyticsConfiguration *AnalyticsConfiguration `locationName:"AnalyticsConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` // The name of the bucket to which an analytics configuration is stored. // @@ -15383,6 +15830,13 @@ func (s *PutBucketAnalyticsConfigurationInput) SetBucket(v string) *PutBucketAna return s } +func (s *PutBucketAnalyticsConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *PutBucketAnalyticsConfigurationInput) SetId(v string) *PutBucketAnalyticsConfigurationInput { s.Id = &v @@ -15412,7 +15866,7 @@ type PutBucketCorsInput struct { Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // CORSConfiguration is a required field - CORSConfiguration *CORSConfiguration `locationName:"CORSConfiguration" type:"structure" required:"true"` + CORSConfiguration *CORSConfiguration `locationName:"CORSConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15452,6 +15906,13 @@ func (s *PutBucketCorsInput) SetBucket(v string) *PutBucketCorsInput { return s } +func (s *PutBucketCorsInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetCORSConfiguration sets the CORSConfiguration field's value. func (s *PutBucketCorsInput) SetCORSConfiguration(v *CORSConfiguration) *PutBucketCorsInput { s.CORSConfiguration = v @@ -15490,7 +15951,7 @@ type PutBucketInventoryConfigurationInput struct { // Specifies the inventory configuration. // // InventoryConfiguration is a required field - InventoryConfiguration *InventoryConfiguration `locationName:"InventoryConfiguration" type:"structure" required:"true"` + InventoryConfiguration *InventoryConfiguration `locationName:"InventoryConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15533,6 +15994,13 @@ func (s *PutBucketInventoryConfigurationInput) SetBucket(v string) *PutBucketInv return s } +func (s *PutBucketInventoryConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *PutBucketInventoryConfigurationInput) SetId(v string) *PutBucketInventoryConfigurationInput { s.Id = &v @@ -15567,7 +16035,7 @@ type PutBucketLifecycleConfigurationInput struct { // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` - LifecycleConfiguration *BucketLifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure"` + LifecycleConfiguration *BucketLifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15604,6 +16072,13 @@ func (s *PutBucketLifecycleConfigurationInput) SetBucket(v string) *PutBucketLif return s } +func (s *PutBucketLifecycleConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetLifecycleConfiguration sets the LifecycleConfiguration field's value. func (s *PutBucketLifecycleConfigurationInput) SetLifecycleConfiguration(v *BucketLifecycleConfiguration) *PutBucketLifecycleConfigurationInput { s.LifecycleConfiguration = v @@ -15632,7 +16107,7 @@ type PutBucketLifecycleInput struct { // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` - LifecycleConfiguration *LifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure"` + LifecycleConfiguration *LifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15669,6 +16144,13 @@ func (s *PutBucketLifecycleInput) SetBucket(v string) *PutBucketLifecycleInput { return s } +func (s *PutBucketLifecycleInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetLifecycleConfiguration sets the LifecycleConfiguration field's value. func (s *PutBucketLifecycleInput) SetLifecycleConfiguration(v *LifecycleConfiguration) *PutBucketLifecycleInput { s.LifecycleConfiguration = v @@ -15698,7 +16180,7 @@ type PutBucketLoggingInput struct { Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // BucketLoggingStatus is a required field - BucketLoggingStatus *BucketLoggingStatus `locationName:"BucketLoggingStatus" type:"structure" required:"true"` + BucketLoggingStatus *BucketLoggingStatus `locationName:"BucketLoggingStatus" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15738,6 +16220,13 @@ func (s *PutBucketLoggingInput) SetBucket(v string) *PutBucketLoggingInput { return s } +func (s *PutBucketLoggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetBucketLoggingStatus sets the BucketLoggingStatus field's value. func (s *PutBucketLoggingInput) SetBucketLoggingStatus(v *BucketLoggingStatus) *PutBucketLoggingInput { s.BucketLoggingStatus = v @@ -15776,7 +16265,7 @@ type PutBucketMetricsConfigurationInput struct { // Specifies the metrics configuration. // // MetricsConfiguration is a required field - MetricsConfiguration *MetricsConfiguration `locationName:"MetricsConfiguration" type:"structure" required:"true"` + MetricsConfiguration *MetricsConfiguration `locationName:"MetricsConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15819,6 +16308,13 @@ func (s *PutBucketMetricsConfigurationInput) SetBucket(v string) *PutBucketMetri return s } +func (s *PutBucketMetricsConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetId sets the Id field's value. func (s *PutBucketMetricsConfigurationInput) SetId(v string) *PutBucketMetricsConfigurationInput { s.Id = &v @@ -15857,7 +16353,7 @@ type PutBucketNotificationConfigurationInput struct { // this element is empty, notifications are turned off on the bucket. // // NotificationConfiguration is a required field - NotificationConfiguration *NotificationConfiguration `locationName:"NotificationConfiguration" type:"structure" required:"true"` + NotificationConfiguration *NotificationConfiguration `locationName:"NotificationConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15897,6 +16393,13 @@ func (s *PutBucketNotificationConfigurationInput) SetBucket(v string) *PutBucket return s } +func (s *PutBucketNotificationConfigurationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetNotificationConfiguration sets the NotificationConfiguration field's value. func (s *PutBucketNotificationConfigurationInput) SetNotificationConfiguration(v *NotificationConfiguration) *PutBucketNotificationConfigurationInput { s.NotificationConfiguration = v @@ -15926,7 +16429,7 @@ type PutBucketNotificationInput struct { Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // NotificationConfiguration is a required field - NotificationConfiguration *NotificationConfigurationDeprecated `locationName:"NotificationConfiguration" type:"structure" required:"true"` + NotificationConfiguration *NotificationConfigurationDeprecated `locationName:"NotificationConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -15961,6 +16464,13 @@ func (s *PutBucketNotificationInput) SetBucket(v string) *PutBucketNotificationI return s } +func (s *PutBucketNotificationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetNotificationConfiguration sets the NotificationConfiguration field's value. func (s *PutBucketNotificationInput) SetNotificationConfiguration(v *NotificationConfigurationDeprecated) *PutBucketNotificationInput { s.NotificationConfiguration = v @@ -16027,6 +16537,13 @@ func (s *PutBucketPolicyInput) SetBucket(v string) *PutBucketPolicyInput { return s } +func (s *PutBucketPolicyInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetPolicy sets the Policy field's value. func (s *PutBucketPolicyInput) SetPolicy(v string) *PutBucketPolicyInput { s.Policy = &v @@ -16059,7 +16576,7 @@ type PutBucketReplicationInput struct { // replication configuration size can be up to 2 MB. // // ReplicationConfiguration is a required field - ReplicationConfiguration *ReplicationConfiguration `locationName:"ReplicationConfiguration" type:"structure" required:"true"` + ReplicationConfiguration *ReplicationConfiguration `locationName:"ReplicationConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -16099,6 +16616,13 @@ func (s *PutBucketReplicationInput) SetBucket(v string) *PutBucketReplicationInp return s } +func (s *PutBucketReplicationInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetReplicationConfiguration sets the ReplicationConfiguration field's value. func (s *PutBucketReplicationInput) SetReplicationConfiguration(v *ReplicationConfiguration) *PutBucketReplicationInput { s.ReplicationConfiguration = v @@ -16128,7 +16652,7 @@ type PutBucketRequestPaymentInput struct { Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // RequestPaymentConfiguration is a required field - RequestPaymentConfiguration *RequestPaymentConfiguration `locationName:"RequestPaymentConfiguration" type:"structure" required:"true"` + RequestPaymentConfiguration *RequestPaymentConfiguration `locationName:"RequestPaymentConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -16168,6 +16692,13 @@ func (s *PutBucketRequestPaymentInput) SetBucket(v string) *PutBucketRequestPaym return s } +func (s *PutBucketRequestPaymentInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetRequestPaymentConfiguration sets the RequestPaymentConfiguration field's value. func (s *PutBucketRequestPaymentInput) SetRequestPaymentConfiguration(v *RequestPaymentConfiguration) *PutBucketRequestPaymentInput { s.RequestPaymentConfiguration = v @@ -16197,7 +16728,7 @@ type PutBucketTaggingInput struct { Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // Tagging is a required field - Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true"` + Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -16237,6 +16768,13 @@ func (s *PutBucketTaggingInput) SetBucket(v string) *PutBucketTaggingInput { return s } +func (s *PutBucketTaggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetTagging sets the Tagging field's value. func (s *PutBucketTaggingInput) SetTagging(v *Tagging) *PutBucketTaggingInput { s.Tagging = v @@ -16270,7 +16808,7 @@ type PutBucketVersioningInput struct { MFA *string `location:"header" locationName:"x-amz-mfa" type:"string"` // VersioningConfiguration is a required field - VersioningConfiguration *VersioningConfiguration `locationName:"VersioningConfiguration" type:"structure" required:"true"` + VersioningConfiguration *VersioningConfiguration `locationName:"VersioningConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -16305,6 +16843,13 @@ func (s *PutBucketVersioningInput) SetBucket(v string) *PutBucketVersioningInput return s } +func (s *PutBucketVersioningInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetMFA sets the MFA field's value. func (s *PutBucketVersioningInput) SetMFA(v string) *PutBucketVersioningInput { s.MFA = &v @@ -16340,7 +16885,7 @@ type PutBucketWebsiteInput struct { Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` // WebsiteConfiguration is a required field - WebsiteConfiguration *WebsiteConfiguration `locationName:"WebsiteConfiguration" type:"structure" required:"true"` + WebsiteConfiguration *WebsiteConfiguration `locationName:"WebsiteConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` } // String returns the string representation @@ -16380,6 +16925,13 @@ func (s *PutBucketWebsiteInput) SetBucket(v string) *PutBucketWebsiteInput { return s } +func (s *PutBucketWebsiteInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetWebsiteConfiguration sets the WebsiteConfiguration field's value. func (s *PutBucketWebsiteInput) SetWebsiteConfiguration(v *WebsiteConfiguration) *PutBucketWebsiteInput { s.WebsiteConfiguration = v @@ -16408,7 +16960,7 @@ type PutObjectAclInput struct { // The canned ACL to apply to the object. ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"` - AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure"` + AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` @@ -16494,6 +17046,13 @@ func (s *PutObjectAclInput) SetBucket(v string) *PutObjectAclInput { return s } +func (s *PutObjectAclInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetGrantFullControl sets the GrantFullControl field's value. func (s *PutObjectAclInput) SetGrantFullControl(v string) *PutObjectAclInput { s.GrantFullControl = &v @@ -16716,6 +17275,13 @@ func (s *PutObjectInput) SetBucket(v string) *PutObjectInput { return s } +func (s *PutObjectInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetCacheControl sets the CacheControl field's value. func (s *PutObjectInput) SetCacheControl(v string) *PutObjectInput { s.CacheControl = &v @@ -16812,6 +17378,13 @@ func (s *PutObjectInput) SetSSECustomerKey(v string) *PutObjectInput { return s } +func (s *PutObjectInput) getSSECustomerKey() (v string) { + if s.SSECustomerKey == nil { + return v + } + return *s.SSECustomerKey +} + // SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value. func (s *PutObjectInput) SetSSECustomerKeyMD5(v string) *PutObjectInput { s.SSECustomerKeyMD5 = &v @@ -16954,7 +17527,7 @@ type PutObjectTaggingInput struct { Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"` // Tagging is a required field - Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true"` + Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` VersionId *string `location:"querystring" locationName:"versionId" type:"string"` } @@ -17002,6 +17575,13 @@ func (s *PutObjectTaggingInput) SetBucket(v string) *PutObjectTaggingInput { return s } +func (s *PutObjectTaggingInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *PutObjectTaggingInput) SetKey(v string) *PutObjectTaggingInput { s.Key = &v @@ -17488,7 +18068,7 @@ type RestoreObjectInput struct { // at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"` - RestoreRequest *RestoreRequest `locationName:"RestoreRequest" type:"structure"` + RestoreRequest *RestoreRequest `locationName:"RestoreRequest" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` VersionId *string `location:"querystring" locationName:"versionId" type:"string"` } @@ -17533,6 +18113,13 @@ func (s *RestoreObjectInput) SetBucket(v string) *RestoreObjectInput { return s } +func (s *RestoreObjectInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetKey sets the Key field's value. func (s *RestoreObjectInput) SetKey(v string) *RestoreObjectInput { s.Key = &v @@ -18008,7 +18595,7 @@ func (s *Tagging) SetTagSet(v []*Tag) *Tagging { type TargetGrant struct { _ struct{} `type:"structure"` - Grantee *Grantee `type:"structure"` + Grantee *Grantee `type:"structure" xmlPrefix:"xsi" xmlURI:"http://www.w3.org/2001/XMLSchema-instance"` // Logging permissions assigned to the Grantee for the bucket. Permission *string `type:"string" enum:"BucketLogsPermission"` @@ -18348,6 +18935,13 @@ func (s *UploadPartCopyInput) SetBucket(v string) *UploadPartCopyInput { return s } +func (s *UploadPartCopyInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetCopySource sets the CopySource field's value. func (s *UploadPartCopyInput) SetCopySource(v string) *UploadPartCopyInput { s.CopySource = &v @@ -18396,6 +18990,13 @@ func (s *UploadPartCopyInput) SetCopySourceSSECustomerKey(v string) *UploadPartC return s } +func (s *UploadPartCopyInput) getCopySourceSSECustomerKey() (v string) { + if s.CopySourceSSECustomerKey == nil { + return v + } + return *s.CopySourceSSECustomerKey +} + // SetCopySourceSSECustomerKeyMD5 sets the CopySourceSSECustomerKeyMD5 field's value. func (s *UploadPartCopyInput) SetCopySourceSSECustomerKeyMD5(v string) *UploadPartCopyInput { s.CopySourceSSECustomerKeyMD5 = &v @@ -18432,6 +19033,13 @@ func (s *UploadPartCopyInput) SetSSECustomerKey(v string) *UploadPartCopyInput { return s } +func (s *UploadPartCopyInput) getSSECustomerKey() (v string) { + if s.SSECustomerKey == nil { + return v + } + return *s.SSECustomerKey +} + // SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value. func (s *UploadPartCopyInput) SetSSECustomerKeyMD5(v string) *UploadPartCopyInput { s.SSECustomerKeyMD5 = &v @@ -18631,6 +19239,13 @@ func (s *UploadPartInput) SetBucket(v string) *UploadPartInput { return s } +func (s *UploadPartInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + // SetContentLength sets the ContentLength field's value. func (s *UploadPartInput) SetContentLength(v int64) *UploadPartInput { s.ContentLength = &v @@ -18667,6 +19282,13 @@ func (s *UploadPartInput) SetSSECustomerKey(v string) *UploadPartInput { return s } +func (s *UploadPartInput) getSSECustomerKey() (v string) { + if s.SSECustomerKey == nil { + return v + } + return *s.SSECustomerKey +} + // SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value. func (s *UploadPartInput) SetSSECustomerKeyMD5(v string) *UploadPartInput { s.SSECustomerKeyMD5 = &v diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go b/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go index c3a2702dad4..bc68a46acfa 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go @@ -12,6 +12,69 @@ import ( var reBucketLocation = regexp.MustCompile(`>([^<>]+)<\/Location`) +// NormalizeBucketLocation is a utility function which will update the +// passed in value to always be a region ID. Generally this would be used +// with GetBucketLocation API operation. +// +// Replaces empty string with "us-east-1", and "EU" with "eu-west-1". +// +// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html +// for more information on the values that can be returned. +func NormalizeBucketLocation(loc string) string { + switch loc { + case "": + loc = "us-east-1" + case "EU": + loc = "eu-west-1" + } + + return loc +} + +// NormalizeBucketLocationHandler is a request handler which will update the +// GetBucketLocation's result LocationConstraint value to always be a region ID. +// +// Replaces empty string with "us-east-1", and "EU" with "eu-west-1". +// +// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html +// for more information on the values that can be returned. +// +// req, result := svc.GetBucketLocationRequest(&s3.GetBucketLocationInput{ +// Bucket: aws.String(bucket), +// }) +// req.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler) +// err := req.Send() +var NormalizeBucketLocationHandler = request.NamedHandler{ + Name: "awssdk.s3.NormalizeBucketLocation", + Fn: func(req *request.Request) { + if req.Error != nil { + return + } + + out := req.Data.(*GetBucketLocationOutput) + loc := NormalizeBucketLocation(aws.StringValue(out.LocationConstraint)) + out.LocationConstraint = aws.String(loc) + }, +} + +// WithNormalizeBucketLocation is a request option which will update the +// GetBucketLocation's result LocationConstraint value to always be a region ID. +// +// Replaces empty string with "us-east-1", and "EU" with "eu-west-1". +// +// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html +// for more information on the values that can be returned. +// +// result, err := svc.GetBucketLocationWithContext(ctx, +// &s3.GetBucketLocationInput{ +// Bucket: aws.String(bucket), +// }, +// s3.WithNormalizeBucketLocation, +// ) +func WithNormalizeBucketLocation(r *request.Request) { + r.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler) +} + func buildGetBucketLocation(r *request.Request) { if r.DataFilled() { out := r.Data.(*GetBucketLocationOutput) @@ -24,7 +87,7 @@ func buildGetBucketLocation(r *request.Request) { match := reBucketLocation.FindSubmatch(b) if len(match) > 1 { loc := string(match[1]) - out.LocationConstraint = &loc + out.LocationConstraint = aws.String(loc) } } } diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go index 84633472303..899d5e8d108 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go @@ -44,3 +44,21 @@ func defaultInitRequestFn(r *request.Request) { r.Handlers.Unmarshal.PushFront(copyMultipartStatusOKUnmarhsalError) } } + +// bucketGetter is an accessor interface to grab the "Bucket" field from +// an S3 type. +type bucketGetter interface { + getBucket() string +} + +// sseCustomerKeyGetter is an accessor interface to grab the "SSECustomerKey" +// field from an S3 type. +type sseCustomerKeyGetter interface { + getSSECustomerKey() string +} + +// copySourceSSECustomerKeyGetter is an accessor interface to grab the +// "CopySourceSSECustomerKey" field from an S3 type. +type copySourceSSECustomerKeyGetter interface { + getCopySourceSSECustomerKey() string +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go b/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go new file mode 100644 index 00000000000..f045fd0db9d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go @@ -0,0 +1,78 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package s3 provides the client and types for making API +// requests to Amazon Simple Storage Service. +// +// See https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01 for more information on this service. +// +// See s3 package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/ +// +// Using the Client +// +// To use the client for Amazon Simple Storage Service you will first need +// to create a new instance of it. +// +// When creating a client for an AWS service you'll first need to have a Session +// already created. The Session provides configuration that can be shared +// between multiple service clients. Additional configuration can be applied to +// the Session and service's client when they are constructed. The aws package's +// Config type contains several fields such as Region for the AWS Region the +// client should make API requests too. The optional Config value can be provided +// as the variadic argument for Sessions and client creation. +// +// Once the service's client is created you can use it to make API requests the +// AWS service. These clients are safe to use concurrently. +// +// // Create a session to share configuration, and load external configuration. +// sess := session.Must(session.NewSession()) +// +// // Create the service's client with the session. +// svc := s3.New(sess) +// +// See the SDK's documentation for more information on how to use service clients. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws package's Config type for more information on configuration options. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon Simple Storage Service client S3 for more +// information on creating the service's client. +// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#New +// +// Once the client is created you can make an API request to the service. +// Each API method takes a input parameter, and returns the service response +// and an error. +// +// The API method will document which error codes the service can be returned +// by the operation if the service models the API operation's errors. These +// errors will also be available as const strings prefixed with "ErrCode". +// +// result, err := svc.AbortMultipartUpload(params) +// if err != nil { +// // Cast err to awserr.Error to handle specific error codes. +// aerr, ok := err.(awserr.Error) +// if ok && aerr.Code() == { +// // Specific error code handling +// } +// return err +// } +// +// fmt.Println("AbortMultipartUpload result:") +// fmt.Println(result) +// +// Using the Client with Context +// +// The service's client also provides methods to make API requests with a Context +// value. This allows you to control the timeout, and cancellation of pending +// requests. These methods also take request Option as variadic parameter to apply +// additional configuration to the API request. +// +// ctx := context.Background() +// +// result, err := svc.AbortMultipartUploadWithContext(ctx, params) +// +// See the request package documentation for more information on using Context pattern +// with the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/request/ +package s3 diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go b/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go new file mode 100644 index 00000000000..b794a63ba20 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go @@ -0,0 +1,109 @@ +// Upload Managers +// +// The s3manager package's Uploader provides concurrent upload of content to S3 +// by taking advantage of S3's Multipart APIs. The Uploader also supports both +// io.Reader for streaming uploads, and will also take advantage of io.ReadSeeker +// for optimizations if the Body satisfies that type. Once the Uploader instance +// is created you can call Upload concurrently from multiple goroutines safely. +// +// // The session the S3 Uploader will use +// sess := session.Must(session.NewSession()) +// +// // Create an uploader with the session and default options +// uploader := s3manager.NewUploader(sess) +// +// f, err := os.Open(filename) +// if err != nil { +// return fmt.Errorf("failed to open file %q, %v", filename, err) +// } +// +// // Upload the file to S3. +// result, err := uploader.Upload(&s3manager.UploadInput{ +// Bucket: aws.String(myBucket), +// Key: aws.String(myString), +// Body: f, +// }) +// if err != nil { +// return fmt.Errorf("failed to upload file, %v", err) +// } +// fmt.Printf("file uploaded to, %s\n", aws.StringValue(result.Location)) +// +// See the s3manager package's Uploader type documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Uploader +// +// Download Manager +// +// The s3manager package's Downloader provides concurrently downloading of Objects +// from S3. The Downloader will write S3 Object content with an io.WriterAt. +// Once the Downloader instance is created you can call Upload concurrently from +// multiple goroutines safely. +// +// // The session the S3 Downloader will use +// sess := session.Must(session.NewSession()) +// +// // Create a downloader with the session and default options +// downloader := s3manager.NewDownloader(sess) +// +// // Create a file to write the S3 Object contents to. +// f, err := os.Create(filename) +// if err != nil { +// return fmt.Errorf("failed to create file %q, %v", filename, err) +// } +// +// // Write the contents of S3 Object to the file +// n, err := downloader.Download(f, &s3.GetObjectInput{ +// Bucket: aws.String(myBucket), +// Key: aws.String(myString), +// }) +// if err != nil { +// return fmt.Errorf("failed to upload file, %v", err) +// } +// fmt.Printf("file downloaded, %d bytes\n", n) +// +// See the s3manager package's Downloader type documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Downloader +// +// Get Bucket Region +// +// GetBucketRegion will attempt to get the region for a bucket using a region +// hint to determine which AWS partition to perform the query on. Use this utility +// to determine the region a bucket is in. +// +// sess := session.Must(session.NewSession()) +// +// bucket := "my-bucket" +// region, err := s3manager.GetBucketRegion(ctx, sess, bucket, "us-west-2") +// if err != nil { +// if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "NotFound" { +// fmt.Fprintf(os.Stderr, "unable to find bucket %s's region not found\n", bucket) +// } +// return err +// } +// fmt.Printf("Bucket %s is in %s region\n", bucket, region) +// +// See the s3manager package's GetBucketRegion function documentation for more information +// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#GetBucketRegion +// +// S3 Crypto Client +// +// The s3crypto package provides the tools to upload and download encrypted +// content from S3. The Encryption and Decryption clients can be used concurrently +// once the client is created. +// +// sess := session.Must(session.NewSession()) +// +// // Create the decryption client. +// svc := s3crypto.NewDecryptionClient(sess) +// +// // The object will be downloaded from S3 and decrypted locally. By metadata +// // about the object's encryption will instruct the decryption client how +// // decrypt the content of the object. By default KMS is used for keys. +// result, err := svc.GetObject(&s3.GetObjectInput { +// Bucket: aws.String(myBucket), +// Key: aws.String(myKey), +// }) +// +// See the s3crypto package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3crypto/ +// +package s3 diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go b/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go index ec3ffe44841..a7fbc2de2f8 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/aws/request" ) @@ -113,15 +112,9 @@ func updateEndpointForAccelerate(r *request.Request) { // Attempts to retrieve the bucket name from the request input parameters. // If no bucket is found, or the field is empty "", false will be returned. func bucketNameFromReqParams(params interface{}) (string, bool) { - b, _ := awsutil.ValuesAtPath(params, "Bucket") - if len(b) == 0 { - return "", false - } - - if bucket, ok := b[0].(*string); ok { - if bucketStr := aws.StringValue(bucket); bucketStr != "" { - return bucketStr, true - } + if iface, ok := params.(bucketGetter); ok { + b := iface.getBucket() + return b, len(b) > 0 } return "", false diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/service.go b/vendor/github.com/aws/aws-sdk-go/service/s3/service.go index 3fb5b3be7b9..614e477d3bb 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/service.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/service.go @@ -11,10 +11,12 @@ import ( "github.com/aws/aws-sdk-go/private/protocol/restxml" ) -// S3 is a client for Amazon S3. -// The service client's operations are safe to be used concurrently. -// It is not safe to mutate any of the client's properties though. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01 +// S3 provides the API operation methods for making requests to +// Amazon Simple Storage Service. See this package's package overview docs +// for details on the service. +// +// S3 methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. type S3 struct { *client.Client } diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/sse.go b/vendor/github.com/aws/aws-sdk-go/service/s3/sse.go index 268ea2fb459..8010c4fa196 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/sse.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/sse.go @@ -5,17 +5,27 @@ import ( "encoding/base64" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/aws/request" ) var errSSERequiresSSL = awserr.New("ConfigError", "cannot send SSE keys over HTTP.", nil) func validateSSERequiresSSL(r *request.Request) { - if r.HTTPRequest.URL.Scheme != "https" { - p, _ := awsutil.ValuesAtPath(r.Params, "SSECustomerKey||CopySourceSSECustomerKey") - if len(p) > 0 { + if r.HTTPRequest.URL.Scheme == "https" { + return + } + + if iface, ok := r.Params.(sseCustomerKeyGetter); ok { + if len(iface.getSSECustomerKey()) > 0 { r.Error = errSSERequiresSSL + return + } + } + + if iface, ok := r.Params.(copySourceSSECustomerKeyGetter); ok { + if len(iface.getCopySourceSSECustomerKey()) > 0 { + r.Error = errSSERequiresSSL + return } } } diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go index 19dd0bf8e59..e5c105fed80 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -1,6 +1,5 @@ // Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. -// Package sts provides a client for AWS Security Token Service. package sts import ( @@ -1086,7 +1085,7 @@ type AssumeRoleInput struct { // // The regex used to validated this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can - // also include underscores or any of the following characters: =,.@:\/- + // also include underscores or any of the following characters: =,.@:/- ExternalId *string `min:"2" type:"string"` // An IAM policy in JSON format. @@ -2270,9 +2269,9 @@ type GetSessionTokenInput struct { // You can find the device for an IAM user by going to the AWS Management Console // and viewing the user's security credentials. // - // The regex used to validate this parameter is a string of characters consisting + // The regex used to validated this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can - // also include underscores or any of the following characters: =,.@- + // also include underscores or any of the following characters: =,.@:/- SerialNumber *string `min:"9" type:"string"` // The value provided by the MFA device, if MFA is required. If any policy requires diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go new file mode 100644 index 00000000000..d2af518cfad --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go @@ -0,0 +1,124 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package sts provides the client and types for making API +// requests to AWS Security Token Service. +// +// The AWS Security Token Service (STS) is a web service that enables you to +// request temporary, limited-privilege credentials for AWS Identity and Access +// Management (IAM) users or for users that you authenticate (federated users). +// This guide provides descriptions of the STS API. For more detailed information +// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). +// +// As an alternative to using the API, you can use one of the AWS SDKs, which +// consist of libraries and sample code for various programming languages and +// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient +// way to create programmatic access to STS. For example, the SDKs take care +// of cryptographically signing requests, managing errors, and retrying requests +// automatically. For information about the AWS SDKs, including how to download +// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/). +// +// For information about setting up signatures and authorization through the +// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) +// in the AWS General Reference. For general information about the Query API, +// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) +// in Using IAM. For information about using security tokens with other AWS +// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) +// in the IAM User Guide. +// +// If you're new to AWS and need additional technical information about a specific +// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/ +// (http://aws.amazon.com/documentation/). +// +// Endpoints +// +// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com +// that maps to the US East (N. Virginia) region. Additional regions are available +// and are activated by default. For more information, see Activating and Deactivating +// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region) +// in the AWS General Reference. +// +// Recording API requests +// +// STS supports AWS CloudTrail, which is a service that records AWS calls for +// your AWS account and delivers log files to an Amazon S3 bucket. By using +// information collected by CloudTrail, you can determine what requests were +// successfully made to STS, who made the request, when it was made, and so +// on. To learn more about CloudTrail, including how to turn it on and find +// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). +// +// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service. +// +// See sts package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/ +// +// Using the Client +// +// To use the client for AWS Security Token Service you will first need +// to create a new instance of it. +// +// When creating a client for an AWS service you'll first need to have a Session +// already created. The Session provides configuration that can be shared +// between multiple service clients. Additional configuration can be applied to +// the Session and service's client when they are constructed. The aws package's +// Config type contains several fields such as Region for the AWS Region the +// client should make API requests too. The optional Config value can be provided +// as the variadic argument for Sessions and client creation. +// +// Once the service's client is created you can use it to make API requests the +// AWS service. These clients are safe to use concurrently. +// +// // Create a session to share configuration, and load external configuration. +// sess := session.Must(session.NewSession()) +// +// // Create the service's client with the session. +// svc := sts.New(sess) +// +// See the SDK's documentation for more information on how to use service clients. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws package's Config type for more information on configuration options. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the AWS Security Token Service client STS for more +// information on creating the service's client. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#New +// +// Once the client is created you can make an API request to the service. +// Each API method takes a input parameter, and returns the service response +// and an error. +// +// The API method will document which error codes the service can be returned +// by the operation if the service models the API operation's errors. These +// errors will also be available as const strings prefixed with "ErrCode". +// +// result, err := svc.AssumeRole(params) +// if err != nil { +// // Cast err to awserr.Error to handle specific error codes. +// aerr, ok := err.(awserr.Error) +// if ok && aerr.Code() == { +// // Specific error code handling +// } +// return err +// } +// +// fmt.Println("AssumeRole result:") +// fmt.Println(result) +// +// Using the Client with Context +// +// The service's client also provides methods to make API requests with a Context +// value. This allows you to control the timeout, and cancellation of pending +// requests. These methods also take request Option as variadic parameter to apply +// additional configuration to the API request. +// +// ctx := context.Background() +// +// result, err := svc.AssumeRoleWithContext(ctx, params) +// +// See the request package documentation for more information on using Context pattern +// with the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/request/ +package sts diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/service.go b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go index be2183846ef..1ee5839e046 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/service.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go @@ -11,54 +11,12 @@ import ( "github.com/aws/aws-sdk-go/private/protocol/query" ) -// The AWS Security Token Service (STS) is a web service that enables you to -// request temporary, limited-privilege credentials for AWS Identity and Access -// Management (IAM) users or for users that you authenticate (federated users). -// This guide provides descriptions of the STS API. For more detailed information -// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). +// STS provides the API operation methods for making requests to +// AWS Security Token Service. See this package's package overview docs +// for details on the service. // -// As an alternative to using the API, you can use one of the AWS SDKs, which -// consist of libraries and sample code for various programming languages and -// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient -// way to create programmatic access to STS. For example, the SDKs take care -// of cryptographically signing requests, managing errors, and retrying requests -// automatically. For information about the AWS SDKs, including how to download -// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/). -// -// For information about setting up signatures and authorization through the -// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) -// in the AWS General Reference. For general information about the Query API, -// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) -// in Using IAM. For information about using security tokens with other AWS -// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) -// in the IAM User Guide. -// -// If you're new to AWS and need additional technical information about a specific -// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/ -// (http://aws.amazon.com/documentation/). -// -// Endpoints -// -// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com -// that maps to the US East (N. Virginia) region. Additional regions are available -// and are activated by default. For more information, see Activating and Deactivating -// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) -// in the IAM User Guide. -// -// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region) -// in the AWS General Reference. -// -// Recording API requests -// -// STS supports AWS CloudTrail, which is a service that records AWS calls for -// your AWS account and delivers log files to an Amazon S3 bucket. By using -// information collected by CloudTrail, you can determine what requests were -// successfully made to STS, who made the request, when it was made, and so -// on. To learn more about CloudTrail, including how to turn it on and find -// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). -// The service client's operations are safe to be used concurrently. -// It is not safe to mutate any of the client's properties though. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 +// STS methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. type STS struct { *client.Client } diff --git a/vendor/vendor.json b/vendor/vendor.json index 73c45eeb7cf..5a60e70f653 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -13,148 +13,156 @@ "revisionTime": "2017-02-13T07:20:14Z" }, { - "checksumSHA1": "6nleggdedlS1mdzSnu1xf1Pnd+8=", + "checksumSHA1": "9CCPEzYQkmeL5Dn7e99Mjxw1IVc=", "path": "github.com/aws/aws-sdk-go", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "kf/pd5o5Gl4JZoOwGvgVBQzVbdQ=", + "checksumSHA1": "WklPj1YaT3LzeGnbvA7VNhQcUnc=", "path": "github.com/aws/aws-sdk-go/aws", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "yyYr41HZ1Aq0hWc3J5ijXwYEcac=", "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "iThCyNRL/oQFD9CF2SYgBGl+aww=", + "checksumSHA1": "n98FANpNeRT5kf6pizdpI7nm6Sw=", "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "0Gfk83qXYimO87ZoK1lL9+ifWHo=", + "checksumSHA1": "7/8j/q0TWtOgXyvEcv4B2Dhl00o=", "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "P7gt3PNk6bDOoTZ2N9QOonkaGWw=", + "checksumSHA1": "Y+cPwQL0dZMyqp3wI+KJWmA9KQ8=", "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "6cj/zsRmcxkE1TLS+v910GbQYg0=", + "checksumSHA1": "JEYqmF83O5n5bHkupAzA6STm0no=", "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "l2O7P/kvovK2zxKhuFehFNXLk+Q=", + "checksumSHA1": "ZdtYh3ZHSgP/WEIaqwJHTEhpkbs=", "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "/EXbk/z2TWjWc1Hvb4QYs3Wmhb8=", "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "+yCOae0vRONrO27QiITkGWblOKk=", + "checksumSHA1": "rxRJvIS15Xx01dqHiNopR+TB2hw=", "path": "github.com/aws/aws-sdk-go/aws/endpoints", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "/L6UweKsmfyHTu01qrFD1ijzSbE=", + "checksumSHA1": "P6f+a0npro0KI5CESeKTWhRtBuE=", "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "5pzA5afgeU1alfACFh8z2CDUMao=", + "checksumSHA1": "Y20DEtMtbfE9qTtmoi2NYV1x7aA=", "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "SvIsunO8D9MEKbetMENA4WRnyeE=", + "checksumSHA1": "1+ZxEwzc1Vz8X2l+kXkS2iATtas=", "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" + }, + { + "checksumSHA1": "04ypv4x12l4q0TksA1zEVsmgpvw=", + "path": "github.com/aws/aws-sdk-go/internal/shareddefaults", + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "Esab5F8KswqkTdB4TtjSvZgs56k=", "path": "github.com/aws/aws-sdk-go/private/endpoints", "revision": "898c81ba64b9a467379d35e3fabad133beae0ee4", "revisionTime": "2016-11-18T23:08:35Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "UkXRa4++RD0AA3UaS8WflQNOm4U=", @@ -165,196 +173,196 @@ "versionExact": "v1.8.11" }, { - "checksumSHA1": "9cMa8SQME8+G/4fM9J/LQZMy6SM=", + "checksumSHA1": "YTTdK2GuBtUbrSvJisR+elXEhOo=", "path": "github.com/aws/aws-sdk-go/private/model/api", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "Zmy1WMdxZAYJ6Wpnffxz30s2eQ8=", "path": "github.com/aws/aws-sdk-go/private/model/cli/api-info", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "RJ9LoVEemry+7+RVuklcg1PEDoo=", + "checksumSHA1": "Cvj+ie4UcH9G9GGrvqz014mUsDw=", "path": "github.com/aws/aws-sdk-go/private/model/cli/gen-api", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "UgCLu0g+9s+6cCe+BquyzAz7sRA=", "path": "github.com/aws/aws-sdk-go/private/model/cli/gen-endpoints", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "wk7EyvDaHwb5qqoOP/4d3cV0708=", "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "O6hcK24yI6w7FA+g4Pbr+eQ7pys=", "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "Drt1JfLMa0DQEZLWrnMlTWaIcC8=", "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "VCTh+dEaqqhog5ncy/WTt9+/gFM=", "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "Rpu8KBtHZgvhkwHxUfaky+qW+G4=", "path": "github.com/aws/aws-sdk-go/private/protocol/restjson", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "lZ1z4xAbT8euCzKoAsnEYic60VE=", + "checksumSHA1": "0qYPUga28aQVkxZgBR3Z86AbGUQ=", "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "F6mth+G7dXN1GI+nktaGo8Lx8aE=", "path": "github.com/aws/aws-sdk-go/private/signer/v2", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "01b4hmyUzoReoOyEDylDinWBSdA=", "path": "github.com/aws/aws-sdk-go/private/util", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", "path": "github.com/aws/aws-sdk-go/private/waiter", "revision": "898c81ba64b9a467379d35e3fabad133beae0ee4", "revisionTime": "2016-11-18T23:08:35Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "aGx2atOHEXSowjXUQ3UoJ/t2LSI=", + "checksumSHA1": "0actRsVcKehoBlcKWIjclcq41Zg=", "path": "github.com/aws/aws-sdk-go/service/cloudwatch", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "kSXrrHPfK1VaFSAxeNDOkwu7X2U=", + "checksumSHA1": "pqg/2Udv19hEhusEM6saFiNUjMk=", "path": "github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "2PIG7uhrvvDAjiNZINBVCgW/Uds=", + "checksumSHA1": "nlw/uUZMqn6O42Kgmf/2g/d48yY=", "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "RHxlu8clKOe30r18os5gd8dZzyE=", + "checksumSHA1": "Wyrgm7VPmms8JTGCQ94jla7SQXM=", "path": "github.com/aws/aws-sdk-go/service/ec2/ec2iface", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "o7qpn0kxj43Ej/RwfCb9JbzfbfQ=", + "checksumSHA1": "2ow2XQ9RCOgOwyJKHt7bibwWv8M=", "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { - "checksumSHA1": "SdsHiTUR9eRarThv/i7y6/rVyF4=", + "checksumSHA1": "VH5y62f+SDyEIqnTibiPtQ687i8=", "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "Tw/kOijtL1ptv5MHMIWSsXrWayg=", "path": "github.com/aws/aws-sdk-go/service/sts/stsiface", - "revision": "200fde3f632bb9f036ec0b8cb29fbc8588155ea5", - "revisionTime": "2017-04-07T21:28:24Z", - "version": "v1.8.11", - "versionExact": "v1.8.11" + "revision": "5e436e55ac5eddc739f26a2a209b3f4248ee8e0e", + "revisionTime": "2017-07-27T22:05:08Z", + "version": "v1.10.18", + "versionExact": "v1.10.18" }, { "checksumSHA1": "cVyhKIRI2gQrgpn5qrBeAqErmWM=", @@ -500,12 +508,6 @@ "revision": "5db88ed452e937f2fd557de6f4f1af7f2eabed0b", "revisionTime": "2016-08-23T18:01:44Z" }, - { - "checksumSHA1": "1MGpGDQqnUoRpv7VEcQrXOBydXE=", - "path": "golang.org/x/crypto/pbkdf2", - "revision": "3543873453996aaab2fc6b3928a35fc5ca2b5afb", - "revisionTime": "2017-04-18T16:44:36Z" - }, { "checksumSHA1": "r7o16T0WQ/XSe2mlQuioMi8gxbw=", "path": "github.com/yudai/gojsondiff", @@ -524,6 +526,12 @@ "revision": "d1c525dea8ce39ea9a783d33cf08932305373f2c", "revisionTime": "2015-04-05T16:34:35Z" }, + { + "checksumSHA1": "1MGpGDQqnUoRpv7VEcQrXOBydXE=", + "path": "golang.org/x/crypto/pbkdf2", + "revision": "3543873453996aaab2fc6b3928a35fc5ca2b5afb", + "revisionTime": "2017-04-18T16:44:36Z" + }, { "checksumSHA1": "WHc3uByvGaMcnSoI21fhzYgbOgg=", "path": "golang.org/x/net/context/ctxhttp", From 0fcc87010ab732079ed4f78912abc1fc8a73637c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 31 Jul 2017 22:30:49 +0200 Subject: [PATCH 167/179] fix: cloudwatch fix for templating namespace argument to metrics tempalting function, fixes #8965 --- public/app/plugins/datasource/cloudwatch/datasource.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/datasource/cloudwatch/datasource.js b/public/app/plugins/datasource/cloudwatch/datasource.js index 60c7e167a06..c3ecc2e5594 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.js +++ b/public/app/plugins/datasource/cloudwatch/datasource.js @@ -210,12 +210,12 @@ function (angular, _, moment, dateMath, kbn, templatingVariable, CloudWatchAnnot var metricNameQuery = query.match(/^metrics\(([^\)]+?)(,\s?([^,]+?))?\)/); if (metricNameQuery) { - return this.getMetrics(metricNameQuery[1], metricNameQuery[3]); + return this.getMetrics(templateSrv.replace(metricNameQuery[1]), templateSrv.replace(metricNameQuery[3])); } var dimensionKeysQuery = query.match(/^dimension_keys\(([^\)]+?)(,\s?([^,]+?))?\)/); if (dimensionKeysQuery) { - return this.getDimensionKeys(dimensionKeysQuery[1], dimensionKeysQuery[3]); + return this.getDimensionKeys(templateSrv.replace(dimensionKeysQuery[1]), templateSrv.replace(dimensionKeysQuery[3])); } var dimensionValuesQuery = query.match(/^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?),\s?([^,]+?)\)/); From e9989cb690da3491621c72fbf08dac459e06fd4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 31 Jul 2017 22:33:22 +0200 Subject: [PATCH 168/179] fix: make it easier to close search by clicking outside result container, fixes #8848 --- public/app/core/components/grafana_app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/core/components/grafana_app.ts b/public/app/core/components/grafana_app.ts index 5a677094754..f910e124a49 100644 --- a/public/app/core/components/grafana_app.ts +++ b/public/app/core/components/grafana_app.ts @@ -192,7 +192,7 @@ export function grafanaAppDirective(playlistSrv, contextSrv) { // hide search if (body.find('.search-container').length > 0) { - if (target.parents('.search-container').length === 0) { + if (target.parents('.search-results-container').length === 0) { scope.$apply(function() { scope.appEvent('hide-dash-search'); }); From 7de1c0eaa20891243534abe1ebf49b510b16ffd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 31 Jul 2017 22:37:11 +0200 Subject: [PATCH 169/179] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 957e75e7e91..60e994f0405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ * **InfluxDB**: Wrong username/password parameter name when using direct access, fixes [#8789](https://github.com/grafana/grafana/issues/8789) * **Forms(TextArea)**: Bug fix for no scroll in text areas [#8797](https://github.com/grafana/grafana/issues/8797) * **Png Render API**: Bug fix for timeout url parameter. It now works as it should. Default value was also increased from 30 to 60 seconds [#8710](https://github.com/grafana/grafana/issues/8710) +* **Search**: Fux fir not being able to close search by clicking on right side of search result container, [8848](https://github.com/grafana/grafana/issues/8848) +* **Cloudwatch**: Fix for using variables in templating metrics() query, [8965](https://github.com/grafana/grafana/issues/8965) ## Changes From c4eadb576e99a244294c0c4ca0596b580a35a097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 31 Jul 2017 22:39:44 +0200 Subject: [PATCH 170/179] fix: graphite bug fix introduced in recent commit --- public/app/plugins/datasource/graphite/datasource.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/graphite/datasource.ts b/public/app/plugins/datasource/graphite/datasource.ts index fe0082cb10c..40573db4234 100644 --- a/public/app/plugins/datasource/graphite/datasource.ts +++ b/public/app/plugins/datasource/graphite/datasource.ts @@ -160,7 +160,8 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv return date.unix(); }; - this.metricFindQuery = function(query, options) { + this.metricFindQuery = function(query, optionalOptions) { + let options = optionalOptions || {}; let interpolatedQuery = templateSrv.replace(query); let httpOptions: any = { From 6d9cbdd59ea3922a555fca383c2002d6a9fe4a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 1 Aug 2017 09:14:49 +0200 Subject: [PATCH 171/179] updated version to v4.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cef722ca56e..52de1007d0b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Coding Instinct AB" }, "name": "grafana", - "version": "4.4.1", + "version": "4.4.2", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git" From 9fb22ef86c461c46299f1638f895b032f32713ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 1 Aug 2017 09:44:45 +0200 Subject: [PATCH 172/179] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60e994f0405..84f0f723f72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ * **GitHub OAuth**: Support for GitHub organizations with 100+ teams. [#8846](https://github.com/grafana/grafana/issues/8846), thx [@skwashd](https://github.com/skwashd) * **Graphite**: Calls to Graphite api /metrics/find now include panel or dashboad time range (from & until) in most cases, [#8055](https://github.com/grafana/grafana/issues/8055) -# 4.4.2 (unreleased) +# 4.4.2 (2017-08-01) ## Bug Fixes From ecfe28d7ac07b65530b3b58e27ebfd0bd0deb476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 1 Aug 2017 09:49:26 +0200 Subject: [PATCH 173/179] packaging: added strech to publish script, closes #8737 --- .gitignore | 2 ++ packaging/publish/publish_both.sh | 4 +++- packaging/publish/publish_testing.sh | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 08cfb7a2931..0e6affc6120 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ profile.cov /pkg/cmd/grafana-cli/grafana-cli /pkg/cmd/grafana-server/grafana-server /examples/*/dist +/packaging/**/*.rpm +/packaging/**/*.deb diff --git a/packaging/publish/publish_both.sh b/packaging/publish/publish_both.sh index 4acaaa9ca95..f4bf299a612 100755 --- a/packaging/publish/publish_both.sh +++ b/packaging/publish/publish_both.sh @@ -1,13 +1,15 @@ #! /usr/bin/env bash -version=4.4.1 +version=4.4.2 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${version}_amd64.deb package_cloud push grafana/stable/debian/jessie grafana_${version}_amd64.deb package_cloud push grafana/stable/debian/wheezy grafana_${version}_amd64.deb +package_cloud push grafana/stable/debian/stretch grafana_${version}_amd64.deb package_cloud push grafana/testing/debian/jessie grafana_${version}_amd64.deb package_cloud push grafana/testing/debian/wheezy grafana_${version}_amd64.deb +package_cloud push grafana/testing/debian/stretch grafana_${version}_amd64.deb wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-${version}-1.x86_64.rpm diff --git a/packaging/publish/publish_testing.sh b/packaging/publish/publish_testing.sh index 8d27a35b826..bf109c96420 100755 --- a/packaging/publish/publish_testing.sh +++ b/packaging/publish/publish_testing.sh @@ -6,6 +6,7 @@ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${deb_v package_cloud push grafana/testing/debian/jessie grafana_${deb_ver}_amd64.deb package_cloud push grafana/testing/debian/wheezy grafana_${deb_ver}_amd64.deb +package_cloud push grafana/testing/debian/stretch grafana_${deb_ver}_amd64.deb wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-${rpm_ver}.x86_64.rpm From ae3e869d7043075bd429465507616baa998deb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 1 Aug 2017 10:18:48 +0200 Subject: [PATCH 174/179] updated download links in docs --- docs/sources/archive.md | 2 ++ docs/sources/installation/debian.md | 6 +++--- docs/sources/installation/rpm.md | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/sources/archive.md b/docs/sources/archive.md index 7102395f4c7..8ed38b933e6 100644 --- a/docs/sources/archive.md +++ b/docs/sources/archive.md @@ -14,5 +14,7 @@ of Grafana. - [Latest](http://docs.grafana.org) - [Version 4.2](http://docs.grafana.org/v4.2) +- [Version 4.1](http://docs.grafana.org/v4.1) +- [Version 4.0](http://docs.grafana.org/v4.0) - [Version 3.1](http://docs.grafana.org/v3.1) - [Version 3.0](http://docs.grafana.org/v3.0) diff --git a/docs/sources/installation/debian.md b/docs/sources/installation/debian.md index a002661bcd4..388fe3834f0 100644 --- a/docs/sources/installation/debian.md +++ b/docs/sources/installation/debian.md @@ -15,7 +15,7 @@ weight = 1 Description | Download ------------ | ------------- -Stable for Debian-based Linux | [grafana_4.4.1_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.4.1_amd64.deb) +Stable for Debian-based Linux | [grafana_4.4.2_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.4.2_amd64.deb) Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing installation. @@ -23,9 +23,9 @@ installation. ## Install Stable ```bash -wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.4.1_amd64.deb +wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.4.2_amd64.deb sudo apt-get install -y adduser libfontconfig -sudo dpkg -i grafana_4.4.1_amd64.deb +sudo dpkg -i grafana_4.4.2_amd64.deb ```