Compare commits

...

1857 Commits

Author SHA1 Message Date
Torkel Ödegaard c643466d57 bumped version to v4-beta2 2016-11-21 09:51:59 +01:00
bergquist 2b6013ce81 fix(notifications): failed image upload should not stop notification
closes #6638
2016-11-21 09:47:59 +01:00
Torkel Ödegaard 6fa4b8c0b6 Merge branch 'master' of github.com:grafana/grafana 2016-11-21 09:42:46 +01:00
Torkel Ödegaard 8d80812601 Merge branch 'issue-6566' of https://github.com/benrubson/grafana into benrubson-issue-6566 2016-11-21 09:39:35 +01:00
benrubson e71114f4fb Come back to #6287 for graph_tooltip.js
as it is an only one loop solution
2016-11-19 09:12:10 +01:00
benrubson 9797845460 Typo 2016-11-18 19:14:12 +01:00
benrubson 0034b6ede7 Highlight correct point when series has null values 2016-11-18 18:49:20 +01:00
benrubson 1eb0ea3450 Correctly stack series with null and missing values 2016-11-18 18:14:40 +01:00
benrubson becb6303e5 Revert #6287 for graph_tooltip.js 2016-11-18 17:50:54 +01:00
bergquist 5dea0fda51 fix(settings): remove nil pointer exception 2016-11-18 16:43:14 +01:00
benrubson 850d39fc50 Revert #6287 for jquery.flot.stack.js 2016-11-18 16:32:00 +01:00
bergquist 61bb9cbc13 test(alerting): fixes broken unit test 2016-11-18 10:53:27 +01:00
bergquist a3b0fbcaba fix(influxdb): fixes broken tag rendering for influxdb alerting
closes #6626
ref #6523
2016-11-17 15:50:49 +01:00
Torkel Ödegaard 7ce33c31ec Merge branch 'master' of github.com:grafana/grafana 2016-11-17 15:50:08 +01:00
Torkel Ödegaard b9cfb19ab8 changelog(): added entry for PR #6579 2016-11-17 15:50:00 +01:00
Torkel Ödegaard e34bf9a1fa Merge branch 'utkarshcmu-or_alerting' 2016-11-17 15:49:52 +01:00
Torkel Ödegaard 62e8a039a1 refactor(alerting): refactoring PR for OR conditions, #6579 2016-11-17 15:48:15 +01:00
bergquist 3ea66ebe3f fix(alerting): remove possible divide by zero panic
ref #6599
2016-11-17 15:20:14 +01:00
Torkel Ödegaard 457ae74343 Merge branch 'or_alerting' of https://github.com/utkarshcmu/grafana into utkarshcmu-or_alerting 2016-11-17 14:43:24 +01:00
Torkel Ödegaard 98d1748e43 fix(templating): work on fixing exporting issues when using templating variables, like data source variables, and panel repeats, requires more work #6189 2016-11-17 12:32:11 +01:00
Torkel Ödegaard 9d5928ddd6 feat(templating): don't persist template variable options when variable has refresh enabled, closes #6586 2016-11-17 11:38:06 +01:00
Torkel Ödegaard eafe0d6bfa fix(templating): fixed issue when adding template variable, fixes #6622 2016-11-17 11:28:33 +01:00
utkarshcmu aae33b36dd Added tests for firingEvaluation string 2016-11-17 01:41:23 -08:00
Torkel Ödegaard 196fdbfd31 fix(dashboard): fixed issue when dragging new panel to drop zone 2016-11-17 10:31:37 +01:00
utkarshcmu fc82dac868 Added braces to single condition firingEvaluation string 2016-11-17 01:30:50 -08:00
utkarshcmu 690868c837 Added firingEvalution to Rule test 2016-11-17 01:28:17 -08:00
Torkel Ödegaard a45fdfdd3f fix(dashboard): minor fixes, and restored in-activity timer to 1min 2016-11-17 10:11:59 +01:00
Torkel Ödegaard 42167a65c6 testdata(): added test graph for null stacking scenario, #6566 2016-11-16 19:00:23 +01:00
Torkel Ödegaard f52c6aafe7 docs(): minor update to centos docs about font packages needed for phantomjs 2016-11-16 18:49:14 +01:00
Torkel Ödegaard 4581bb4a7a fix(singletat): Support repeated template variables in prefix/postfix, fixes #6595 2016-11-16 18:44:39 +01:00
Torkel Ödegaard e6776f71d9 cleanup(sass): removed tight-form styles 2016-11-16 18:26:39 +01:00
Torkel Ödegaard d7e8753c59 cleanup(): removed unused gfbox style 2016-11-16 18:08:45 +01:00
Torkel Ödegaard 079b0ef44a change(alerting): delete alert rule from panel model when duplicating panel 2016-11-16 18:03:00 +01:00
Torkel Ödegaard a50178eab1 ux(tweak): minor polish to date picker styling 2016-11-16 17:56:42 +01:00
Torkel Ödegaard f64385cfc9 ux(tweak): minor polish to date picker styling 2016-11-16 17:53:56 +01:00
Torkel Ödegaard 465451c289 cleanup(): removed unused uio-angular tab component 2016-11-16 17:47:37 +01:00
Torkel Ödegaard 18e965c775 fix(error handling): fixed server side error handling page 2016-11-16 17:41:44 +01:00
Torkel Ödegaard e3564d12a1 fix(404): fixed 404 page 2016-11-16 17:09:00 +01:00
Dan Cech c980efd470 fix up sass lint warnings (#6603) 2016-11-16 17:08:38 +01:00
Dan Cech eacb7c8aba Merge pull request #6584 from tomkozlowski/bugfix/oauth-login-bearer-token
explicitly set oauth2 token to Bearer Type
2016-11-16 10:35:32 -05:00
Torkel Ödegaard e7a30ac464 fix(units): fixed issue with data rate bit units, fixes #6602 2016-11-16 16:29:10 +01:00
Tom Kozlowski a353c8d1bb added explicitly setting token as Bearer Type 2016-11-16 09:55:14 -05:00
Torkel Ödegaard 4fa995eafa ux(view/tv mode): treat tab change as user activity, resets in activity timer 2016-11-16 14:44:55 +01:00
Torkel Ödegaard 9c7f8268dc fix(build): fixed failing unit test 2016-11-16 14:39:17 +01:00
Torkel Ödegaard 171335bfef fix(ux): fixed dropzone display issues, fixes #6598 2016-11-16 14:28:52 +01:00
bergquist e12a4f6b46 docs(notifications): fixes typo 2016-11-16 10:55:47 +01:00
Mitsuhiro Tanda 9740752c1e (cloudwatch) long retention support (#6547) 2016-11-16 10:50:33 +01:00
Matt Toback 10cf32f835 Removed green border from OK alerts. Makes dashboards too busy, competes for attention where action is unnceessary (#6555) 2016-11-16 10:50:01 +01:00
Torkel Ödegaard f91a833e6a fix(panel): set initial transparency state at first link 2016-11-16 09:44:16 +01:00
bergquist cbe8af967d docs(api): add docs about creating new org
close #6588
2016-11-16 09:06:32 +01:00
utkarshcmu f46c4c88ca Added OR condition in docs 2016-11-15 22:43:09 -08:00
Ben RUBSON a4de6da9a0 Correct series highlight (#6578)
solves issue #6573
2016-11-15 18:59:17 +01:00
utkarshcmu 8d0bcd23f8 Added tests for checking nested operators 2016-11-15 08:07:05 -08:00
utkarshcmu dfb1b1918c Implemented operator based firiing in backend 2016-11-15 06:35:25 -08:00
bergquist b9d709ab27 feat(alerting): improve error logging for extracting alerts
ref #6576
2016-11-15 11:47:46 +01:00
Torkel Ödegaard 05c5a09f63 docs(): updated changelog 2016-11-15 08:46:30 +01:00
utkarshcmu b2db2b26dd Added OR to alert_tab 2016-11-14 18:36:22 -08:00
Carl Bergquist 6e94ccea07 Merge pull request #6569 from nicr9/patch-1
docs(datasources/influxdb): Fix broken image link
2016-11-14 17:25:52 +01:00
Nic Roland 0cdf05ae5d docs(datasources/influxdb): Fix broken image link
Twas missing a leading `/`.
2016-11-14 16:04:33 +00:00
Torkel Ödegaard 62ff85e774 docs(): fixed ldap link 2016-11-14 11:34:58 +01:00
bergquist 4fdfee739a fix(influxdb): add support for regex measurments
closes #6560
2016-11-14 08:48:19 +01:00
bergquist a87fd11f26 feat(stats): add alerts to global admin stats 2016-11-11 14:04:38 +01:00
bergquist ad97db937c feat(stats_usage): add stats about alerts 2016-11-11 13:57:11 +01:00
Carl Bergquist 08429d9a08 Merge pull request #6546 from huydx/master
Fix typo (password strenght -> password strength)
2016-11-11 10:31:04 +01:00
huydx f5a804a558 Fix typo (password strenght -> password strength) 2016-11-11 18:02:58 +09:00
Andrew McDonald b98f817d68 Fix for cloudwatch datasource requesting too many datapoints (#6544)
The range checking in _getPeriod appeared to be using a different variable than the period that had just been calculated for its bounds checks.
2016-11-11 08:54:44 +01:00
bergquist e04d27c0b0 fix(influxdb): return internal influxdb errors
ref #6523
2016-11-11 08:47:53 +01:00
Carl Bergquist b824fa1916 Merge pull request #6538 from grafana/alertlist_only_from_dashboard
feat(alertlist): make it possible to filter on alerts from current da…
2016-11-10 16:19:12 +01:00
bergquist a51de8e987 tech(conf): remove dragoo :( 2016-11-10 16:15:55 +01:00
bergquist abb8f33d77 feat(alertlist): make it possible to filter on alerts from current dashboard 2016-11-10 16:07:13 +01:00
bergquist f924b241ae tech(influxdb): refactor query builder
trying to reduce the amounts of moving parts for influxdb
2016-11-10 14:38:07 +01:00
bergquist a948dfe514 fix(influxdb): fixes broken raw query usage 2016-11-10 14:18:10 +01:00
Torkel Ödegaard 9f7d0862e8 docs(): minor docs fix 2016-11-10 13:08:32 +01:00
Carl Bergquist a825e63a19 Merge pull request #6515 from grafana/influxdb_alias_seriename
[Influxdb] Backend support for seriename alias
2016-11-10 12:56:53 +01:00
bergquist ecba23e883 Merge branch 'master' into influxdb_alias_seriename 2016-11-10 12:22:17 +01:00
Torkel Ödegaard 6767bdd76d fix(graph): fixed issue log base scale on right y axis, option was not applied at all, also issue with log scale and max value calculation fixed, fixes #6534 2016-11-10 12:04:55 +01:00
Torkel Ödegaard 316d754a21 fix(ui/browser): fixed border not showing in safari, fixes #6530 2016-11-10 11:31:27 +01:00
bergquist 70b9ba2573 tech(build): switch to golang 1.7.3
tls/cipher fixes
https://github.com/golang/go/issues?q=milestone%3AGo1.7.3
2016-11-10 11:30:18 +01:00
bergquist 4f3c8c6663 fix(influxdb): add default operator
ref #6523
2016-11-10 11:21:38 +01:00
Torkel Ödegaard 71eb0f3278 fix(graph): fixed issue with bar width when used in series override, fixes #6528 2016-11-10 10:50:48 +01:00
Ben RUBSON 6495ba155a Correct timeStep in case of missing values (#6526)
* Correct timeStep in case of missing values

* Comment
2016-11-10 10:20:27 +01:00
Ben RUBSON 2443326386 Add some comments about some previous modifications (#6533) 2016-11-10 10:19:42 +01:00
bergquist ef08a243c5 fix(influxdb): fixes possible nil pointer
closes #6531
2016-11-10 08:23:58 +01:00
bergquist 6a8138904e fix(shortcuts): CTRL on windows or linux 2016-11-09 14:48:51 +01:00
bergquist 82e1d3f6aa feat(influxdb): disable debug logging in appmode 2016-11-09 14:48:05 +01:00
Torkel Ödegaard fff26086d5 docs(): updated install links with beta links as well 2016-11-09 13:53:20 +01:00
Torkel Ödegaard 1d4cace849 fix(testdata): fixed query in default grafana data source 2016-11-09 12:52:56 +01:00
bergquist f0a0e647a0 feat(influxdb): backend support for alias by segment
ref #6510
2016-11-09 12:45:59 +01:00
Torkel Ödegaard d1bedfc1d1 updated version to beta1 2016-11-09 12:10:03 +01:00
Torkel Ödegaard bfed566ea8 changelog(): updated with entry for #2912 and #6287, closes #2912 2016-11-09 11:37:36 +01:00
Torkel Ödegaard a9c6bdc197 panel(graph): stacking can now handle null values, #6287 2016-11-09 11:34:34 +01:00
Torkel Ödegaard 485980eebf Merge branch 'issue-2912' of https://github.com/benrubson/grafana into benrubson-issue-2912 2016-11-09 11:17:04 +01:00
Torkel Ödegaard 33664b0a7e docs(): minor docs change 2016-11-09 11:14:04 +01:00
Torkel Ödegaard 2164bbd447 ux(tv mode): added 1 second delay animation 2016-11-09 10:59:06 +01:00
bergquist 97271514fb feat(influxdb): cleanup influxdb query editor options 2016-11-09 10:30:03 +01:00
bergquist c897d39d5e feat(influxdb): add support for serie alias replacement
ref #6510
2016-11-09 10:22:11 +01:00
bergquist 24a3a100ed feat(influxdb): add alias to query 2016-11-09 10:05:12 +01:00
Torkel Ödegaard 652eb057cf change(graph): change default line width from 2 to 1 2016-11-08 20:57:17 +01:00
Torkel Ödegaard 20d789cb94 docs(): fix title 2016-11-08 20:57:16 +01:00
Torkel Ödegaard d717e0cf13 docs(): minor spelling fix 2016-11-08 20:57:16 +01:00
bergquist 029e52f5a1 docs(pagerduty): update docs regarding pagerduty 2016-11-08 20:41:02 +01:00
bergquist eb34855adb feat(pagerduty): add support for auto resolve
closes #6513
2016-11-08 20:38:38 +01:00
Carl Bergquist 0d729ae392 Merge pull request #6512 from utkarshcmu/pagerduty_bug
Send test notification fixed
2016-11-08 20:30:41 +01:00
utkarshcmu 610ea090dc Send test notification fixed 2016-11-08 11:22:03 -08:00
bergquist 5542b0ab9e tech(pagerduty): sync calls should be using context 2016-11-08 20:05:43 +01:00
bergquist b5c96d2685 style(influxdb): fixes broken layout 2016-11-08 20:02:55 +01:00
bergquist 98a7bf181a tech(influxdb): close body reader 2016-11-08 19:19:49 +01:00
Torkel Ödegaard fd09f17cd3 docs(): alerting docs, #6490 2016-11-08 14:53:28 +01:00
bergquist 8713dd8221 tech(docker): pin elastic to 2.4.1 for dev 2016-11-08 14:31:59 +01:00
Utkarsh Bhatnagar e642dce027 Fixed import dashboard bug (#6480) 2016-11-08 14:03:04 +01:00
Matt Toback b8ad86fabd Alert pulse tweak (#6508)
* Added faint tint of red to alerting panels, started working on animation. more to come

* Finally happy with pulse animation. Ready to merge
2016-11-08 14:02:45 +01:00
bergquist 309391cb79 docs(alerting): not only graphite 2016-11-08 11:24:39 +01:00
bergquist 5445e47fd5 docs(alerting): typo 2016-11-08 11:24:19 +01:00
bergquist 1f2b8044b2 docs(notifications): format as table 2016-11-08 11:14:35 +01:00
Torkel Ödegaard b658f38036 docs(): added what new in v4 article and initial draf of alerting docs, #6490 2016-11-08 11:09:10 +01:00
bergquist 8ca18b511f docs(alerting): add docs for alert notifications 2016-11-08 10:58:59 +01:00
Torkel Ödegaard dea5fd385f ux(alerting): minor wording change on alert tab 2016-11-08 09:34:52 +01:00
Torkel Ödegaard 49af12f69f Merge branch 'master' of github.com:grafana/grafana 2016-11-08 09:31:19 +01:00
Carl Bergquist a7be3b91fd Merge pull request #6499 from utkarshcmu/last
Added last function for alerting conditions
2016-11-08 09:10:35 +01:00
utkarshcmu 841fb74b39 Reversed loop for last function 2016-11-07 23:16:57 -08:00
utkarshcmu 74632b5e98 Added last function for alerting conditions 2016-11-07 23:16:57 -08:00
bergquist 5bbdd99d35 tech(notifications): remove async webhook 2016-11-08 08:06:42 +01:00
bergquist 66f257e382 tech(pagerduty): make api call sync 2016-11-08 07:51:19 +01:00
bergquist 7bc80d0374 tech(pagerduty): declare url as constant 2016-11-08 07:50:58 +01:00
bergquist 6dd076efc1 Merge branch 'alerting_pagerduty' of https://github.com/utkarshcmu/grafana into utkarshcmu-alerting_pagerduty 2016-11-08 07:48:20 +01:00
Carl Bergquist bdcff9d15c Merge pull request #6501 from utkarshcmu/invalid_state
Removed invalid alerting state from the UI
2016-11-08 07:00:55 +01:00
utkarshcmu a7e67f3bdd Removed invalid alerting state 2016-11-07 17:43:13 -08:00
Carl Bergquist 9479364600 Merge pull request #6481 from msound/update-github-auth-documentation
Update github auth docs
2016-11-07 20:42:05 +01:00
Carl Bergquist f7f64fbe95 Merge pull request #6495 from rogerswingle/add-govcloud
Add AWS Govcloud Region
2016-11-07 20:36:38 +01:00
Torkel Ödegaard 901e670db4 docs(): minor tweak 2016-11-07 19:58:30 +01:00
Roger Swingle 69ff13adce add govcloud 2016-11-07 13:56:29 -05:00
utkarshcmu 5549d8658a Fixed description message 2016-11-07 07:27:31 -08:00
utkarshcmu f8d1eb11a9 Removed ExecError state 2016-11-07 07:12:43 -08:00
utkarshcmu 4b53ea0a56 Fixed pagerduty tests 2016-11-07 07:08:52 -08:00
utkarshcmu 638d3bcb42 Removed NoData option 2016-11-07 07:08:51 -08:00
utkarshcmu de0fa3d479 Added pagerduty tests 2016-11-07 07:08:51 -08:00
utkarshcmu df8cd764b2 Added trigger options with Pagerduty 2016-11-07 07:08:51 -08:00
utkarshcmu 139bbecc10 Added Pagerduty basic alerting 2016-11-07 07:08:51 -08:00
Torkel Ödegaard a100836bb4 docs(): Added pages for alerting docs, added keyboard shortcuts doc article, #6490 2016-11-07 15:18:27 +01:00
Carl Bergquist 3607316920 Merge pull request #6489 from bergquist/reduce_notification_states
Reduce alerting states
2016-11-07 15:18:07 +01:00
bergquist b2d8e83c7d fix(alert_tab): better execution state description 2016-11-07 14:54:42 +01:00
bergquist 56340bfdfb fix(influxdb): fixes bug when using regexps/numbers in tags
closes #6488
2016-11-07 14:26:20 +01:00
bergquist d7f11c304c tech(alerting): set prev state when creating eval context 2016-11-07 13:01:54 +01:00
bergquist 489f087fbd feat(alerting): reduce states. Make exeuction result configurable.
ref #6444
2016-11-07 12:42:39 +01:00
bergquist 16e7bfc622 docs(changelog): add note about closing #6292 2016-11-07 08:10:36 +01:00
Carl Bergquist d670f1b959 Merge pull request #6479 from utkarshcmu/playlist_bug
Removed playlist item when dashboard is deleted
2016-11-07 08:00:57 +01:00
bergquist f0b591b89b feat(alerting): extract logic state updates and notifications
ref #6444
2016-11-07 07:57:34 +01:00
Torkel Ödegaard b88791135f sasslint fix 2016-11-06 18:05:01 +01:00
Torkel Ödegaard 907fb9c1be ux(dashboard): fix for dropzone width when resizing another panel 2016-11-06 17:41:17 +01:00
Mani Soundararajan db77dfea7a Update github auth docs
In Github's "allowed organizations" scenario, it makes sense to have
`allow_sign_up` to be `true` as most administrators will expect their
org's github users to be able to sign in without further steps like
creating a local user first.
2016-11-06 20:48:14 +05:30
Torkel Ödegaard 2d19af601a fix(alerting): various alerting fixes 2016-11-06 15:40:02 +01:00
Torkel Ödegaard 05c124bb1e docs(changelog): correct changelog 2016-11-06 11:07:52 +01:00
utkarshcmu c737704eeb Removed playlist item when dashboard is deleted 2016-11-06 01:49:43 -08:00
Torkel Ödegaard 8db40b25db ux(dashboard): final tweaks to view mode and kiosk mode, better animation for view mode, and kiosk mode can be entered via kiosk url parameter, #6476 2016-11-06 10:15:36 +01:00
Torkel Ödegaard bd996a4810 ux(viewmode): refining view mode #6476 2016-11-05 21:05:12 +01:00
Torkel Ödegaard 3df4375e39 docs(changelog): updated changelog with new ux improvements 2016-11-05 14:28:40 +01:00
Torkel Ödegaard d38de2cc8b ux(view/kiosk mode): added view mode and kiosk mode, #6476 2016-11-05 14:23:37 +01:00
Torkel Ödegaard 0d82fb71ad ux(keybindings): updated look of dashboard keybindings help modal, #6465 2016-11-05 12:19:52 +01:00
Torkel Ödegaard aaa174a091 ux(dashboard): minor fix so hide controls hide panel resize handles 2016-11-05 08:32:16 +01:00
Torkel Ödegaard 2b81b204aa docs(): fixing image urls in docs 2016-11-04 20:29:17 +01:00
Torkel Ödegaard 3cc4a194a9 ux(keybindings): polish help modal with keybindings, #6465 2016-11-04 17:19:03 +01:00
Torkel Ödegaard 4ab095b051 fix(ux): fixed issue with row menu gliding over header, or in realting extending outside it's bound and not getttin the menu background 2016-11-04 15:35:32 +01:00
Carl Bergquist 741faa2299 Merge pull request #6468 from utkarshcmu/changelog_entry
Added OpenTSDB nested templating fix entry to CHANGELOG
2016-11-04 15:01:46 +01:00
utkarshcmu a78db041ea Added OpenTSDB nested templating fix to CHANGELOG 2016-11-04 06:57:26 -07:00
Carl Bergquist 8bc0462877 Merge pull request #6467 from utkarshcmu/slack_mention
Added Slack mention feature
2016-11-04 14:14:32 +01:00
utkarshcmu dc3a62da83 Added slack tests , fixed webhook tests 2016-11-04 06:05:44 -07:00
utkarshcmu 2f60929d1e Added slack mention functionality 2016-11-04 06:05:44 -07:00
Torkel Ödegaard 6fa89456d6 build(): updated glob node package 2016-11-04 13:58:06 +01:00
Torkel Ödegaard 2da2d5df56 Merge branch 'master' of github.com:grafana/grafana 2016-11-04 12:15:08 +01:00
Torkel Ödegaard c99f4cb9c5 ux(dashboard): minor cleanup 2016-11-04 12:14:43 +01:00
Torkel Ödegaard 2fa7100c3b ux(dashboard): lots of tweaks and polish to row menu, added remove X to add panel and row option views, #6442 2016-11-04 11:43:49 +01:00
Ryan Bak 7165c866c2 Add blank default options for constant templates (#6460)
Restores ability to change constant templates without going into
templating menu
2016-11-04 11:41:39 +01:00
TerraTech 05d24020b1 settings.html: Fixup filename for custom.ini (#6463) 2016-11-04 11:41:12 +01:00
Carl Bergquist 691956bd33 Merge pull request #6363 from Noah-Heil/patch-1
Added two hints to help newer users
2016-11-04 11:12:20 +01:00
bergquist f0d9d133c6 tech(slack): format code using gofmt 2016-11-04 07:55:15 +01:00
Matt 616e9ce5f6 Changed panel-handle cursor to proper 2 directional 2016-11-03 22:56:39 -04:00
Matt cf248a503b Added panel name to individual add panel item to show full name when long 2016-11-03 17:49:54 -04:00
Matt 80f8c0712c Merge branch 'v4ux' of https://github.com/grafana/grafana into v4ux 2016-11-03 17:41:54 -04:00
Matt 308cc9d9f6 Thinned out fonts for row headers, sits much nicer in the dashboard 2016-11-03 17:41:35 -04:00
Torkel Ödegaard abf1f6a163 ux(dashboard): added back hide controls toggle and shortcut, #6442 2016-11-03 22:39:59 +01:00
Torkel Ödegaard d0513d3a54 ux(dashboard): changed name of delete row to remove row, #6442 2016-11-03 22:32:04 +01:00
Torkel Ödegaard 0da60a8bb2 ux(dashboard): minor tweak to row menu animation, it hides in a better way now after click #6442 2016-11-03 22:29:53 +01:00
Torkel Ödegaard 98be1734fa ux(dashboard): refining new row slide out menu, #6442 2016-11-03 22:14:29 +01:00
Torkel Ödegaard d917f69255 Merge branch 'v4ux' of github.com:grafana/grafana into v4ux 2016-11-03 20:32:45 +01:00
Torkel Ödegaard 82592f0c13 ux(help): began work on new help modal 2016-11-03 20:32:36 +01:00
Matt 4e15e61b39 Added vertical ellipses, played with box shadows and borders and such. Ellipses need to fade to Opacity 0 when menu is open. 2016-11-03 15:12:39 -04:00
bergquist 2d7bb4a9f3 fix(tsdb): broken build :( 2016-11-03 19:20:53 +01:00
bergquist b578d06e4a chore(notification): improve log message 2016-11-03 18:04:50 +01:00
bergquist 1afe0e90f9 fix(tsdb): fixes broken legend buidler for prometheus
closes #6456
2016-11-03 18:04:09 +01:00
bergquist 0059beb85d chore(tsdb): remove commented code 2016-11-03 17:34:57 +01:00
bergquist 4af420f759 tech(alerting): refactor how evalhandler uses conditions 2016-11-03 17:31:36 +01:00
Carl Bergquist 262b806193 Merge pull request #6455 from utkarshcmu/opentsdb_template_fix
Fixed multi-value nested templating for opentsdb
2016-11-03 17:11:52 +01:00
Torkel Ödegaard 3e712178cc ux(dashboard): began removing build mode and adding new slide out row menu 2016-11-03 15:50:11 +01:00
Torkel Ödegaard f91e067235 ux(dashboard): keybinding changes / new, #6442 2016-11-03 15:14:44 +01:00
Torkel Ödegaard 8ea2d3f19c ux(dashboard): removed getting started stuff from dashlist panel, #6442 2016-11-03 13:24:01 +01:00
Torkel Ödegaard e80241b5f4 ux(dashboard): minor tweaks 2016-11-03 13:19:40 +01:00
Torkel Ödegaard f1137e4d20 ux(dashboard): removed green row icon gain, replaced with collapse icon, #6442 2016-11-03 11:30:25 +01:00
Carl Bergquist 61c48aecc2 [Alertlist] Set max-height to respect row height (#6454)
* feat(alertlist): max-height to respect row height

closes #6417

* feat(alertlist): use pre calculated panel.height instead

* style(alertlist): rearrange variable order
2016-11-03 11:01:21 +01:00
utkarshcmu 89cf32b160 Made quotes consistent 2016-11-03 01:22:24 -07:00
utkarshcmu 849ac9441a Fixed multi-value nested templating for opentsdb 2016-11-03 01:18:54 -07:00
bergquist c138b04c5e feat(alerting): avoid double logging 2016-11-03 07:25:00 +01:00
bergquist ff5d4e8e0c fix(alerting): temp fix for broken AND condition
This should be refactored. lets return condition results instead
of setting new value on the evalContext. The condition execution
should only be able to update its own state.

closes #6449
2016-11-03 07:18:39 +01:00
Carl Bergquist 89a3d023ce Merge pull request #6453 from utkarshcmu/alert_message_typo
Log bad alert config and fixed alert message typo
2016-11-03 07:12:36 +01:00
Carl Bergquist bb7f03c91e Merge pull request #6446 from utkarshcmu/graphite_alerting_fix
Fixed intervalFormat for Graphite Alerting
2016-11-03 06:58:51 +01:00
utkarshcmu fc91231104 Fixed failing tests 2016-11-02 22:31:59 -07:00
utkarshcmu d009c6b953 Log bad alert config 2016-11-02 18:22:24 -07:00
utkarshcmu 942de5497e Fixed alert message typo 2016-11-02 18:13:11 -07:00
Torkel Ödegaard 075c722527 ux(dashboard): worked on single row edit mode, #6442 2016-11-02 22:24:08 +01:00
bergquist d1d7c240f9 tech(mailer): dont use deprecated method 2016-11-02 22:11:59 +01:00
Torkel Ödegaard e23f898418 ux(dashboard): minor tweaks and polish, added g a shortcut for go to alerting list 2016-11-02 22:08:17 +01:00
Torkel Ödegaard cdea420285 ux(dashboard): fixes for changing panel tabs, #6442 2016-11-02 21:45:46 +01:00
Carl Bergquist 377d9f4a78 Merge pull request #6452 from utkarshcmu/tooltip_bug
Fixed the tooltip message for slack notifier
2016-11-02 20:46:05 +01:00
utkarshcmu 2b28cf1ff1 Fixed the tooltip message for slack notifier 2016-11-02 12:42:33 -07:00
utkarshcmu 33ee85ede9 Commented strange behavior of tests 2016-11-02 11:11:06 -07:00
Torkel Ödegaard 47aae7f1f2 ux(dashboard): added more shortcusts to v/edit panel, #6442 2016-11-02 17:03:14 +01:00
Torkel Ödegaard 95e7ead89b ux(dashboard): varius dashboard ux fixes and keybinding improvements, press 'e' while hovering over panel will open dashboard in edit mode, pressing 'd' will remove panel, #6442 2016-11-02 15:16:48 +01:00
Torkel Ödegaard 19509d1e7a ux(dashboard): minor fix, #6442 2016-11-02 13:49:12 +01:00
Torkel Ödegaard 40ea014fa8 ux(dashboar): added shortcut for build mode, switched keybinding lib to mousetrap, supports sequences so also added for Go to home dashboard, open search with starred dashbords prefiltered, go to profile, #6442 2016-11-02 12:55:58 +01:00
Torkel Ödegaard 3c1435253d feat(ux dashboard editmode): added shortcut to setting menu, #6442 2016-11-02 11:05:28 +01:00
utkarshcmu a4a2e35bb2 Verified interval format function and gofmt check 2016-11-02 02:07:08 -07:00
bergquist d4bc92b267 feat(tsdb): default tsdb httpclient 2016-11-02 08:51:34 +01:00
utkarshcmu 2088363bf9 Added tests for graphite alerting 2016-11-02 00:00:18 -07:00
utkarshcmu 1e8beb8983 Fixed intervalFormat for Graphite Alerting 2016-11-01 17:55:45 -07:00
bergquist 9b28bf25a4 docs(cli): add info about how to install specific plugin version
closes #6434
2016-11-01 18:35:15 +01:00
Carl Bergquist e659eb745d Merge pull request #6420 from utkarshcmu/alerting_initial_state
Alerts not sent when state is changed from "initialized" to "ok"
2016-11-01 18:30:14 +01:00
Torkel Ödegaard 8980f481f7 fix(ux dashboard): panel height fix to reduce jumpiness when loading dashboard 2016-11-01 16:11:26 +01:00
Torkel Ödegaard 8eee4d8e6b fix(dashboard): fixed white theme for new dashboard row look / dash edit mode, #6442 2016-11-01 16:06:49 +01:00
utkarshcmu 7490c49f60 Alert un paused to pending state 2016-11-01 07:58:38 -07:00
Torkel Ödegaard f3090d8cd4 fix(dashboard): fixed issue with resizing panel, #6442 2016-11-01 15:33:20 +01:00
utkarshcmu d9f2519916 Renamed Initialized to Pending 2016-11-01 07:30:55 -07:00
Torkel Ödegaard 18056e53cc ux(dashboard): Fixing broken unit test made by changes for dash edit mode, #6442 2016-11-01 14:35:35 +01:00
Torkel Ödegaard 786afda4c3 ux(dashboard): edit mode fixes 2016-11-01 13:43:05 +01:00
bergquist 578507ae77 tech(cli): add default settings for transport 2016-11-01 08:58:44 +01:00
Carl Bergquist 4b8d9cac6f Merge pull request #6437 from dmvk/feature/grafana-cli-proxy
Take grafana-cli proxy settings from env
2016-11-01 08:53:23 +01:00
bergquist 39f9db8650 Merge branch 'utkarshcmu-slack_notifier' 2016-11-01 08:48:26 +01:00
bergquist 63e2337f6c feat(alerting): change placeholder to info-popover 2016-11-01 08:46:31 +01:00
David Moravek c6257b30c1 Take grafana-cli proxy settings from env 2016-10-31 23:14:48 +01:00
utkarshcmu 95117a0bc9 Added message parsing functionality 2016-10-31 14:55:21 -07:00
utkarshcmu 80fdd830de Added override default recipient functionality 2016-10-31 14:46:51 -07:00
Torkel Ödegaard 48a54edd85 ux(dashboard): improving drag and drop behavior! 2016-10-30 19:37:50 +01:00
Torkel Ödegaard 09a19d8ecb ux(dashboard): progress on ghost empty space panel 2016-10-30 18:02:46 +01:00
Torkel Ödegaard ca1f06f18f hunting memory leaks 2016-10-30 17:11:19 +01:00
Torkel Ödegaard 4d420a0c33 refactor(): dashboard row model and hunting down memory leak 2016-10-30 15:14:18 +01:00
Torkel Ödegaard 57cbefdf0a working on empty space / dropzone ghost panel 2016-10-30 12:05:11 +01:00
Torkel Ödegaard d98191ad65 Merge remote-tracking branch 'origin/row-tabs' into dash-edit-mode 2016-10-30 11:09:09 +01:00
Matt caaeb8e468 Added move row up and down arrows 2016-10-29 09:15:58 -04:00
Torkel Ödegaard 703eda489e ux(row): fixed panel footer hook border 2016-10-29 13:56:47 +02:00
Torkel Ödegaard c6757bed72 ux(dashboard): new row tabs look 2016-10-29 13:51:16 +02:00
Torkel Ödegaard bda5cdcb2f ux(dash edit mode): fix for row height when collapsed 2016-10-29 13:14:37 +02:00
Torkel Ödegaard 591f6536f8 feat(ux): trying to simplify display rules for edit mode / row actions 2016-10-29 13:10:20 +02:00
Torkel Ödegaard 3be9e8e022 Merge branch 'dash-edit-mode' of github.com:grafana/grafana into dash-edit-mode 2016-10-29 11:51:18 +02:00
Torkel Ödegaard 2fbe8cde8a Merge branch 'master' of github.com:grafana/grafana into dash-edit-mode 2016-10-29 11:50:57 +02:00
utkarshcmu dcaae47e96 Fixed tests 2016-10-28 14:54:55 -07:00
utkarshcmu 4c64e45a59 Added initalized state to alerts 2016-10-28 14:44:45 -07:00
Matt d9f99eb501 Added fadeIn animation to non-build mode 2016-10-28 17:09:33 -04:00
Matt 51f55cf6f1 Beginnings of changes to row edits 2016-10-28 16:12:20 -04:00
Torkel Ödegaard e170e47e7c ux(dashboard): minor updates 2016-10-28 16:41:48 +02:00
Torkel Ödegaard 3fc6f6d730 ux(dashboard): minor fixes 2016-10-28 16:37:13 +02:00
Torkel Ödegaard 366650e1ae ux(dashboard): fixed scss issue 2016-10-28 16:30:16 +02:00
Torkel Ödegaard be99c3e20a updates to dashboard edit mode 2016-10-28 16:26:53 +02:00
Torkel Ödegaard 30789308d7 minor change 2016-10-28 14:49:34 +02:00
Torkel Ödegaard 155cce959f more polish on edit mode 2016-10-28 14:38:48 +02:00
Torkel Ödegaard e215ba821c ux(): edit mode polish 2016-10-28 14:13:11 +02:00
Torkel Ödegaard f1a44ad090 ux(): progress on row ux 2016-10-28 13:36:27 +02:00
Eric Uldall 658fc1a67a added hosted domain suppport to google oauth login (#6372) 2016-10-28 12:00:47 +02:00
seanclerkin 7acdbde8f0 Cloudwatch: add support for Aurora specific RDS metrics (#6378) 2016-10-28 12:00:22 +02:00
Hans Kristian Flaatten b5eaa5ea59 Add missing closing " in Docker README (#6413) 2016-10-28 11:55:47 +02:00
Torkel Ödegaard 517ebfaf6d Merge branch 'dash-edit-mode' of github.com:grafana/grafana into dash-edit-mode 2016-10-27 22:11:08 +02:00
Torkel Ödegaard f8395666e6 minor update 2016-10-27 22:11:00 +02:00
Torkel Ödegaard 9c50893221 progress on new design 2016-10-27 21:51:57 +02:00
Matt b58c38a5db Refactored to be a proper list, added x button in upper right. Before cleaning up the CSS, want trent to set some eyes on it and make it look better. 2016-10-27 11:36:46 +02:00
Matt 4633da47ef Merge branch 'dash-edit-mode' of https://github.com/grafana/grafana into dash-edit-mode 2016-10-26 17:52:41 +02:00
Matt e7f5b76570 Added styles and new markup for dashlist panel 2016-10-26 17:52:37 +02:00
Torkel Ödegaard c609586ff0 ux(dashboard): making progress on new add panel experiance 2016-10-26 17:42:39 +02:00
Torkel Ödegaard f1f923abb9 build fix 2016-10-26 14:31:47 +02:00
Torkel Ödegaard 113a772e33 ux(dashboard): add panel stuff 2016-10-26 12:19:18 +02:00
Torkel Ödegaard 280709327c updated 2016-10-25 17:33:22 +02:00
Torkel Ödegaard 7b0eb6d0bb feat(dashboard): progress on dash edit mode 2016-10-25 16:36:40 +02:00
Utkarsh Bhatnagar b382d17e34 Fixed alerting bug for mysql (#6375) 2016-10-25 14:52:20 +02:00
Torkel Ödegaard 5e1f1c0989 updated 2016-10-25 12:12:59 +02:00
Torkel Ödegaard b45bd07032 ux(dashboard): when saving dashbord with default new dashboard title show Save As Dialog, #6099 2016-10-25 11:11:21 +02:00
Torkel Ödegaard 8a715cd122 using gf-form in row header 2016-10-25 10:47:13 +02:00
Torkel Ödegaard d1cc890ed3 Merge branch 'master' into dash-edit-mode 2016-10-24 14:57:30 +02:00
Torkel Ödegaard 556547b316 ux(panel resize): snap to even 12ths spans 2016-10-24 14:57:13 +02:00
Torkel Ödegaard d6c07d242c Merge branch 'master' into dash-edit-mode 2016-10-24 14:51:35 +02:00
Torkel Ödegaard 4db723ea81 ux(panel resize): snap to even 12ths spans 2016-10-24 14:40:46 +02:00
Torkel Ödegaard 6fb81f54bb ux(): minor fix 2016-10-24 14:12:19 +02:00
Torkel Ödegaard 01627b3a68 feat(ux): dashboard edit mode progress 2016-10-24 13:50:38 +02:00
Utkarsh Bhatnagar 10a42cc98c CHANGELOG entry (#6362) 2016-10-24 11:11:44 +02:00
Noah Heil 56ccd80cce Added two hints to help newer users
I spent a couple of hours trying to figure out why the cloudwatch datasource was not working and the "internal error" notice was not helpful. So I added some hints so that people who are a little newer to linux/aws/grafana wont have to suffer like I did.
2016-10-24 03:05:16 -06:00
Utkarsh Bhatnagar 86ca7ddda4 Added explicitTags support for OpenTSDB>=2.3 (#6361) 2016-10-24 09:15:19 +02:00
Torkel Ödegaard 29e834e74b feat(UX): revived dash-edit-mode branch, #6099 2016-10-23 10:05:31 +02:00
Torkel Ödegaard 1bb8192a38 Merge branch 'master' into dash-edit-mode 2016-10-23 10:03:55 +02:00
Torkel Ödegaard 42961ef8a0 fix(dashbard): fixed issue confirmig when saving a dashboard with conflict 2016-10-22 12:34:18 +02:00
Torkel Ödegaard 8735a84685 Merge branch 'master' of github.com:grafana/grafana 2016-10-22 11:51:48 +02:00
Torkel Ödegaard 8bb2f11505 Merge branch 'alerting_keeplast' 2016-10-22 11:51:16 +02:00
Carl Bergquist bc90e6ce46 Alerting: Keep last state on no data (#6354)
* feat(alerting): add support to keep last state on no data

closes #6332

* refactoring(alerting PR #6354): added new option type for NoData option so AlertStateType does not have to contain invalid state, #6354
2016-10-22 10:56:04 +02:00
Torkel Ödegaard a2e14f56e4 refactoring(alerting PR #6354): added new option type for NoData option so AlertStateType does not have to contain invalid state, #6354 2016-10-22 10:54:50 +02:00
Torkel Ödegaard 4999fff29b fix(alerting): fixed email notification so it splits email address multiple ways, fixes #6353 2016-10-22 10:24:31 +02:00
Torkel Ödegaard b32bbbd1a2 fix(influxdb): enforce database restriction, fixes #6352 2016-10-22 10:03:02 +02:00
Torkel Ödegaard 401c67d136 fix(dashboard): re-render panels when leaving fullscreen mode, fixes #6312 2016-10-22 09:51:18 +02:00
Torkel Ödegaard 1581bf8d5b fix(docs): added api_url to configuration docs, fixes #6351 2016-10-22 08:51:32 +02:00
bergquist 6e65c93203 fix(cli): improve error handling 2016-10-21 16:03:02 +02:00
bergquist 2c7dbde06a feat(alerting): recover from panic 2016-10-21 14:46:58 +02:00
bergquist ad56f67ad1 feat(alerting): add support to keep last state on no data
closes #6332
2016-10-21 14:00:20 +02:00
Torkel Ödegaard 96008c9738 Squashed commit of the following:
commit 4113ed00782590187d19dd2f8cbae683f164142c
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Fri Oct 21 10:47:35 2016 +0200

    docs(): minor fix for docs index page

commit 45478d120571519462fac905aadeab5954696690
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Thu Oct 20 14:28:21 2016 +0200

    updated

commit c9c1c1d5a462f85e8001a45218f24102583d7aee
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Thu Oct 20 14:27:34 2016 +0200

    docs(): updated image refs

commit 5fa0f27963968d77bbbbb7edd973847ea72135e3
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Wed Oct 19 14:33:04 2016 +0200

    docs is almost done

commit 6b988c90cb08563e2c27212338c2947e69f6fcc3
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Tue Oct 18 20:45:28 2016 +0200

    almost done

commit 17757c21ed813892ddb1f289f2e52613caf7bcef
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Tue Oct 18 16:45:48 2016 +0200

    making progress on docs

commit f06c815991dd81b8893912a6da04a17b80b63fda
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Tue Oct 18 14:30:55 2016 +0200

    progress on new docs

commit 5197237426252623de2d8b9cc22ddbbdbb240763
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Tue Oct 18 13:25:26 2016 +0200

    making progress

commit 33e2b6b617f16f65878141cf11e54b2817a2ea96
Merge: de385e5 ecb4a99
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Tue Oct 18 12:17:58 2016 +0200

    Merge branch 'new-docs' of github.com:grafana/grafana into new-docs

commit ecb4a99dd54aa39f17d9bf4d7e132a389812f8fd
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Tue Oct 18 10:39:59 2016 +0200

    keep urls for now

commit de385e56d86b071cf2150ccf9f1aa06ec5187277
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Mon Oct 17 17:56:18 2016 +0200

    more progress

commit 8469ebc239ab2316cbbc01862e5026737f272f00
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Mon Oct 17 17:08:06 2016 +0200

    progress on new docs

commit e755f656b12534cfcb23bad11f1fa696e43f7428
Merge: 4644a35 35cce3b
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Mon Oct 17 12:21:27 2016 +0200

    Merge branch 'new-docs' of github.com:grafana/grafana into new-docs

commit 4644a35102555204787e91041b50dcbfe0f7a213
Merge: 25c4bef 977cdd5
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Mon Oct 17 12:21:11 2016 +0200

    Merge branch 'master' of github.com:grafana/grafana into new-docs

commit 35cce3bef802fac020a53693b02c112a91a096fc
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Mon Oct 17 09:31:17 2016 +0200

    progress on #6170

commit 25c4bef629de7d77218ba95cc3bd25fb50bb19d6
Author: Torkel Ödegaard <torkel.odegaard@gmail.com>
Date:   Sun Oct 16 15:05:30 2016 +0200

    fix for osx

commit 6c6b52f975630be87da23dd51beafaecb820cec2
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Sun Oct 16 12:56:39 2016 +0200

    progress on new docs

commit 6a09633981ab26191d5542dbe3a788846ac6b73d
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Sat Oct 15 11:39:49 2016 +0200

    progress on new docs

commit 7d533fbc23e41b86fd1ba9c955dd17ae1ad977e5
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Mon Oct 10 09:25:12 2016 +0200

    making progress on new docs site

commit 50392ce98edfa201977716e92e4a86f9d48ae386
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Sun Oct 9 20:02:28 2016 +0200

    feat(new docs): progress on new docs site

commit 81a3d3d0952d3a5d790412e90d01ac5a247e0686
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Fri Oct 7 07:52:11 2016 +0200

    new docs site experiment

commit 704adc98664665b3624087ab38ce29fc9da005f1
Author: Torkel Ödegaard <torkel@grafana.org>
Date:   Sat Oct 1 20:46:53 2016 +0200

    new docs poc
2016-10-21 11:01:34 +02:00
Carl Bergquist 5520454523 Merge pull request #6344 from roidelapluie/cuu
Allow to set current on graph panel
2016-10-21 09:30:48 +02:00
bergquist 5bf5ed68e1 tech(notifications): replace internal email code 2016-10-21 09:06:03 +02:00
bergquist f77799837e feat(alerting): support for attached graphs in alert notifications
closes #6183
2016-10-21 09:06:03 +02:00
bergquist ded5a0a9d5 tech(alerting): remove unused code 2016-10-21 09:05:54 +02:00
Carl Bergquist 206a6b0a47 Merge pull request #6346 from cglewis/master
fix cla link; formatting and grammar fixes
2016-10-21 08:57:14 +02:00
cglewis 3931e0b743 fix cla link; formatting and grammar fixes 2016-10-20 13:08:12 -07:00
Julien Pivotto d1eb7e5fcd Allow to set current on graph panel
Refs #6335

Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
2016-10-20 21:13:32 +02:00
Carl Bergquist 1ce0b8fe25 Merge pull request #6333 from utkarshcmu/alerting_typo
Fixed typo
2016-10-20 11:26:02 +02:00
utkarshcmu b989b08781 Fixed typo 2016-10-20 02:22:37 -07:00
Eric Uldall eda442dbf9 added support to login user oauth user by email only (#6330)
* added support to login user oauth user by email only

* added sql handler

* fixed model method name from GetUserByEmail to GetUserByEmailQuery

* fixed variable declaration typo
2016-10-20 06:45:10 +02:00
bergquist 9badb051ba fix(changelog): typo 2016-10-20 06:38:45 +02:00
bergquist f2cbfece2c feat(notification): add helptext for using multiple email addresses 2016-10-19 17:04:17 +02:00
bergquist 6ea0f0120e feat(notifications): switch to ; seperator
using \n caused problems with the json deserialisation.

closes #6326
2016-10-19 16:34:12 +02:00
bergquist 3ac38dfe70 Merge branch 'alerting_opentsdb' 2016-10-19 13:16:16 +02:00
bergquist 2df8c649b7 Merge branch 'master' into alerting_opentsdb 2016-10-19 13:15:22 +02:00
bergquist 5fbab038e8 fix(opentsdb): can always return false 2016-10-19 13:14:42 +02:00
Torkel Ödegaard a826591eed Merge branch 'master' of github.com:grafana/grafana 2016-10-19 13:14:34 +02:00
Carl Bergquist 497eca0190 Merge pull request #6325 from utkarshcmu/alerting_opentsdb
Implmented targetContainsTemplate for OpenTSDB
2016-10-19 13:07:33 +02:00
utkarshcmu 62895114e1 Implmented targetContainsTemplate for OpenTSDB 2016-10-19 03:54:41 -07:00
bergquist 4c2f2eeb58 feat(opentsdb): add mock method for detecting targets with template values 2016-10-19 11:45:39 +02:00
bergquist 20bfe443fe feat(prometheus): trim labelname lookup key
closes #6300
2016-10-19 08:57:58 +02:00
bergquist b2d5b920f5 feat(alerting): allow editor to modify notifications
closes #6314
2016-10-19 08:01:31 +02:00
Carl Bergquist a1e97b0067 Merge pull request #6290 from utkarshcmu/alerting_opentsdb
Opentsdb alerting feature completed, ready for testing
2016-10-19 07:50:40 +02:00
Eric Uldall 9468ddeed5 Issues/6317 empty google login (#6318)
* added Login property to google_oauth model

* fixed spacing

* fixed google_oauth syntax error, missing comma before newline

* set noexpandtab for commit
2016-10-19 07:43:32 +02:00
utkarshcmu 333a853948 Fixed for loop and append 2016-10-18 08:48:06 -07:00
bergquist d1eceedf55 feat(webhook): add httpmethod to webhook
closes #6255
2016-10-18 16:50:16 +02:00
bergquist 9429434cb5 feat(influxdb): use database auth if provided
closes #6310
2016-10-18 15:12:04 +02:00
Mitsuhiro Tanda a8dd44918b support future time range 2016-10-18 19:39:04 +09:00
bergquist 2b55cf609c tech(build): include sha1 as artifact 2016-10-18 11:42:25 +02:00
bergquist d016fc1da1 tech(build): create sha files for windows build 2016-10-18 10:54:17 +02:00
Carl Bergquist 860865bd55 Merge pull request #6303 from mtanda/cw_region
(cloudwatch) add region
2016-10-18 08:48:44 +02:00
Mitsuhiro Tanda 888619d74e (cloudwatch) add region 2016-10-18 12:28:20 +09:00
utkarshcmu 10d581dd0a Added unit tests for query parsing 2016-10-17 14:51:51 -07:00
utkarshcmu 2374d09877 Fixed query parsing bugs 2016-10-17 14:50:53 -07:00
bergquist 97008f90c4 tech(build): semicölöns 2016-10-17 15:19:00 +02:00
bergquist 75a1ff1037 tech(build): dont override arch for windows 2016-10-17 15:09:35 +02:00
bergquist 0abc22f272 tech(build): make artifact path less strict 2016-10-17 14:35:09 +02:00
mkm85 977cdd5933 Fix cloudwatch multivalue (#6282)
* Fixed missing contains variable problem

* allow All option to be used in cloudwatch templating
2016-10-17 11:33:28 +02:00
bergquist b6d112f8d7 tech(build): appveyor formating 2016-10-17 09:34:58 +02:00
bergquist 6c7e227d2f Merge branch 'master' of github.com:grafana/grafana 2016-10-17 09:29:29 +02:00
Paul Traylor a45a487ad3 Update query for "Rule Eval Duration" (#6294)
This query was changed to use seconds in https://github.com/prometheus/prometheus/commit/f69e668fc468dfa2feb13603237810b8d748d87e
2016-10-17 08:37:59 +02:00
utkarshcmu ace81760ea Added tests file for writing tests 2016-10-16 12:10:13 -07:00
utkarshcmu b7744b4928 Added tags and filters params to alerting 2016-10-16 10:55:07 -07:00
utkarshcmu 35f93f4117 Added rate params to alerting 2016-10-16 05:20:58 -07:00
utkarshcmu cc0a39f816 Added downsampling params to alerting 2016-10-16 04:12:13 -07:00
benrubson 807bc5eb47 Add time back to result array 2016-10-16 01:09:00 +02:00
benrubson 9792bd7b08 Typo 2016-10-16 00:46:56 +02:00
benrubson 604dcbc6b2 Missing values, corect tooltip 2016-10-16 00:30:50 +02:00
benrubson 07bf4c0b82 Missing values, keep interpolation 2016-10-16 00:29:15 +02:00
benrubson 04a276dc2c Missing values, correctly highlight last point 2016-10-15 16:51:18 +02:00
benrubson 8d5269dea7 Typo 2016-10-15 13:17:11 +02:00
benrubson 43129aa563 Missing values, correct graph specs 2016-10-15 13:10:19 +02:00
benrubson c976448f6a Missing values, stack null & missing values 2016-10-15 13:07:41 +02:00
benrubson 2cdd097b3a Missing values, correct timeStep 2016-10-15 11:43:36 +02:00
Ben RUBSON d1e8418c74 Correct tooltip timestamp (#6283)
Corrects #6275, follows #6211
2016-10-15 08:02:07 +02:00
Torkel Ödegaard c1567ae595 fix(build): fixes #6284 2016-10-15 08:00:48 +02:00
Torkel Ödegaard 04c23ef322 fix(SIGHUP): ignore SIGHUP syscall, fixes #6276 2016-10-14 14:23:22 +02:00
Torkel Ödegaard 30645a6d3d refactor(alerting): initial step for seperating alerting and dash model, #6273 2016-10-14 13:06:29 +02:00
bergquist 466e62968e tech(build): publish artifacts to s3 2016-10-14 10:37:31 +02:00
bergquist ec4260e14f tech(build): remove commented build steps 2016-10-14 10:26:08 +02:00
bergquist 5e0fa0f0ad feat(opentsdb): context aware http requests 2016-10-14 10:21:47 +02:00
bergquist 6d6d6d90fc Merge branch 'utkarshcmu-alerting_opentsdb' into alerting_opentsdb 2016-10-14 10:15:43 +02:00
bergquist f44e360b0d fix(opentsdb): fmt 2016-10-14 10:15:30 +02:00
Torkel Ödegaard 4c26c55fea fix(api): minor change to how pause alert was done 2016-10-14 09:58:22 +02:00
Torkel Ödegaard 46bab0bb37 feat(alerting): remove annotations when deleting alert, closes #6244 2016-10-14 09:43:30 +02:00
Torkel Ödegaard c9d7eb0a7a feat(alerting): added clear history button to alert state history view, #6244 2016-10-14 09:33:42 +02:00
bergquist fe24e6c8a8 Merge branch 'alerting_opentsdb' of https://github.com/utkarshcmu/grafana into utkarshcmu-alerting_opentsdb 2016-10-14 09:19:42 +02:00
bergquist 455df7f0a0 Merge branch 'master' into alerting_opentsdb 2016-10-14 09:17:35 +02:00
bergquist aeb0c5cb53 Merge branch 'master' into interval 2016-10-14 09:15:04 +02:00
bergquist f4e0a9245e feat(influxdb): choose highest interval value 2016-10-14 09:14:13 +02:00
utkarshcmu 4247e92e87 Resolved conflicts 2016-10-14 00:01:36 -07:00
utkarshcmu 06f2047ced OpenTsdb alerting works with metric query 2016-10-13 23:49:28 -07:00
bergquist 998df2a1ac feat(opentsdb): add alerting support to plugin.json 2016-10-13 23:49:27 -07:00
bergquist b8ec1ce9a2 tech(tsdb): add basic skeleton for alerting 2016-10-13 23:49:27 -07:00
bergquist fb99d9d680 feat(build): remove dist from artifact path 2016-10-14 07:05:36 +02:00
bergquist b2acc7cf03 feat(build): build zipfile before creating artifact 2016-10-13 17:51:09 +02:00
Carl Bergquist 0793811b7e Merge pull request #6192 from polynomial/fix_typo
fix(docs): duplicate word data in Graph Panel
2016-10-13 17:17:49 +02:00
bergquist da2aaf7095 feat(build): trigger windows build after successfull CI build 2016-10-13 17:11:04 +02:00
Carl Bergquist 7bdedff89c feat(plugins): make sure windows data plugin path is absolute (#6264) 2016-10-13 15:36:35 +02:00
Torkel Ödegaard 44f064392d feat(alerting): different colored lines/icons for alert annotations based on state, #6244 2016-10-13 15:22:54 +02:00
mdadm fa492c6828 fixed scoping issue with certPool variable (#6261) 2016-10-13 13:38:55 +02:00
bergquist 4144eacc24 feat(influxdb): start parsing interval parameters 2016-10-13 11:42:51 +02:00
bergquist 1506df8c11 feat(alerting): parse the interval value from the panel 2016-10-13 11:19:44 +02:00
Carl Bergquist c0596d0dd0 Merge pull request #6257 from utkarshcmu/opentsdb_lodash
Opentsdb queries fixed without alias but with tags/filters
2016-10-13 07:34:00 +02:00
utkarshcmu 6638605fd1 Removed console.log 2016-10-12 13:47:40 -07:00
utkarshcmu cc3b928708 Opentsdb queries broken if no alias is uses with tags/filters 2016-10-12 13:32:37 -07:00
bergquist 2e4ca64783 fix(cli): improve error handling
closes #6256
2016-10-12 22:31:28 +02:00
Torkel Ödegaard 0f2fa33daf docs(changelog): added fix for #4393 to the changelog 2016-10-12 13:17:30 +02:00
Uros Meglic e1739b6025 (fix)elasticsearch: IP addresses don't survive terms aggregation (#4393) (#6246) 2016-10-12 13:14:57 +02:00
Carl Bergquist ce60efea8a Merge pull request #6249 from txisme/master
Fixed latest builds URL
2016-10-12 13:06:38 +02:00
txisme 2fc7957485 Fixed latest builds URL 2016-10-12 11:27:21 +01:00
bergquist 5a39bf5c58 fix(alert_tab): dont add dup notifications to repeater
closes #6233
2016-10-12 11:27:49 +02:00
Torkel Ödegaard 0bae12e4ae change(graph): Changed default for stack hover value 2016-10-12 11:21:23 +02:00
bergquist c0829903ba fix(alerting): scope variable was updated
closes #6228
2016-10-12 09:46:32 +02:00
Torkel Ödegaard b8b577eafb fix(spelling): minor spelling fix in alerting code 2016-10-12 09:17:48 +02:00
bergquist 5a91d45f3f fix(influxdb): broken unittests 2016-10-12 07:43:30 +02:00
Torkel Ödegaard 1b8a81d4ba fix(alerting): fixed reducer change issue, fixes #6241 2016-10-12 07:04:53 +02:00
Torkel Ödegaard 3d593492c9 fix to text panel and transparent mode 2016-10-12 07:04:53 +02:00
marcv81 150d21800c Do not pass Authorization header in Grafana.net proxy (#6243) 2016-10-12 06:54:33 +02:00
bergquist 885e0366c5 feat(influxdb): support raw queries in alerting
ref #6231
2016-10-11 18:53:09 +02:00
bergquist ccee1b3f96 fix(alerting): fix bug with unhandled error
closes #6239
2016-10-11 17:37:07 +02:00
bergquist 0d4b00df95 feat(alerting): add template validation for influxdb
closes #6230
2016-10-11 16:03:00 +02:00
Torkel Ödegaard 2e21613be7 fix(templating): fixed issues with dynamic dashboard srv (panel/row) repeats, fixes #6237 2016-10-11 15:17:47 +02:00
Corentin Chary 4df379f90c Do not align refresh time (#6178)
When you have a lot of dashboards, all of them
end up refreshing their dashboards at the exact
same time, which isn't particulary good for your
TSDB backend.
2016-10-11 13:57:53 +02:00
Ben RUBSON f7124f1638 Patch: 4 tooltip bugs (#6211)
* Order tooltip by yaxis by default

solves #6174

* typo

* Avoid sorting multiple times

and evaluate series.yaxis.n as it may not exist.

* typo

* typo

* typo

* Tooltip values loose their format when reordered

solves #6208

* Hover the correct point

* Make tooltip sort happy with hidden series
2016-10-11 13:53:49 +02:00
Uros Meglic dc680a41c8 fix(elasticsearch): Query editor allows to remove last group by (#5692) (#6223) 2016-10-11 13:41:13 +02:00
Torkel Ödegaard cace1d6b8f change(plugin page): changed tab order on plugin page, closes #6123 2016-10-11 13:40:16 +02:00
Torkel Ödegaard 73fc659011 fix(graph): fixed issue with old threshold to new threshold model migration, fixes #6236 2016-10-11 13:22:46 +02:00
Torkel Ödegaard f1905a8485 fix(alerting): fixed issue with using nested queries in graphite query used in alerting rule, fixes #5996 2016-10-11 12:50:11 +02:00
bergquist 446bde2421 Merge branch 'pause_alert_rules'
closes #6135
2016-10-11 10:54:58 +02:00
bergquist c6cf7647ff feat(alerting): pausing alerts requires alert id 2016-10-11 10:53:24 +02:00
Carl Bergquist be2054fe51 Merge pull request #6229 from nijanthanh/cloudwatch_ApplicationELB_UnHealthyHostCount_fix
(cloudwatch) Fix UnHealthyHostCount metric of ApplicationELB
2016-10-11 10:36:19 +02:00
bergquist 3162e680c2 tech(notifiers): improve logging for notifications
ref #6228
2016-10-11 10:15:41 +02:00
Torkel Ödegaard 7b70e0ff3a fix(UI): fixed 3 UI bugs, fixes #6225 2016-10-11 09:51:43 +02:00
bergquist 8b0c29b104 Merge branch 'master' into pause_alert_rules 2016-10-11 09:46:48 +02:00
bergquist 4bbc2108f9 feat(alerting): add pause button to alert list 2016-10-11 09:45:38 +02:00
Nijanthan Hariharan 2b8404e178 (cloudwatch) Fix UnHealthyHostCount metric of ApplicationELB
The UnHealthyHostCount metric of ApplicationELB for cloudwatch datasource did not work because the capitalization was wrong - it was UnhealthyHostCount instead of UnHealthyHostCount.
Here is the AWS documentation listing the metric name - http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html#load-balancer-metrics-alb
2016-10-11 13:10:57 +05:30
Dan Cech 6b16fcea52 Oauth2 Updates (#6226)
* break out go and js build commands

* support oauth providers that return errors via redirect

* remove extra call to get grafana.net org membership

* removed GitHub specifics from generic OAuth

* readded ability to name generic source

* revert to a backward-compatible state, refactor and clean up

* streamline oauth user creation, make generic oauth support more generic
2016-10-11 08:51:44 +02:00
bergquist 804797245d feat(alerting): make it possible to pause from alert tab 2016-10-11 08:40:38 +02:00
Torkel Ödegaard d4fd1c82e3 fix(alerting): added step any to alert threshold input fields, fixes #6205 2016-10-10 19:47:16 +02:00
Dan Cech 519100f1bd Merge pull request #6217 from ericpp/oauth_add_state_param
Added a state parameter for all OAuth requests
2016-10-10 09:58:35 -04:00
bergquist f3825263d4 feat(alerting): add pause button in alert list 2016-10-10 15:17:14 +02:00
Carl Bergquist b0d154d5aa Merge pull request #6221 from grafana/alerting_influxdb
Alerting support for influxdb
2016-10-10 14:32:47 +02:00
bergquist 264590a9c2 feat(alerting): add paused api endpoint 2016-10-10 14:26:09 +02:00
bergquist 19427b59f9 feat(alerting): do not enqueue paused rules 2016-10-10 13:29:10 +02:00
bergquist 04f417a423 feat(alerting): enabled by default. configurable elert engine
closes #6210
2016-10-10 13:09:16 +02:00
bergquist 8d96262106 chore(tsdb): tidy up code 2016-10-10 11:58:06 +02:00
bergquist b841e649ab Merge branch 'master' into alerting_influxdb 2016-10-10 11:38:29 +02:00
bergquist f609623abd style(influxdb): tidy up code 2016-10-10 11:34:52 +02:00
bergquist 95b9f472d1 tech(influxdb): remove unused logging 2016-10-10 11:17:00 +02:00
bergquist f919d04e3c docs(tsdb): improve fill comment 2016-10-10 09:52:53 +02:00
bergquist 0bfb94dc6f feat(tsdb): add interval calculator 2016-10-10 09:45:33 +02:00
Torkel Ödegaard 918481909c fix(metricsegment): fixed issue with metric segment, fixes #6212 2016-10-08 10:23:30 +02:00
Eric Perrino 81443bf8b4 Added a state parameter for all OAuth requests 2016-10-08 01:22:32 -05:00
Torkel Ödegaard 913f17ee8a fix(plugin dashboards): fixed issue with plugin dashboard list, fixes #6215 2016-10-07 16:04:58 +02:00
bergquist 4fafefd66a feat(influxdb): proper support for group by tags 2016-10-07 15:09:54 +02:00
bergquist e499e8850c fix(influxdb): fix for timerange 2016-10-07 11:33:17 +02:00
bergquist 0633e2c03f feat(influxdb): add real support for time ranges 2016-10-07 11:23:37 +02:00
bergquist e36f9fa795 Merge branch 'master' into alerting_influxdb 2016-10-07 10:45:05 +02:00
bergquist a3c91450d5 tech(config): add log.filters to default and sample 2016-10-07 10:39:01 +02:00
Torkel Ödegaard a5cbfc8b98 fix(opentsdb): fixed opentsdb issue, fixes #6206 2016-10-07 08:57:40 +02:00
Eric Perrino d3b0905899 Added allow_sign_up setting to auth.ldap to be able to disable automatic user creation for LDAP logins (#6191) 2016-10-07 08:49:58 +02:00
Wolfram Kroll 7e6595acaf hint about how to override settings from default section (#6181) 2016-10-07 08:48:57 +02:00
bergquist 522d40fa26 fix(influxdb): support mulitple tags 2016-10-06 18:51:17 +02:00
bergquist 87650c150b feat(influxdb): add tags to serie names 2016-10-06 18:47:59 +02:00
bergquist b0addbd7cb feat(influxdb): support multi row results 2016-10-06 15:30:09 +02:00
Torkel Ödegaard dacfa6b978 fixed issue in metric_segment 2016-10-06 15:09:02 +02:00
bergquist d8aa38fafe tech(influxdb): refactor and cleanup 2016-10-06 14:16:26 +02:00
bergquist ab8751767c feat(influxdb): send request and parse response 2016-10-06 12:51:45 +02:00
bergquist b519d5e92c feat(docker): update docker-compose for influxdb 2016-10-06 12:50:06 +02:00
Torkel Ödegaard 04a5ad529c generate sha1 for package files, fixes #913 2016-10-06 10:53:42 +02:00
Torkel Ödegaard cc1452277b added testdata scenario for null data and stacking, also updated testdata dashbord, #2912 2016-10-06 10:53:42 +02:00
bergquist 887ca40455 feat(influxdb): add support for policies 2016-10-05 20:57:28 +02:00
bergquist 4387d20222 feat(influxdb): render select and groupby 2016-10-05 20:36:05 +02:00
bergquist 9968fa5bc5 feat(influxdb): add query part definitions 2016-10-05 16:59:33 +02:00
bergquist 8588bb386c feat(influxdb): add conditions property to tag 2016-10-05 16:57:32 +02:00
Peter Dave Hello bf4c3f3ae6 optimize png images using zopflipng (#6197) 2016-10-05 15:57:50 +02:00
bergquist c7abd3ba4e feat(influxdb): add querypart renderers 2016-10-05 14:42:06 +02:00
bergquist d0e6a9559e feat(influxdb): add query part model 2016-10-05 10:56:34 +02:00
bergquist 92121ea656 feat(alerting): add nop uploader
ref #6183
2016-10-05 07:34:48 +02:00
Benjamin Smith 39769ea65b fix(docs): duplicate word data in Graph Panel 2016-10-04 12:40:34 -07:00
bergquist 946e0bf32e feat(influxdb): parse query json 2016-10-04 21:28:05 +02:00
bergquist e556df5b49 feat(tsdb): add draft implementation for influxdb 2016-10-04 16:25:33 +02:00
bergquist d726f49a8c fix(notification): broken test notifications
ref #6159
2016-10-03 17:03:21 +02:00
bergquist 5a201cfd35 tech(tsdb): abort batch procces when context closes 2016-10-03 14:33:47 +02:00
bergquist d889415c4b tech(tsdb): rename context to query 2016-10-03 14:32:04 +02:00
bergquist 653a0502c4 tech(tsdb): add jsondata to tsdb datasource struct 2016-10-03 14:31:33 +02:00
bergquist 1606b74fce tech(opentsdb): add init ref for opentsdb 2016-10-03 10:59:09 +02:00
bergquist f4a834f84b fix(opentsdb): add context to opentsdb executor 2016-10-03 10:37:49 +02:00
bergquist 8368a4a88a Merge branch 'master' into alerting_opentsdb 2016-10-03 10:36:33 +02:00
bergquist 6f1a9f4f2e Merge branch 'mtanda-cloudwatch_interval' 2016-10-03 10:32:07 +02:00
bergquist f4b5fa4d6a Merge branch 'master' into mtanda-cloudwatch_interval 2016-10-03 10:32:00 +02:00
bergquist 96ca69c5a9 tech(cloudwatch): extract method 2016-10-03 10:31:07 +02:00
Carl Bergquist c38f6ff182 Make alerting notifcations sync (#6158)
* tech(routines): move the async logic from notification to alerting notifier

* tech(notification): reduce code dupe

* fix(notification): dont touch the response unless its an error

* feat(alerting): make alerting exeuction async but flow sync

* tech(alerting): remove commented code

* tech(alerting): remove unused code

* tech(alerting): fix typo

* tech(alerting): implement Context on EvalContext

* tech(alerting): wait for all alerts to return

* feat(alerting): dont allow alert responses to cancel

* Revert "feat(alerting): dont allow alert responses to cancel"

This reverts commit 324b006c96.

* feat(alerting): give alerts some time to finish before closing down
2016-10-03 09:38:03 +02:00
bergquist 6b7015799c Merge branch 'cloudwatch_interval' of https://github.com/mtanda/grafana into mtanda-cloudwatch_interval 2016-10-03 08:51:33 +02:00
bergquist 36f0bf0e1e chore(web): Improve error message for invalid SSL configuration 2016-10-03 08:47:36 +02:00
Torkel Ödegaard 4a116ad4ad fix(build): fixed failing unit test 2016-10-01 17:36:56 +02:00
Torkel Ödegaard 4ec2377e09 fix(notifications): added form validation and restored Send Test button which was always hidden, #6159 2016-10-01 17:14:45 +02:00
Torkel Ödegaard c6cf6d4655 fix(api): fixed issue with api content-type in api success messages, fixes #6160 2016-10-01 16:52:52 +02:00
HeroCC 72f81b3b2a Make Slack Logo link to Slack (#6165) 2016-10-01 16:50:56 +02:00
miao 1f5a68aab1 Modify basic introductions of docs and make it exact (#6166) 2016-10-01 16:50:09 +02:00
Torkel Ödegaard a6918617ff feat(api): fixed minor issue with error message when trying to create duplicate datasource, fixes #6164 2016-10-01 16:41:27 +02:00
Torkel Ödegaard 4f2263552c feat(alerting): updated look for alerting panel, #6136 2016-10-01 16:32:13 +02:00
bergquist 91b180168e tech(notifications): remove unused filter markup 2016-10-01 15:51:08 +02:00
Torkel Ödegaard aa78114440 fix(alerting): fixed icon for ok state in panel header, #6136 2016-09-30 17:39:05 +02:00
Torkel Ödegaard 7c339f0794 feat(alerting): show alertin state in panel header, closes #6136 2016-09-30 17:37:47 +02:00
bergquist 1226beba31 feat(opentsdb): add alerting support to plugin.json 2016-09-30 16:50:50 +02:00
Torkel Ödegaard 2c4524bbfd fix(logging): minor logging fix 2016-09-30 13:25:54 +02:00
Torkel Ödegaard 2908c6a80b fix(metricsegment): added min width for inputs for metric segment and value select components 2016-09-30 13:13:28 +02:00
Torkel Ödegaard fe4a0a98c1 fix(alerting): added confirm modal in UI, when deleting alert 2016-09-30 13:00:16 +02:00
Torkel Ödegaard 24a25453f6 fix(server): shutdown logging fixes 2016-09-30 10:18:19 +02:00
Torkel Ödegaard 5ec86a9ef4 fix(build): fixed broken build, unreachable code in migrator.go 2016-09-30 09:23:26 +02:00
Torkel Ödegaard 86b546c21d refactor(main): refactoring main grafana server / startup code 2016-09-30 08:36:20 +02:00
Torkel Ödegaard 2b8177e3e5 fix(migration): fix for sqlstore migration, the execution of the migration and recording of the success of it was not done in same transaction, fixes #5315 2016-09-30 07:49:40 +02:00
Torkel Ödegaard 0ab2113fab docs(config): added missing smtp config section, fixes #6155 2016-09-30 07:40:58 +02:00
bergquist b66d94343e tech(tsdb): add basic skeleton for alerting 2016-09-30 07:35:48 +02:00
Torkel Ödegaard 50d146e82c fix(docs): fixed influxdb docs and mention of InfluxDB version, #6027 2016-09-29 14:53:50 +02:00
Torkel Ödegaard 5a1a80bcdd feat(templating): adding missing label property to query variable defaults, fixes #6150 2016-09-29 14:46:59 +02:00
bergquist 1a062c52fa fix(notifications): handle none configured image uploader
ref #6152
2016-09-29 14:31:19 +02:00
Torkel Ödegaard 88ec307f3e fix(graph panel): fixed issue with graph axis labels 2016-09-28 21:39:51 +02:00
Alexander Zobnin c2856926aa fix(graph): fix X axis value selection. (#6145) 2016-09-28 21:29:51 +02:00
Torkel Ödegaard 75311e0626 feat(alerting): removed old init package 2016-09-28 21:27:24 +02:00
Torkel Ödegaard 5f5bbfbda5 Merge branch 'master' of github.com:grafana/grafana 2016-09-28 21:12:37 +02:00
Torkel Ödegaard 80eb82420e fix(cleanup): check if images dir exists 2016-09-28 21:12:25 +02:00
Torkel Ödegaard c28d004731 Merge branch 'go_routines' 2016-09-28 21:06:07 +02:00
Torkel Ödegaard 71e2c6f6ef refactor(backend): refactoring management of go routines in backend 2016-09-28 21:06:00 +02:00
Dan Cech 6d7061dcaf fix typo in config loader 2016-09-28 13:10:31 -04:00
Torkel Ödegaard 2750c8a801 feat(config): changed name of allow_user_login_pass to disable_login_form, changed the section of the config option to [auth], impacts merged PR #5423 2016-09-28 15:27:08 +02:00
Torkel Ödegaard 3e657357e5 Merge branch 'gnet-oauth' 2016-09-28 15:11:03 +02:00
Torkel Ödegaard e5fc4332cd feat(oauth): refactoring PR #6077 2016-09-28 15:10:50 +02:00
bergquist bc634f20d5 Merge branch 'master' into go_routines 2016-09-28 13:58:14 +02:00
bergquist 7a6501640f tech(log): fixes extra param logging 2016-09-28 13:57:19 +02:00
bergquist 991539e410 style(go_routines): improve variable naming 2016-09-28 13:35:24 +02:00
Torkel Ödegaard 5ccdbf01fd merge with master 2016-09-28 13:02:15 +02:00
Torkel Ödegaard 10e63e5dd2 Merge branch 'master' of github.com:grafana/grafana 2016-09-28 12:17:16 +02:00
Torkel Ödegaard 15299c2ac0 fix(govendor): added new null package 2016-09-28 12:15:47 +02:00
Torkel Ödegaard 599fe49944 fix(templating): fix to datasource variable, was not updated on dashboard load, added unit test for case as well 2016-09-28 12:12:38 +02:00
Mitsuhiro Tanda 593863fb9e (prometheus) check time range (#6137) 2016-09-28 11:54:25 +02:00
Torkel Ödegaard 68370ba2bc feat(testdata): added alert dashboard 2016-09-28 10:44:21 +02:00
Torkel Ödegaard a4648607bb feat(testdata): added csv test data scenario 2016-09-28 10:37:30 +02:00
Torkel Ödegaard 8d5857661e refactor(tsdb): changed tsdb time series model to use null.Float instead of pointers 2016-09-28 09:15:48 +02:00
Torkel Ödegaard 63caedb094 Merge branch 'master' of github.com:grafana/grafana 2016-09-28 08:09:51 +02:00
Torkel Ödegaard 460160cfa4 feat(testdata): added test case for ms resolution data 2016-09-28 08:08:46 +02:00
Torkel Ödegaard 22e8885690 feat(testdata): progress on test data stuff 2016-09-27 18:36:00 +02:00
Torkel Ödegaard 3ecd96e682 feat(testdata): lots of work on new test data data source and scenarios 2016-09-27 18:17:39 +02:00
bergquist 34b31aeef8 tech(goroutines): sync state between different go routines 2016-09-27 16:47:17 +02:00
bergquist 8e89173095 tech(log): fixes extra param logging 2016-09-27 16:06:06 +02:00
Torkel Ödegaard ade8aa5b92 feat(graph): refactorings 2016-09-27 14:47:04 +02:00
Torkel Ödegaard 34f15d92d0 feat(testdata): worked on testdata app 2016-09-27 14:39:51 +02:00
bergquist 262e7193a3 feat(alerting): keep proccessing results even if one response panics 2016-09-27 11:16:55 +02:00
bergquist 071f2205e1 tech(tsdb): ops <o> 2016-09-27 11:13:13 +02:00
bergquist 46d4f817e3 tech(graphite): return error if statuscode is not ok 2016-09-27 10:09:56 +02:00
Torkel Ödegaard 81cb4a740b refactor(graph): progress on graph panel work 2016-09-26 17:25:29 +02:00
bergquist 6a699d13c4 docs(configuration): add note about snapshot configuration 2016-09-26 14:46:03 +02:00
bergquist 7585e9a930 docs(changelog): add note about closing #4087 and #2172 2016-09-26 14:41:13 +02:00
bergquist dbb7852f21 feat: purge old files and snapshots
closes #4087
closes #2172
2016-09-26 14:33:40 +02:00
Torkel Ödegaard 40e6317b7b feat(graph): refactoring 2016-09-26 14:04:13 +02:00
Torkel Ödegaard acfde82c0a refactor(graph): js -> typescript refactoring 2016-09-26 13:55:42 +02:00
bergquist 1a32ab64b6 tech(renderer): improve renderOpts names 2016-09-26 11:07:36 +02:00
bergquist effd2098ee feat(alerting): fixes broken image renderer 2016-09-26 10:51:45 +02:00
bergquist 887e236bce fix(rule): fixes rule reading bug 2016-09-26 10:01:33 +02:00
bergquist 8cd9225eb6 feat(alerting): increase timeout to 15s 2016-09-26 08:45:55 +02:00
Torkel Ödegaard 5682520603 feat(graph): more work on graph panel and support for non time series 2016-09-24 13:08:58 +02:00
Torkel Ödegaard cd270f14a2 feat(graph): more work on graph panel and support for non time series 2016-09-23 17:12:10 +02:00
Dan Cech 501e67a657 use semver when comparing grafana and plugin versions (#6108) 2016-09-23 14:38:59 +02:00
Torkel Ödegaard 3bbc940b88 Merge branch 'master' into graph-panel-non-timeseries 2016-09-23 14:22:44 +02:00
Torkel Ödegaard 9a94072c1d Merge branch 'master' of github.com:grafana/grafana 2016-09-23 12:30:20 +02:00
Torkel Ödegaard 175c651e65 fix(server side rendering): Fixed issues with server side rendering for alerting & for auth proxy scenarios, fixes #6115, fixes #5906 2016-09-23 12:29:53 +02:00
bergquist 99c77e7df8 tech(plugins): increase timeout 2016-09-23 09:56:42 +02:00
bergquist e5c64732f1 fix(sql): Add boolstr to all dialects
closes #6116
2016-09-23 09:36:15 +02:00
bergquist 521b5cf014 tech(build): make sure build.go setup works fine
ref #6113
2016-09-23 06:51:37 +02:00
Carl Bergquist 696a5f6a80 Merge pull request #6113 from replay/fix_context_dependency
Fix context dependency
2016-09-23 06:43:32 +02:00
Carl Bergquist 66fe886755 Merge pull request #6112 from replay/fix_typo
fix typo
2016-09-23 06:42:59 +02:00
Mauro Stettler f7dfcb4401 Merge branch 'master' of github.com:grafana/grafana into fix_context_dependency 2016-09-22 21:13:53 +01:00
Mauro Stettler cb0f19f8d4 fix context dependency 2016-09-22 21:13:08 +01:00
Carl Bergquist 7bfef0ced8 Merge pull request #6111 from grafana/pluginreadme
allow non-admin users to view plugin readme
2016-09-22 21:12:44 +01:00
Torkel Ödegaard bb77caa369 Merge branch 'master' of github.com:grafana/grafana 2016-09-22 21:49:57 +02:00
Torkel Ödegaard e36cdac594 fix(templating): fixed issue with templating when initalizing variables without any existing value 2016-09-22 21:49:41 +02:00
Mauro Stettler b063cf0a6e fix typo 2016-09-22 20:44:57 +01:00
Carl Bergquist d6a0ec85c4 Merge pull request #6111 from grafana/pluginreadme
allow non-admin users to view plugin readme
2016-09-22 19:51:47 +02:00
Dan Cech 2c3dd84ebb allow non-admin users to view plugin readme 2016-09-22 13:46:11 -04:00
bergquist 5817948341 Merge branch 'alert_prometheus' 2016-09-22 19:27:35 +02:00
bergquist d711c0ed35 Merge branch 'master' into alert_prometheus 2016-09-22 19:27:24 +02:00
bergquist a49c21df3a fix(png-renderer): increase timeouts 2016-09-22 19:24:18 +02:00
Torkel Ödegaard f2f3115749 feat(graph panel): more progress on graph panel and non time series data support 2016-09-22 16:47:37 +02:00
Torkel Ödegaard 6cd4db12c7 feat(graph panel): refactoring axes tab options into it's own component 2016-09-22 16:19:44 +02:00
bergquist 76b8cff445 fix(gnet): remove trailing , 2016-09-22 16:17:22 +02:00
Torkel Ödegaard 23246605b0 feat(graph panel): working on adding non time series support to graph panel 2016-09-22 16:05:20 +02:00
Torkel Ödegaard f3d4a97f49 Merge branch 'master' into graph-panel-non-timeseries 2016-09-22 14:03:06 +02:00
Torkel Ödegaard 0fc7405b95 fix(elasticsearch): for query template variable when looking up terms without query, no longer relies on elasticsearch default field, fixes #3887 2016-09-22 12:05:03 +02:00
Torkel Ödegaard f79600b352 fix(internal metrics): removed local dev code 2016-09-22 11:54:47 +02:00
Torkel Ödegaard e336fb3d60 fix(smtp mailer): added timeout of 10 seconds to smpt mailer, fixes #2989 2016-09-22 11:51:39 +02:00
Torkel Ödegaard 936146768f fix(snapshots): fixed issue with viewing embedded/solo/png panel from snapshot without login, fixes #3769 2016-09-22 11:46:58 +02:00
Torkel Ödegaard 3ed7ab93c5 added small info text to plugins list page, #5176 2016-09-22 11:32:27 +02:00
Torkel Ödegaard 6574dfacfb feat(internal metrics): added some total stats to metrics reporting, closes #5865 2016-09-22 11:16:19 +02:00
Torkel Ödegaard 8c05a125dc fix(build): updated build.go setup 2016-09-22 10:33:43 +02:00
Torkel Ödegaard d8df421b43 fix(build): fixed issues with optimized build, fixes #6096 2016-09-22 10:22:16 +02:00
Torkel Ödegaard 39af588a94 fix(playlist): fixed sorting issue with playlist playback, fixes #5467 2016-09-22 10:06:03 +02:00
Torkel Ödegaard 598ac0e815 docs(http api): Clarified issue with admin http api docs, fixes #5834# 2016-09-22 09:09:12 +02:00
Torkel Ödegaard 2752dbd13a feat(templating): minor fixes to recent refactorings 2016-09-22 09:00:15 +02:00
Torkel Ödegaard 6257ae094c feat(sqlstore): added index for dashboard_id in dashboard_tag table, fixes #5868 2016-09-21 21:32:51 +02:00
Torkel Ödegaard d65fbcbb42 fix(graphite): fixed minor graphite lexer issue when nodes begin with octal syntax and end with dash identifier, fixes #6049# 2016-09-21 20:04:09 +02:00
Dan Cech 248ed2672f remove 'Github' from oauth login error messages 2016-09-21 09:42:06 -04:00
Dan Cech b387c1291d Merge branch 'master' into gnet-oauth
Conflicts:
	pkg/api/login_oauth.go
2016-09-21 09:39:35 -04:00
Torkel Ödegaard 9e26a4cfcb fix(templating): fixed unique filter after regex pass, fixes #6086 2016-09-21 15:30:11 +02:00
Torkel Ödegaard b4111d78e1 fix(security): fixed login issue that was a potential for social engineering, fixes #6014 2016-09-21 15:03:14 +02:00
Torkel Ödegaard 4a1693196c fix(mixed datasource): fixed issue when exporting dashboard using mixed data source, fixes #6032 2016-09-21 14:57:19 +02:00
Torkel Ödegaard 46ab09ed60 feat(links): fixed styling for dashboard links 2016-09-21 14:20:59 +02:00
bergquist b856d7e193 fix(prometheus): remove timerange from context 2016-09-21 13:55:42 +02:00
bergquist ae7345b04d style(prometheus): remove commented test 2016-09-21 13:46:26 +02:00
bergquist c084145cba refactor(prometheus): add timerange to alert context 2016-09-21 13:46:10 +02:00
Torkel Ödegaard dc3b614749 fix(submenu): fixed issue with submenu and annotation display, and annotation issue in table panel 2016-09-21 13:45:26 +02:00
bergquist af551b8825 refactor(tsdb): remove toUnix from timerange 2016-09-21 13:41:25 +02:00
bergquist 9534a04d3d fix(prometheus): only accept matrix result 2016-09-21 13:30:41 +02:00
bergquist ee0f1a0f36 feat(prometheus): handle more errors 2016-09-21 13:17:36 +02:00
Torkel Ödegaard d0b75cdb66 fix(templating): fixed issue with regex in query variable introduced by yesterdays big merged refactoring of template variable system 2016-09-21 11:38:59 +02:00
bergquist 3e73be8d2e feat(prometheus): improve error handling 2016-09-21 11:31:56 +02:00
Torkel Ödegaard 8b90eedb35 feat(table): table options tab form layout changes 2016-09-21 11:23:39 +02:00
bergquist 4c88db3e43 feat(prometheus): add support for legend formatting 2016-09-21 11:17:29 +02:00
Torkel Ödegaard 7c10af012e feat(singlestat): slight layout changes to options tab 2016-09-21 10:56:17 +02:00
Torkel Ödegaard 7b7ba46f12 fix(styleguide): fixed theme switching in style guide 2016-09-21 09:10:25 +02:00
Torkel Ödegaard 4f892ab9bf Merge branch 'master' of github.com:grafana/grafana 2016-09-21 09:03:57 +02:00
Torkel Ödegaard a01836e86d feat(adhoc filters): basic implementation for ad hoc filters for elasticsearch, #6038 2016-09-21 08:48:49 +02:00
Alexander Zobnin 392976981c fix(table panel): update Table Panel options tab styles. (#6087) 2016-09-21 07:40:12 +02:00
bergquist 43d8bd5a25 feat(prometheus): initial support for prometheus 2016-09-21 07:01:53 +02:00
Dan Cech 630a8ed8aa support setting default org role when adding user via grafana.net auth 2016-09-20 12:36:36 -04:00
Torkel Ödegaard 1b02632de8 fix(jslint): fixed lint issue 2016-09-20 17:36:20 +02:00
Dan Cech da95a23080 remove 'Github' from oauth login error messages 2016-09-20 11:36:13 -04:00
Torkel Ödegaard 0906312046 Merge branch 'adhoc-filters' 2016-09-20 17:34:57 +02:00
Torkel Ödegaard 15423e6e51 feat(adhoc filters): initial base mvp for adhoc filters are donecloses #6038 2016-09-20 17:34:38 +02:00
Torkel Ödegaard dfe0f91105 feat(adhoc): adhoc filters progress 2016-09-20 16:29:48 +02:00
Dan Cech dcd96c90e2 add grafana.net auth section to defaults.ini, normalize section heading line lengths 2016-09-20 10:09:20 -04:00
Alexander Zobnin 159a8bf734 fix(singlestat): update singlestat options tab styles. (#6084) 2016-09-20 15:29:10 +02:00
Torkel Ödegaard 6e429b8575 feat(adhoc filters): good progress on ad hoc filters and sync from to url, #6038 2016-09-20 11:57:43 +02:00
Alexander Zobnin 20f7eee8cc fix(graph): increase Y min and max range when series values are the same, (#6082)
fixes #6070, #6050.
2016-09-20 11:38:18 +02:00
Alexander Zobnin e926b01185 Bug fixes for flexible Y-Min and Y-Max settings (#6066)
* fix(flexible_y-min/max): fixed negative values support and added tests for this.

* fix(flexible_y-min/max): fixed issue with Y-Min and Y-Max values stored as numbers.
	Issue: panels with configured Y-Min and Y-Max don't display anything
		   after upgrade.
2016-09-20 11:23:31 +02:00
bergquist d2fb660557 fix(cli): remove unused logging 2016-09-20 10:10:27 +02:00
Carl Bergquist 630adfaf2b Merge pull request #6068 from fg2it/cross
Cross build support
2016-09-20 10:03:06 +02:00
bergquist ec452dd704 docs(conf): remove internal options since its not working atm 2016-09-20 08:18:15 +02:00
bergquist 21fcb2c643 Merge branch 'mtanda-cloudwatch_expand_template' 2016-09-20 08:14:01 +02:00
bergquist 46866add7e docs(changelog): add note about closing #5003 2016-09-20 08:13:53 +02:00
Mitsuhiro Tanda 71b5007ec7 refactor 2016-09-20 11:04:23 +09:00
Mitsuhiro Tanda 07cce5f6bd refactor 2016-09-20 11:04:23 +09:00
Mitsuhiro Tanda 481cc01242 (cloudwatch) add test for expand templater variables 2016-09-20 11:04:23 +09:00
Mitsuhiro Tanda 540436e9d5 inject templateSrv 2016-09-20 11:04:23 +09:00
Mitsuhiro Tanda 490141da82 (cloudwatch) expand multi select template variable 2016-09-20 11:03:35 +09:00
Dan Cech f5e2d61aef Merge branch 'master' into gnet-oauth 2016-09-19 16:48:40 -04:00
Dan Cech fc17ed351c support logging in with grafana.net credentials 2016-09-19 16:48:07 -04:00
Torkel Ödegaard cb522d58cd feat(templating): back to be able to continue work on ad hoc filters, #6048 2016-09-19 18:41:42 +02:00
Torkel Ödegaard 7a6fb70026 feat(templating): progress on variable system refactoring, #6048 2016-09-19 18:32:09 +02:00
Torkel Ödegaard 9d6ecc6361 feat(templating): progress on variable system refactoring, #6048 2016-09-19 18:06:36 +02:00
Steven Arnott 6e4ed4debd Altered DB for Prefix (#6062) 2016-09-19 17:12:43 +02:00
Torkel Ödegaard 945b5ee3cf feat(templating): progress on variable system refactoring, #6048 2016-09-19 17:03:36 +02:00
bergquist 87be56a4f0 fix: add goconvey to vendor 2016-09-19 16:22:39 +02:00
bergquist 3f00834f25 tech: remove unused dependencies 2016-09-19 15:21:53 +02:00
Torkel Ödegaard 8a796c5b4b feat(templating): progress on variable system refactoring, #6048 2016-09-19 15:15:15 +02:00
Torkel Ödegaard 5ded88fa4d feat(templating): progress on variable system refactoring, #6048 2016-09-19 11:34:08 +02:00
bergquist 1cb45c3416 fix(alertlist): better description 2016-09-19 10:11:33 +02:00
Torkel Ödegaard 524f505664 tech(templating): refactoring, updated dashboardSrv to typescript 2016-09-19 10:08:05 +02:00
bergquist 0bde2ae689 fix(alertlist): remove timerange checkbox option 2016-09-19 10:07:53 +02:00
fg2it 0984edd8b2 avoid copy of go dep. from vendor/ for release 2016-09-19 08:03:35 +02:00
fg2it 699c515369 enforce unconditional copy 2016-09-18 11:45:46 +00:00
fg2it c669de1169 add options to support cross build 2016-09-18 10:07:12 +00:00
fg2it 62a2f80f10 add option for grunt release 2016-09-18 09:13:00 +00:00
fg2it 174ea11b1c avoid copy of go dep. from vendor/ for release 2016-09-18 09:03:47 +00:00
Torkel Ödegaard 5ce3e40cc9 feat(templating): more work on new variable handling code, #6048 2016-09-17 15:27:53 +02:00
Torkel Ödegaard 4188c46f83 feat(templating): more work on new variable handling code, #6048 2016-09-17 11:28:45 +02:00
Torkel Ödegaard 46ebae7304 feat(templating): progress on template system rewrite #6048 2016-09-16 16:50:30 +02:00
bergquist 05d43999dc feat(alertlist): add support for time range lockdown
closes #5981
2016-09-16 15:55:38 +02:00
bergquist 77783c02cd fix(alerting): dont log null series
closes #6025
2016-09-16 14:59:54 +02:00
Torkel Ödegaard 7e8b279895 feat(templating): good progress on new variable update code, #6048 2016-09-16 10:48:03 +02:00
Torkel Ödegaard 852fd66c4c Update debian.md 2016-09-16 10:42:15 +02:00
Alexander Zobnin 4fa22e2158 Refactor: flexible Y-Min and Y-Max settings (#6051)
* Feature: Flexible Y-Min and Y-Max settings.

Y-Min and Y-Max is now string.
New usage for both Y-Min and Y-Max (Where X is a real number):
  >X Y-Max/Y-Max is auto if data is above X else X
  <X Y-Max/Y-Min is auto if data is below X else X
  =X Y-Max/Y-Min is scaled to current value +/- X
  ~X Y-Max/Y-Min is caled to average value +/- X

Example: Y-Min: <100 Y-Max: >200
If all points are within 100 and 200: Y-Min is 100 and Y-Max is 200
If some points are above 200: Y-Min is 100 and Y-Max is auto
If some points are below 100: Y-Min is auto and Y-Max is 200
if some points are below 100 and above 200: Y-Min and Y-Max is auto

Tests for new settings added

* Use parseFloat instead of implicit conversion

* feat(flexible_y-min/max): refactor.

* feat(flexible_y-min/max): added more tests.
2016-09-15 21:03:54 +02:00
bergquist a95808a7c3 docs(build): update required go version to 1.7 2016-09-15 16:29:25 +02:00
cmartin0077 f91f74be04 fix(influxdb) autocomplete measurement while typing, fixes #4278 (#5931) 2016-09-15 16:11:38 +02:00
bergquist 3c92f78ee7 feat(cli): add grafana version header to all request against grafana.net 2016-09-15 16:01:06 +02:00
Torkel Ödegaard 0f4a9f1ed1 feat(templating): began refactoring variables into rich behavioral classes 2016-09-15 14:53:36 +02:00
bergquist 3c966caa23 feat(cli): download all plugin dependencies 2016-09-15 14:38:11 +02:00
bergquist fc67ab1dce tech(build): add build grafana-server and cli to CI 2016-09-15 13:52:41 +02:00
bergquist dd70c535ed tech(build): upgrade ci build to 1.7.1 2016-09-15 13:43:37 +02:00
bergquist dede58915d Merge branch 'go_vendor' 2016-09-15 13:25:50 +02:00
bergquist 6be48269e2 tech(build): update build docs 2016-09-15 13:09:33 +02:00
bergquist d3a5d5c058 tech(build): update makefile 2016-09-15 13:02:16 +02:00
bergquist bda1f6493c tech(scripts): move benchmark script into /scripts 2016-09-15 13:00:26 +02:00
bergquist 283172e78c tech(build): remove unused file 2016-09-15 12:59:25 +02:00
bergquist 6489571179 move circle trigger to /scripts 2016-09-15 12:57:41 +02:00
bergquist 4afd7a5ef1 tech(build): update circle ci to build using vendor folder 2016-09-15 11:32:32 +02:00
Zihao Yu 6d843e3db5 update github oauth docs (#6042) 2016-09-15 11:29:03 +02:00
Torkel Ödegaard 94e5001c0e feat(templating): making progress on adhoc template variable, #6038 2016-09-15 09:18:28 +02:00
Alexander Zobnin 3be84b00d5 ES nested fields autocomplete (#6043)
* Re-create PR #4527 from @arcolife:
fixes #4526 - add nested support to fieldname autocomplete; Also:
    - update _mapping to first use given time range
      for deducting index mapping, then fallback to
      today's date based index name

* (elasticsearch): refactor getFields() method.

* (elasticsearch): add tests for getFields() method.

* (elasticsearch): fixed _get() method (tests was broken after @arcolife commit).
2016-09-15 07:30:08 +02:00
Torkel Ödegaard 83b9db51e3 feat(templating): great progress on adhoc filters, #6038 2016-09-14 17:36:28 +02:00
bergquist 6253476c73 tech(build): move dependencies to vendor folder 2016-09-14 16:14:27 +02:00
bergquist 4e567b5f02 feat(alert): order alerts by name.. instead of nothing. 2016-09-14 14:51:31 +02:00
bergquist a23b7f1371 fix(alerting): add missing evaldata field to set state command 2016-09-14 14:35:05 +02:00
bergquist 31892ed73c style(alertlist): remove unused code 2016-09-14 14:21:56 +02:00
bergquist 9dd8b3b408 wip 2016-09-14 14:12:19 +02:00
Torkel Ödegaard 0a44add6c9 feat(adhoc fiters): began work on ad-hoc filters, refactored submenu filters to use gf-form styles, #6038 2016-09-14 11:21:02 +02:00
bergquist d0f9623037 feat(alertlistpanel): support state filter
ref #5981
2016-09-14 10:49:05 +02:00
bergquist b49a642ca5 feat(alerting): extract method for join eval matches 2016-09-14 10:49:05 +02:00
bergquist d02f29fb02 feat(alertlist): basic alert list panel
ref #5981
2016-09-14 10:49:05 +02:00
Torkel Ödegaard babab7677c tech(lib upgrade): fixed issue with angular 1.5.8, so can revert revert of upgrade, that is we are no on latest angularjs, #6022 2016-09-14 10:45:56 +02:00
Torkel Ödegaard c594f9f2ad fix(lodash): corrected checked in lodash version 2016-09-14 10:13:33 +02:00
Torkel Ödegaard 649d9f9177 tech(lodash): upraded lodash to 4.15.0, closes #6021 2016-09-14 09:17:10 +02:00
Torkel Ödegaard 0fa0066cd9 tech(lodash): began migration work 2016-09-13 22:10:44 +02:00
Torkel Ödegaard 2146e69a11 revert angularjs upgrade 2016-09-13 21:26:28 +02:00
Torkel Ödegaard fffa26b876 tech(lib upgrade): updated jquery to 3.1, fixes #6034 2016-09-13 20:42:28 +02:00
Torkel Ödegaard 25139c77b9 tech(update angularjs): updated angularjs to 1.5.9 2016-09-13 20:33:49 +02:00
Torkel Ödegaard f5809c0209 fix(build): trying to fix build 2016-09-13 20:14:18 +02:00
Torkel Ödegaard 9cd517780f Merge branch 'master' of github.com:grafana/grafana 2016-09-13 16:25:48 +02:00
Torkel Ödegaard 8c30babdf1 feat(alerting): fixed build issues 2016-09-13 16:24:00 +02:00
Torkel Ödegaard 3af891d023 feat(alerting): restored alert history 2016-09-13 16:13:41 +02:00
Torkel Ödegaard b0c7e61ef8 feat(alerting): removed severity 2016-09-13 15:09:55 +02:00
wvl a73424d6af Secure Elasticsearch datasources a bit (#6031)
Instead of allowing users to access the
entire cluster, apply some sane restrictions.

Change-Id: Ib2e93722bf2e39d700d4afa713ff49ec556f2fdf
2016-09-13 15:04:21 +02:00
bergquist 6a723dff37 feat(notifications): set default value to false for new notifications 2016-09-13 14:25:48 +02:00
Torkel Ödegaard 6375418d8c Merge branch 'alerting' into grafana-annotations 2016-09-13 09:38:12 +02:00
Mitsuhiro Tanda 1264a1b3a6 (cloudwatch) add metrics/dimensions (#6020) 2016-09-13 09:08:33 +02:00
Jouni Kuusisto e53b815956 Enable "With Credentials" for InfluxDB datasource (#6018) 2016-09-13 08:57:39 +02:00
Carl Bergquist 52dc2db769 Merge pull request #6008 from rubycut/patch-1
Increase datasource limit to 1000 #3910
2016-09-13 08:38:07 +02:00
bergquist 3ba3d9d445 docs(changelog): add note about closing #2839 2016-09-13 08:14:43 +02:00
bergquist f7abf01efb Merge branch 'mtanda-template_sort' 2016-09-13 08:12:23 +02:00
bergquist 03fb152d4b tech(templates): extract sort method 2016-09-13 08:11:04 +02:00
bergquist 9c5436c648 feat(templating): set default sort order 2016-09-13 07:39:30 +02:00
bergquist e348822190 Merge branch 'template_sort' of https://github.com/mtanda/grafana into mtanda-template_sort 2016-09-13 07:16:34 +02:00
Carl Bergquist 1c7b76cb43 Merge pull request #6013 from mtanda/cloudwatch_kinesis_analytics
(cloudwatch) add metrics/dimensions
2016-09-12 17:03:25 +02:00
Mitsuhiro Tanda f998b86ade (cloudwatch) add metrics/dimensions 2016-09-12 23:47:31 +09:00
bergquist 157ab1ba36 fix(setting): broken code 2016-09-12 14:57:37 +02:00
bergquist 811b7188c4 docs(config): add docs for how to run grafana behind a reverse proxy 2016-09-12 14:47:21 +02:00
bergquist d7bf70a77b tech(tsdb): remove skip ssl setting. should be based on datasource settings 2016-09-12 13:37:00 +02:00
bergquist 6c5860d3e8 feat(metrics): measure proxy requests 2016-09-12 13:29:31 +02:00
Rubycut 501f89e829 Increase datasource limit to 1000 #3910 2016-09-12 10:45:17 +02:00
bergquist eb673fd16d fix(middleware): typo 2016-09-12 10:11:55 +02:00
Torkel Ödegaard 014b70ded9 fix(graph): fixed showing rendering error in inspector, fixes #5995 2016-09-10 12:00:33 +02:00
Torkel Ödegaard 7aab4a4a59 fix(table): fixed issue with using mixed data source in table panel, fixes #5999 2016-09-10 09:57:25 +02:00
Chen Chenglong 7b1c374f64 support connect ldap server with starttls (#5969)
* support connect ldap server with starttls

* add more doc for start_tls option
2016-09-10 09:40:56 +02:00
bergquist 4edb31723c fix(metrics): ignore datasource proxy requests 2016-09-09 13:53:50 +02:00
bergquist e7b56c6389 tech(metrics): move all request counters into one middleware 2016-09-09 13:28:19 +02:00
Torkel Ödegaard 4a2f2fba73 feat(alerting): show panel specific alert annotations, #5694 2016-09-09 11:30:55 +02:00
bergquist 583790e650 fix(alering): the crocdile turned on me > <
closes #5855
2016-09-09 07:42:07 +02:00
Carl Bergquist 51d2534f6a Merge pull request #5994 from mtanda/prometheus_fix_legend_template
(prometheus) fix template variable expansion in legend
2016-09-08 18:37:27 +02:00
Mitsuhiro Tanda 9d09e5bbd0 (prometheus) fix template variable expansion in legend 2016-09-09 00:46:04 +09:00
bergquist aa80b52c07 feat(alerting): make it possible to skip ssl verification for alerting https requests 2016-09-08 16:29:31 +02:00
bergquist 7b9099ef93 fix(query): requires all that all series are empty to set NoDataFound 2016-09-08 14:33:10 +02:00
Torkel Ödegaard 0ac4ece00d feat(annotations): refactoring annotations srv to typescript, #5990 2016-09-08 14:31:30 +02:00
bergquist 9511f89a22 fix(alerting): fixes bug in query conditions 2016-09-08 13:28:41 +02:00
Torkel Ödegaard 23de094a81 feat(alerting/annotations): fixed broken test 2016-09-08 13:22:30 +02:00
bergquist bec099cd84 tech: remove unused files 2016-09-08 11:41:56 +02:00
Torkel Ödegaard b8081b29fd Merge branch 'master' into grafana-annotations 2016-09-08 11:26:55 +02:00
Torkel Ödegaard d60bd77658 feat(annotations): added support to show grafana stored annotations in graphs, #5982 2016-09-08 11:25:45 +02:00
bergquist 3c9432b7e9 fix(metrics): default updateSince to ms 2016-09-08 10:48:11 +02:00
bergquist acf74cdacc fix(alerting): change execution time to ms 2016-09-08 10:45:10 +02:00
bergquist 5f934e0238 feat(emails): move bg color to main table 2016-09-08 09:59:51 +02:00
bergquist 21c5b543fb feat(profile): hide orgs list when it only contains one org 2016-09-08 09:03:29 +02:00
bergquist 592ae5a39a tests(alerting): fixes broken tests. pointers and stuff 🤷 2016-09-07 17:05:41 +02:00
bergquist 30f36fe2c4 docs(changelog): add note about merging #4718 2016-09-07 15:24:38 +02:00
bergquist f56d45ac56 feat(alerting): include default notifications in alert tab 2016-09-07 15:13:24 +02:00
bergquist c769148701 Merge branch 'emails' 2016-09-07 13:52:16 +02:00
bergquist 62372978e4 style: convert tabs to spaces 2016-09-07 13:51:17 +02:00
bergquist 59cb51dc6f test(emails): update fake data model 2016-09-07 13:47:57 +02:00
bergquist 9595916a5f feat: right align value metrics 2016-09-07 13:47:21 +02:00
bergquist 712061ab4f test(alerting): fixes broken unit tests 2016-09-07 11:45:38 +02:00
bergquist 166df66f66 docs(go): update go dep to 1.6 2016-09-07 11:28:22 +02:00
bergquist f26824049f Merge branch 'master' into emails 2016-09-07 11:19:52 +02:00
bergquist 374016b9b5 Merge branch 'kfitzpatrick-custom-github-style-oauth' 2016-09-07 11:07:30 +02:00
bergquist 10b3ee362c docs(oauth): add generic_auth to docs 2016-09-07 11:06:59 +02:00
bergquist 53dddf1a8f fix(oauth): remove github refs from generic auth 2016-09-07 10:55:46 +02:00
bergquist 3b6820ef03 feat(oauth): create struct for generic oauth and add config values 2016-09-07 10:34:56 +02:00
Torkel Ödegaard 0d083bad14 Merge branch 'master' of github.com:grafana/grafana
Conflicts:
	pkg/components/imguploader/s3uploader.go
2016-09-07 10:14:36 +02:00
Torkel Ödegaard 50b41130ca feat(alerting): fixed s3 upload issue, progress on alerting on null/missing data, updated ini package to get the support for line continuations 2016-09-07 10:11:00 +02:00
bergquist d1a7a23c84 test(imageupload): add more specific tests
torkels commit will fix this unit test :)
2016-09-07 10:05:01 +02:00
bergquist 4646723cbb Merge branch 'custom-github-style-oauth' of https://github.com/kfitzpatrick/grafana into kfitzpatrick-custom-github-style-oauth 2016-09-07 08:15:44 +02:00
Torkel Ödegaard fc8f0721cd Merge branch 'master' of github.com:grafana/grafana
Conflicts:
	pkg/services/alerting/eval_context.go
2016-09-06 20:40:49 +02:00
Torkel Ödegaard fbae6abb3c feat(alerting): progress on handling no data in alert query, #5860 2016-09-06 20:40:12 +02:00
bergquist 2e8d5ca519 docs(changelog): add note about updating systemd description 2016-09-06 17:32:18 +02:00
Carl Bergquist a02bef7d94 Merge pull request #5971 from cicku/master
Update systemd unit's description to be more understandable
2016-09-06 17:11:46 +02:00
Christopher Meng 6afb456bef Update systemd unit's description to be more understandable
Signed-off-by: Christopher Meng <i@cicku.me>
2016-09-06 16:29:15 +02:00
bergquist 04690ca920 feat(alerting): add support for retries
ref #5855
2016-09-06 15:09:49 +02:00
bergquist 0d7a871223 style(alerting): remove blank lines 2016-09-06 14:57:15 +02:00
bergquist 22805ce56b fix(alert_tab): fix broken alert history 2016-09-06 14:42:34 +02:00
bergquist 55b560a4a8 feat(alerting): filter notifications based on severity
closes #5851
2016-09-06 14:27:48 +02:00
Torkel Ödegaard b1ed641d73 fix(graph): fixed issue with duplicate metric calls when doing full page reload of graph in edit/view mode 2016-09-06 09:20:34 +02:00
Torkel Ödegaard 6b17cdbca6 feat(alerting): Save As removes alerts from panels, closes #5965 2016-09-06 09:14:11 +02:00
bergquist 2ca7284a56 tech(notifications): splitt into 3 queries
closes #5883
2016-09-06 08:43:15 +02:00
bergquist c893e5d241 feat(notifications): add support for default notifications
ref #5883
2016-09-05 21:35:37 +02:00
bergquist eb0396ad95 chore(tsdb): remove some logging 2016-09-05 21:35:24 +02:00
bergquist 015423b233 tech(gitignore): ignore vscode folder 2016-09-05 21:35:24 +02:00
Carl Bergquist b501590a75 fix(.editorconfig): correct spelling of indent_style
Unleash the fucking fury
2016-09-05 17:38:55 +02:00
bergquist d11bc57c37 feat(notifications): make it possible to send test alert notifications
closes #5847
2016-09-05 14:45:15 +02:00
Torkel Ödegaard 4c5461d4ba feat(alerting): alerting scheduling distribution, only distibutes it on seconds for now, not sub second distribution, #5854 2016-09-05 14:26:08 +02:00
Torkel Ödegaard e2f5bf1666 feat(alerting): fixed confirm delete dashboard issue 2016-09-05 13:38:25 +02:00
Torkel Ödegaard 395213abd7 feat(graph panel): more refactoring of #5917 2016-09-05 11:46:16 +02:00
Torkel Ödegaard 31642b472c refactoring(graph panel): #5917 2016-09-05 11:07:41 +02:00
Torkel Ödegaard 36252602af Merge branch 'master' into graph-panel-non-timeseries 2016-09-05 09:58:07 +02:00
bergquist daea38060f feat(notifications): redirect to notification list after creation. 2016-09-05 08:27:12 +02:00
Carl Bergquist 002cfb09cb Merge pull request #5953 from kobtea/fix/ng-ctrl
fix typo
2016-09-05 07:56:57 +02:00
Carl Bergquist ae2fe11166 Merge pull request #5957 from tdi/master
Changed EBS to ELB
2016-09-05 07:54:03 +02:00
Dariusz Dwornikowski 1b283d052b Changed EBS to ELB 2016-09-02 20:49:28 +02:00
Hiroaki Kobayashi 3645fb371c fix typo 2016-09-02 15:22:04 +09:00
bergquist 1955defc43 fix(api): add missing jsonData field to dto
The field is available on the dto so I guess is should be used.
Otherwise we should remove the field rather then not setting it.

ref #5944
2016-09-01 17:21:13 +02:00
bergquist 86aea89214 style(tsdb): extract some methods 2016-09-01 13:03:15 +02:00
bergquist d73547c0dc feat(tsdb): add missing content type and join url using path 2016-09-01 11:12:35 +02:00
bergquist 3d3365f242 tech(graphite): add more logging 2016-09-01 10:09:13 +02:00
bergquist 94389a3a44 tech(tsdb): improve logging for graphite client 2016-09-01 09:38:43 +02:00
bergquist 29b60329cc stupid stupid stupid me 2016-09-01 09:17:57 +02:00
bergquist 000eb669df tech(build): change min go version to 1.6 2016-09-01 08:13:48 +02:00
bergquist 7ddd625e9d feat(alerting): add slack/email support for execution errors 2016-08-31 15:55:01 +02:00
bergquist 4619a05f43 feat(alerting): save execution error message to annotations 2016-08-31 14:06:54 +02:00
bergquist c624f3d470 fix(alerting): measure state result instead of severity 2016-08-31 11:55:35 +02:00
bergquist e493015f54 fix(alerting): replace one hack with another hack 2016-08-31 10:10:39 +02:00
bergquist 53a9dec407 feat(alerting): move timestamp to new row
ref #5850
2016-08-31 09:48:58 +02:00
bergquist a5d49c9820 docs(config): add note about poodle vulnerabillity in <3.0
closes #3483
2016-08-31 08:34:15 +02:00
Trent White 00f82010f8 tweaked alert example to see if there were any visual changes 2016-08-30 12:11:00 -04:00
Trent White 852a8b77e4 table tweak 2016-08-30 12:04:26 -04:00
bergquist 1a70e69447 mark second td as last 2016-08-30 15:23:59 +02:00
bergquist ae428b9177 docs(changelog): add note about cli fix 2016-08-30 13:49:50 +02:00
bergquist 645293e590 fix(cli): improve error message for upgrade-all
closes #5885
2016-08-30 13:47:42 +02:00
bergquist b55b7cde4b fix(alerting): remove error message when model is valid again
closes #5921
2016-08-30 13:36:13 +02:00
bergquist 11a4ff0f8a feat(alerting): add basic UI for history in alert tab
ref #5850
2016-08-30 13:22:59 +02:00
bergquist 650a87dc05 feat(alerting): add alert history api endpoint
ref #5850
2016-08-30 09:32:56 +02:00
bergquist 1f1d232ea6 tech(githooks): remove symlink bash script 2016-08-30 07:48:15 +02:00
Trent White 90873cfe76 getting tables to behave on mobile 2016-08-29 16:55:19 -04:00
bergquist a2525f77d9 fix(config): comment sample value 2016-08-29 21:14:47 +02:00
bergquist ff9b95f4b3 docs(changelog): adds note about closing #5827 2016-08-29 16:24:23 +02:00
Carl Bergquist 47438ad9b9 Merge pull request #5926 from cmartin0077/5827-add-elapsed-influxdb
feat(influxdb) add elapsed(), fixes #5827
2016-08-29 16:21:59 +02:00
bergquist 9c92d8c4e9 fix(circle-ci): change to ubuntu 14 for CI 2016-08-29 16:12:42 +02:00
chrismartin0077 88ca695361 feat(influxdb) add elapsed(), fixes #5827 2016-08-29 07:05:10 -07:00
Carl Bergquist 7d4cc098a8 Merge pull request #5924 from cmartin0077/master
feat(api) HEAD response, fixes #3854
2016-08-29 15:54:21 +02:00
bergquist c0697b99d6 fix(alerting): adds support for basic auth
closes #5897
2016-08-29 15:50:11 +02:00
chrismartin0077 0050707134 feat(api) HEAD response, fixes #3854 2016-08-29 06:07:44 -07:00
cmartin0077 9c08d7aef5 fix(influxdb) fix tag value autocomplete with upper case values, fixes #5399 (#5919) 2016-08-29 13:03:54 +02:00
Torkel Ödegaard 9d69eaf07b Merge branch 'issue-5812-x-axis' of https://github.com/alexanderzobnin/grafana into graph-panel-non-timeseries 2016-08-27 09:53:10 +02:00
paulroche 5ba6bab237 redact provider_config (#5915) 2016-08-27 09:50:35 +02:00
Trent White ab4f06bc54 redesign email template 2016-08-26 14:25:39 -04:00
Alexander Zobnin 1bdd24ab9e Graph panel: fix merge conflicts introduced by alerting branch, issue #5812. 2016-08-26 21:22:46 +03:00
Alexander Zobnin 7a6d32138b Graph panel: refactor, issue #5812. 2016-08-26 20:47:12 +03:00
Alexander Zobnin 06af566f3f Graph panel: initial elastic raw document format support, issue #5812. 2016-08-25 22:03:42 +03:00
Trent White 35b90afdd0 initial styling 2016-08-24 17:41:29 -04:00
Alexander Zobnin d23e9fa3c3 Graph panel: table format support improvements, issue #5812. 2016-08-23 20:44:58 +03:00
Carl Bergquist 5b9366a9c3 tech(docker): update prometheus config 2016-08-23 11:50:17 +02:00
bergquist d0ca4ca3cd chore(alerting): remove unused files 2016-08-22 17:01:23 +02:00
bergquist 0cbedb4473 chore(api): remove commented endpoints 2016-08-22 16:56:28 +02:00
bergquist b8ccb82382 Merge branch 'alerting' 2016-08-22 16:10:36 +02:00
bergquist 7095a9d7e1 Merge branch 'master' into alerting 2016-08-22 15:31:33 +02:00
bergquist 3b8bba3e9f feat(alerting): add more fields to webhook 2016-08-22 15:11:27 +02:00
bergquist 1ff21b3ee8 docs(example): remove old properties 2016-08-22 14:55:16 +02:00
bergquist f3d6035c59 feat(alerting): add alerts for notification edits 2016-08-22 14:49:40 +02:00
Carl Bergquist 90388710af Merge pull request #5874 from mtanda/cw_api_gateway
(cloudwatch) add api gateway metrics/dimensions
2016-08-22 14:36:40 +02:00
Carl Bergquist 1c25d22f9e Merge pull request #5875 from mtanda/prometheus_time
(prometheus) refactor time calculation
2016-08-22 14:25:52 +02:00
bergquist 457eb91c2f docs(alerting): example dashboards 2016-08-22 13:30:57 +02:00
bergquist 77f9c24050 feat(alerting): add support for count reducer 2016-08-22 13:25:31 +02:00
bergquist 26c6437846 Merge branch 'master' into alerting 2016-08-22 12:27:08 +02:00
bergquist 69de3bcfc7 chore(example): remove example file and add links 2016-08-22 12:26:26 +02:00
bergquist 5a33679470 fix(alerting): remove has no value condition 2016-08-22 12:20:07 +02:00
Mitsuhiro Tanda d9fe41cc8d (prometheus) refactor time calculation 2016-08-20 22:51:33 +09:00
Mitsuhiro Tanda 6bd2bb04a7 (cloudwatch) add api gateway metrics/dimensions 2016-08-20 21:57:20 +09:00
bergquist 3077f992bb docs(changelog): add note about closing #5613 2016-08-19 15:19:08 +02:00
Carl Bergquist 9fdda0e269 Merge pull request #5613 from ctrochalakis/group_by_nodes
feat(graphite): added groupByNodes func def, closes #5612
2016-08-19 15:16:40 +02:00
bergquist 8d49b66dae Merge branch 'Scalingo-database_url' 2016-08-19 14:53:38 +02:00
bergquist aeb1b99648 docs(changelog): add note about closing #5456 2016-08-19 14:51:09 +02:00
bergquist 92a52ccdf7 docs(conf): add more info about using database.url 2016-08-19 14:48:40 +02:00
bergquist c663e32ea8 Merge branch 'database_url' of https://github.com/Scalingo/grafana into Scalingo-database_url 2016-08-19 13:15:44 +02:00
Alexander Zobnin c683c7a448 Graph panel: initial support for table format, issue #5812. 2016-08-18 21:59:28 +03:00
bergquist e415412691 feat(alerting): add image for howto popup
closes #5784
2016-08-18 18:36:58 +02:00
bergquist d3421c671c fix(alerting): make sure xorm can reset execution_error 2016-08-18 17:25:32 +02:00
bergquist 28ac05b1d1 docs(changelog): add filter for org switcher
closes #2609
2016-08-18 15:52:14 +02:00
bergquist 6d60d125d3 Merge branch 'Othyus-filter_orgs' 2016-08-18 15:48:47 +02:00
bergquist e3bbf96b37 Merge branch 'filter_orgs' of https://github.com/Othyus/grafana into Othyus-filter_orgs 2016-08-18 15:48:01 +02:00
Alexander Zobnin 284a6ee629 Graph panel: rename X axis modes, issue #5812. 2016-08-18 15:34:32 +03:00
bergquist def4632f08 test(alerting): add falsification test 2016-08-18 14:13:39 +02:00
bergquist cbe7f8b697 feat(config): add ascii dragon to sample.ini 2016-08-18 14:13:02 +02:00
bergquist d28df71c3b feat(alerting): add support for "no_value" evaluator 2016-08-18 11:44:25 +02:00
Torkel Ödegaard 09cdf3e9e1 feat(alerting): show execution errors in alert list 2016-08-18 11:37:35 +02:00
Torkel Ödegaard 5cf9711862 feat(alerting): added eval match to test results 2016-08-18 11:22:24 +02:00
Torkel Ödegaard 2f953d75a6 Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-08-18 10:07:45 +02:00
Torkel Ödegaard 9028d4899f feat(alerting): alert list fixes 2016-08-18 10:07:31 +02:00
bergquist 631acc2bf9 feat(alerting): only show available queries in alert query 2016-08-18 10:02:17 +02:00
Torkel Ödegaard 9b5a7b5ef6 feat(alerting): added alert howto text, closes #5784 2016-08-18 09:58:20 +02:00
Torkel Ödegaard 902314d3a1 Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-08-18 09:04:00 +02:00
Torkel Ödegaard 75a6c2b612 feat(alerting): added validation that checks valid data source and checks for template variables in graphite query, #5841 2016-08-18 09:03:46 +02:00
beejeebus 998ed097d3 Update aws-sdk from v1.0.0 to v1.4.1, fixes #5763. (#5813) 2016-08-18 08:19:53 +02:00
Roman Vynar d086f5d398 Align step with interval passed to Prometheus query using rate() (#5839) 2016-08-18 08:19:32 +02:00
bergquist 6d080904fa tech(alerting): empty string does not update database 2016-08-17 22:13:27 +02:00
bergquist 4154a4066f feat(alerting): handle all results, even due they have errors
DON'T SWALLOW THE ERR CARL
2016-08-17 22:12:08 +02:00
bergquist 158ce06167 fix(alerting): cleanup alerting example dashboard 2016-08-17 17:21:57 +02:00
Torkel Ödegaard eabba50bbf Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-08-17 15:49:18 +02:00
Torkel Ödegaard 2e7cb04490 feat(alerting): some final changes to alert list #5784 2016-08-17 15:48:58 +02:00
Torkel Ödegaard 63a283b4bc feat(alerting): working on alert state filters for alert list 2016-08-17 11:00:00 +02:00
bergquist 7d1e5b6374 tech(alerting): remove old crit/warn properties from dashboard 2016-08-17 10:53:24 +02:00
bergquist d8cfe22318 tech(alerting): add example dashboard with many alerts 2016-08-17 10:35:48 +02:00
Torkel Ödegaard da59d6547f Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-08-17 10:03:57 +02:00
Torkel Ödegaard 05697d5ecd Merge branch 'master' into alerting
Conflicts:
	conf/sample.ini
2016-08-17 10:03:33 +02:00
Torkel Ödegaard 6fae5a3b4e Merge branch 'v3.1.x' 2016-08-17 10:02:08 +02:00
Torkel Ödegaard 093563ac37 fix(metrics): restored prefix default to prod.grafana.. 2016-08-17 10:01:55 +02:00
Torkel Ödegaard f9b628ad0e Merge branch 'v3.1.x'
Conflicts:
	conf/defaults.ini
	conf/sample.ini
	pkg/metrics/graphite.go
	pkg/metrics/graphite_test.go
2016-08-17 09:53:46 +02:00
Torkel Ödegaard 2b2b64865b Merge branch 'master' of github.com:grafana/grafana 2016-08-17 09:42:52 +02:00
Torkel Ödegaard 159ea69e5d fix(OpenTSDB): correct content-type, fixes #4965 2016-08-17 09:42:40 +02:00
bergquist 6497b307c4 feat(alerting): save execution error upon state changed 2016-08-17 09:27:29 +02:00
bergquist 9915f15ed0 feat(alerting): adds sql layer for saving execution errors 2016-08-17 07:49:14 +02:00
Torkel Ödegaard 0951da9c89 Merge branch 'v3.1.x' of github.com:grafana/grafana into v3.1.x 2016-08-16 22:31:51 +02:00
Torkel Ödegaard a5f0f508ea feat(inspector): fixed error handling, showing response body when data proxy returns text/html body 2016-08-16 22:31:26 +02:00
Torkel Ödegaard 434332f02d feat(alerting): changed fontsize in alert list 2016-08-16 21:26:54 +02:00
Alexander Zobnin 93515d0ffc Graph panel: display only bars in histogram mode, issue #5812. 2016-08-16 21:53:53 +03:00
Alexander Zobnin 113173be3d Graph panel: preserve series options (colors and other), issue #5812. 2016-08-16 21:12:35 +03:00
Alexander Zobnin 63886598e9 Graph panel: add value option (min, max, avg, etc), issue #5812. 2016-08-16 19:43:14 +03:00
Alexander Zobnin e39e5f9a9b Graph-panel: Add initial histogram option, issue #5812. 2016-08-16 18:45:57 +03:00
Torkel Ödegaard 15c11fdb54 Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-08-16 16:51:24 +02:00
Torkel Ödegaard 0b7fa3c19d feat(alerting): minor progress on alert list, #5784 2016-08-16 16:50:36 +02:00
bergquist de714e3398 tech(docker): add default db for postgres 2016-08-16 15:54:13 +02:00
bergquist c7cb93a33a style(alerting): improve codestyle for evaluators 2016-08-16 12:44:31 +02:00
bergquist fb7f2ae2e2 feat(alerting): adds within_range and outside_range evaluators
closes #5829
2016-08-16 12:37:07 +02:00
bergquist b5d92b6191 test(alerting): fix broken tests 2016-08-16 12:37:07 +02:00
Torkel Ödegaard 6b90587d27 feat(alerting): fixing failing go unit test 2016-08-16 10:22:16 +02:00
Torkel Ödegaard 65ce01fbff feat(alerting): fixing failing typescript build 2016-08-16 10:09:07 +02:00
Torkel Ödegaard fe9d591b28 Merge branch 'alerting' of github.com:grafana/grafana into alerting
Conflicts:
	pkg/services/sqlstore/migrations/alert_mig.go
2016-08-16 09:54:06 +02:00
Torkel Ödegaard f934081bcb feat(alerting): making progress on alerting list, #5784 2016-08-16 09:52:45 +02:00
Alexander Zobnin 7588ee974d Working on non time series X-axis feature. 2016-08-15 22:46:34 +03:00
bergquist aaabdbe33b feat(alerting): make post execution fields nullable 2016-08-15 20:26:36 +02:00
bergquist 2c2157f3b0 fix(alerting): rename events to evalMatches 2016-08-15 20:17:32 +02:00
Claudius Zingerli 08932b8ebc InfluxDB data source: Removed 'required' attribute from User/Password (#5820) 2016-08-15 17:56:46 +02:00
Torkel Ödegaard 9f29c54170 Merge branch 'query_part_refactor' into alerting
Conflicts:
	pkg/services/sqlstore/migrations/alert_mig.go
	pkg/services/sqlstore/migrations/heartbeat_mig.go
2016-08-15 17:54:42 +02:00
Torkel Ödegaard d8d951c810 feat(alerting): can now change reducer 2016-08-15 17:53:44 +02:00
Torkel Ödegaard 1418cbbd8b feat(query_part): refactoring query part 2016-08-15 17:20:45 +02:00
Torkel Ödegaard 0392fde34e feat(alerting): doing schema changes 2016-08-15 15:12:43 +02:00
bergquist 3195209878 tech(circle): rearrange build order 2016-08-15 14:01:20 +02:00
Torkel Ödegaard befca9bb2f feat(query parts): refactoring query part component to support actions 2016-08-15 13:51:55 +02:00
bergquist f7a9102523 feat(metrics): improve graphite settings
Fixes the broken support for overriding settings with ENV variables.
closes #5769
2016-08-15 09:59:55 +02:00
bergquist cf6736d480 fix(metrics): add ending dot for graphite prefix 2016-08-15 09:58:32 +02:00
bergquist 41790c6709 fix(metrics): hide none existing metrics settings 2016-08-15 09:58:23 +02:00
bergquist ebecc5e5a0 fix(metrics): make metrics cfg backwards compatible 2016-08-15 09:57:49 +02:00
Torkel Ödegaard 2c1b893c55 feat(metrics): minor fix for internal metrics fix PR #5758 2016-08-15 09:57:23 +02:00
bergquist 0524d0c625 fix(metrics): replaces . with _ in instance name
closes #5739
2016-08-15 09:57:00 +02:00
bergquist 2b2e015d62 feat(cli): add default plugin folder for MAC OS
closes #5806
2016-08-15 09:18:56 +02:00
Torkel Ödegaard cd9bd5be17 Update CHANGELOG.md 2016-08-15 09:15:20 +02:00
bergquist 7ce13ef075 docs(changelog): add note about fixing #5806 2016-08-15 09:13:49 +02:00
bergquist 7a913f77d3 feat(cli): add default plugin folder for MAC OS
closes #5806
2016-08-15 08:54:35 +02:00
bergquist 4d0982a21c Merge branch 'master' into alerting 2016-08-15 07:58:30 +02:00
Torkel Ödegaard 0ea3458f69 Merge branch 'v3.1.x'
Conflicts:
	public/app/features/dashboard/dynamic_dashboard_srv.ts
2016-08-14 14:47:14 +02:00
Torkel Ödegaard 58df60f670 fix(templating): another fix for repeating panels and having old panels/scoped vars stuck after switching repeat variable, fixes #5795 2016-08-14 14:45:49 +02:00
Julian Einwag cbf0e77add fix repeat panels (#5796) 2016-08-14 13:59:16 +02:00
Torkel Ödegaard 1eca0d7c53 docs(): updated docs 2016-08-14 13:58:04 +02:00
Torkel Ödegaard 76e4b7ce3b Merge branch 'master' of github.com:grafana/grafana 2016-08-14 13:51:09 +02:00
Julian Einwag deb245f526 fix repeat panels (#5796) 2016-08-14 13:50:49 +02:00
Mitsuhiro Tanda 7a1011ac39 (cloudwatch) support ApplicationELB (#5802) 2016-08-14 13:21:17 +02:00
Torkel Ödegaard 8499d32d0f Merge branch 'master' of github.com:grafana/grafana 2016-08-14 13:18:55 +02:00
Torkel Ödegaard d894c13718 fix(graph): fixed issue with tooltip introduced in recent commit 2016-08-14 13:18:23 +02:00
Torkel Ödegaard 46ea3ed971 fix(godep): fixed godep dependency 2016-08-13 13:07:55 +02:00
bergquist fb7a6c0764 feat(alerting): list all series in alert email 2016-08-13 12:50:51 +02:00
Carl Bergquist a530df8449 Merge pull request #5809 from kou/patch-1
Update the number of ways
2016-08-13 12:18:01 +02:00
bergquist c4e905474a feat(alerting): improve email notifications layout 2016-08-13 11:24:03 +02:00
Kouhei Sutou 46630df88d Update the number of ways 2016-08-13 14:12:29 +09:00
Torkel Ödegaard 74dbd7fb36 feat(alerting): disable visual thresholds while alert is enabled 2016-08-12 13:19:06 +02:00
Torkel Ödegaard 7242dc2ebe feat(thresholds): hide threshold handles when second y axis is shown 2016-08-12 10:50:31 +02:00
Torkel Ödegaard 597103a1f2 Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-08-12 10:32:58 +02:00
Torkel Ödegaard 06210a4a22 feat(thresholds): refactoring and adding many unit tests 2016-08-12 10:32:46 +02:00
bergquist 1dcae464fe chore(notifications): remove commented test 2016-08-12 10:17:21 +02:00
bergquist 16e75a3036 feat(alerting): add alert message to slack integration 2016-08-12 10:12:04 +02:00
bergquist e7613b8bc0 fix(metrics): typo 2016-08-12 08:15:53 +02:00
bergquist 2fa97427eb fix(metrics): add ending dot for graphite prefix 2016-08-12 08:06:54 +02:00
Torkel Ödegaard 895cff78b6 feat(thresholds): more work on thresholds, within and outside types no work 2016-08-11 22:22:15 +02:00
Torkel Ödegaard 7a5dda9e7c Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-08-11 21:33:29 +02:00
Torkel Ödegaard 6793eed6c5 feat(thresholds): dragging thresholds works again 2016-08-11 21:32:59 +02:00
Torkel Ödegaard 224ceb0ae5 feat(thresholds): updated design for grab handles 2016-08-11 21:22:40 +02:00
bergquist 937726499f feat(alerting): add global usage metrics for alerting
closes #5786
2016-08-11 21:12:46 +02:00
Torkel Ödegaard 89ca15f3a1 feat(thresholds): lots of progress on thresholds 2016-08-11 18:25:41 +02:00
bergquist ae15de119f Merge branch 'master' into alerting 2016-08-11 17:01:35 +02:00
bergquist f07b2ac446 fix(metrics): hide none existing metrics settings 2016-08-11 17:00:09 +02:00
bergquist cb6fd4ca78 test(alerting): fixes broken unit test 2016-08-11 16:55:08 +02:00
bergquist 99e99922b4 feat(alerting): add support for uploading images to webdav.
closes #5770
2016-08-11 16:48:54 +02:00
Torkel Ödegaard 72a67b39f1 feat(thresholds): more work thresholds 2016-08-11 15:18:21 +02:00
Torkel Ödegaard 6881db87bb Merge branch 'alerting' into thresholds_v3 2016-08-11 10:31:39 +02:00
Torkel Ödegaard 8878a55dc6 Merge branch 'master' into alerting 2016-08-11 10:31:15 +02:00
Torkel Ödegaard da6ac07b1d Merge branch 'v3.1.x' 2016-08-11 10:29:48 +02:00
Torkel Ödegaard 0d26bc63ae fix(graphite): minor fix/improvement to graphite error handling when doing metric exploration in query editor, fixes #5778 2016-08-11 10:29:28 +02:00
Torkel Ödegaard 780ec92dd8 fix(docs): fixed plugins docs, fixes #5777 2016-08-11 07:39:34 +02:00
Jeremy Bingham 7150571e60 Mac grafana wrapper script (#5779)
* One of the homebrew folks first asked for a wrapper script to make launching grafana easier. Later I was asked to remove it and submit it upstream, so here it is.

* add instructions for installing grafana HEAD from git with homebrew back to the docs
2016-08-11 07:37:35 +02:00
Jeremy Bingham 2c4ab4af02 Mac grafana wrapper script (#5779)
* One of the homebrew folks first asked for a wrapper script to make launching grafana easier. Later I was asked to remove it and submit it upstream, so here it is.

* add instructions for installing grafana HEAD from git with homebrew back to the docs
2016-08-11 07:36:14 +02:00
Torkel Ödegaard fbb8f8e691 feat(alerting): making progress on alert handles 2016-08-10 21:37:10 +02:00
Torkel Ödegaard 2639c38912 fix(threshold): remove old threshold properties 2016-08-10 20:44:39 +02:00
Torkel Ödegaard bdb8d77562 feat(thresholds): migration from previous threshold schema 2016-08-10 20:41:21 +02:00
Alexander Zobnin 124961a9e3 Explicitly set charset to utf-8 in viewJson(), fixes #5719. (#5774) 2016-08-10 20:23:58 +02:00
Torkel Ödegaard 7c0675798e feat(thresholds): new thresholds options are looking ok 2016-08-10 17:32:34 +02:00
Torkel Ödegaard 0f8c8517e3 feat(thresholds): adding a new form of thresholds options 2016-08-10 15:27:33 +02:00
bergquist 95c1a4a936 feat(alerting): implement more simple reducers 2016-08-10 14:06:17 +02:00
bergquist f2436fc7cd test(alerting): add tests for simple reducer 2016-08-10 13:52:15 +02:00
Torkel Ödegaard 4fd8b2ace4 Merge branch 'master' into alerting 2016-08-10 12:53:41 +02:00
Torkel Ödegaard a56cf9d6fd Merge branch 'v3.1.x' 2016-08-10 12:44:43 +02:00
Torkel Ödegaard 9a7e0eaf42 fix(dashboard): fixed drag and drop issue in chrome, fixes #5767 2016-08-10 12:43:36 +02:00
bergquist 03f0bc46a1 fix(metrics): make metrics cfg backwards compatible 2016-08-10 11:15:49 +02:00
Torkel Ödegaard c5d0c9f088 Merge branch 'v3.1.x' 2016-08-10 08:42:30 +02:00
Torkel Ödegaard c0301349fb docs(): update mac docs 2016-08-10 08:39:57 +02:00
Torkel Ödegaard 624e30e743 fix(docs): minor doc fixes, fixes #5751 2016-08-10 08:38:08 +02:00
Torkel Ödegaard d95545b5d3 feat(graph tooltip): refactoring PR #3063 2016-08-10 08:31:53 +02:00
Torkel Ödegaard 34804bda6d Merge branch 'issue-3063' of https://github.com/alexanderzobnin/grafana into alexanderzobnin-issue-3063 2016-08-10 08:08:57 +02:00
Torkel Ödegaard d49f0569f2 feat(metrics): minor fix for internal metrics fix PR #5758 2016-08-10 08:06:10 +02:00
Torkel Ödegaard 61756d2ae6 feat(alerting): removed delete button 2016-08-10 07:58:40 +02:00
bergquist de47710f1e tech(circle): rearrange build order 2016-08-09 14:28:44 +02:00
bergquist 5b57210aeb fix(metrics): replaces . with _ in instance name
closes #5739
2016-08-09 14:06:03 +02:00
bergquist d6fdb598b0 fix(alerting): gofmt 2016-08-08 14:46:47 +02:00
Alexander Zobnin f8f7543d4a Fix Elastic datasource tests - use moment.utc() instead moment() to prevent timezone-related issues, fixes #5733. (#5746) 2016-08-07 12:01:53 +02:00
bmundt 6d1dd95ab3 adds check for making datasource template variables children of other template variables (#5717) 2016-08-05 10:03:46 +02:00
hc4 4d40326706 Add refresh query parameter parsing (#5729) 2016-08-04 18:58:59 +02:00
Torkel Ödegaard 34ea7312bc docs(): added missing snapshot config options, fixes #5708 2016-08-02 09:35:15 +02:00
Torkel Ödegaard 01e5fd623b Update latest.json 2016-08-02 09:31:02 +02:00
Torkel Ödegaard e044a65d08 feat(alerting): updated 2016-08-01 22:15:28 +02:00
Alexander Zobnin 2c283ddd77 Fixed shared tooltip time calculation. Fixes #3063. 2016-08-01 20:41:15 +03:00
Torkel Ödegaard 1edd224168 feat(alerting): fixing failing unit tests 2016-08-01 14:34:58 +02:00
Torkel Ödegaard e6c4e47849 updated dependencies 2016-08-01 14:15:41 +02:00
Torkel Ödegaard 2bfccd77d4 docs(): updated release links 2016-08-01 12:47:55 +02:00
Torkel Ödegaard 84d7305d37 docs(): updated release links 2016-08-01 12:45:31 +02:00
Torkel Ödegaard fbad17d3a1 docs(): updated changelog 2016-08-01 12:27:03 +02:00
Torkel Ödegaard 317ffd1b68 Merge branch 'master' of github.com:grafana/grafana 2016-08-01 12:24:01 +02:00
Torkel Ödegaard 49abb205a0 Merge branch 'v3.1.x'
Conflicts:
	public/sass/_variables.light.scss
2016-08-01 12:23:36 +02:00
Torkel Ödegaard a4d27083d0 fix(tests): fixed unit test broken in recent dynamic dashboard fix 2016-08-01 12:20:16 +02:00
Torkel Ödegaard a9cf7cd4f0 fix(light theme): fixes issue with hidden queries in light theme, fixes #5697 2016-08-01 11:58:12 +02:00
Torkel Ödegaard 44d1393480 fix(templating): fixed issue with panel/row repeat when saving dashboard, fixes #5591 2016-08-01 10:50:33 +02:00
Torkel Ödegaard b46af0069e fix(footer): fixed link in footer, #5690 2016-08-01 10:09:43 +02:00
Torkel Ödegaard 357358898d feat(annotations): working on alert annotations, #5694 2016-08-01 10:07:00 +02:00
Torkel Ödegaard c5e90b1801 feat(alerting): more polish on alerting tab UI 2016-07-31 21:58:12 +02:00
Torkel Ödegaard 3b69c8f687 feat(alerting): new design for alert tab with sidemenu 2016-07-31 09:31:32 +02:00
Torkel Ödegaard 2b276d5cd1 feat(alerting): working on alert notification and image rendering 2016-07-30 13:36:21 +02:00
Torkel Ödegaard f9ddfb4337 Merge branch 'master' into alerting 2016-07-29 15:07:47 +02:00
Torkel Ödegaard 79138e211f Merge branch 'v3.1.x' 2016-07-29 15:07:17 +02:00
Torkel Ödegaard 741b7353c1 Merge branch 'v3.1.x' of github.com:grafana/grafana into v3.1.x 2016-07-29 15:06:09 +02:00
Torkel Ödegaard c4e7a3ae89 fix(png rendering): another fix for #5606 2016-07-29 15:04:51 +02:00
Torkel Ödegaard 4fc50742a0 feat(alerting): working on image rendering with alert notifications 2016-07-29 14:55:02 +02:00
Torkel Ödegaard f9a28d3306 feat(alerting): slack notification improvements, #5679 2016-07-29 13:41:42 +02:00
Torkel Ödegaard 01da3f6cb2 feat(alerting): worked on improving slack alerts 2016-07-28 17:03:53 +02:00
Torkel Ödegaard 717cce014b feat(alerting): refactoring 2016-07-27 17:07:44 +02:00
Torkel Ödegaard 6aaf4c97a2 feat(alerting): refactoring conditions out to seperate package 2016-07-27 16:18:10 +02:00
Torkel Ödegaard ae5f8a76d9 feat(alerting): lots of progress on notifications, refactored them out to their own package, restored webhook notitication and added slack notification 2016-07-27 12:09:55 +02:00
Torkel Ödegaard 77c66a88d9 Merge branch 'master' into alerting 2016-07-27 10:22:00 +02:00
Torkel Ödegaard c997923b17 Merge branch 'master' of github.com:grafana/grafana 2016-07-27 10:21:38 +02:00
Torkel Ödegaard e789d0df63 Merge branch 'v3.1.x' 2016-07-27 10:21:16 +02:00
Torkel Ödegaard 89dc3b88d1 fix(test): fixed failing test caused by recent change 2016-07-27 10:20:48 +02:00
Torkel Ödegaard c2eeb6dda0 fix(alerting): minor notification fix 2016-07-27 10:15:21 +02:00
Thib17 732c84c230 Enable scaling down seconds unit s > ms > µs > ns (#5642) 2016-07-27 10:10:01 +02:00
Torkel Ödegaard cde1bbff78 Merge branch 'alert_conditions' into alerting 2016-07-27 09:52:42 +02:00
Torkel Ödegaard c675ffc682 Merge branch 'master' into alerting 2016-07-27 09:45:16 +02:00
Mark Henderson 39be7cf7d7 Added grafana-cli command. Added public documentation for specifying plugin version when installing. (#5665) 2016-07-27 09:41:33 +02:00
Torkel Ödegaard e8e8463828 docs(): updated changelog 2016-07-27 09:39:46 +02:00
Torkel Ödegaard e4592c8d53 Merge branch 'v3.1.x' 2016-07-27 09:36:46 +02:00
Torkel Ödegaard 971e2d62f1 fix(zoom): fixed zoom in and out issues when graph is embedded, fixes #5666, fixes #4489 2016-07-27 09:36:35 +02:00
Torkel Ödegaard 5155c8a753 feat(templating): set default min span to 4, fixes #5662 2016-07-26 17:20:27 +02:00
Torkel Ödegaard 0b0f6b0848 feat(alerting): made very basic threshold viz work again 2016-07-26 14:35:42 +02:00
Torkel Ödegaard 0d9b98da6d feat(alerting): progress on email notifications 2016-07-26 12:29:52 +02:00
Torkel Ödegaard 6cb1dafb1d feat(alerting): progress on notifications 2016-07-25 16:26:28 +02:00
Torkel Ödegaard 8df558dece feat(notifications): refactoring notification handling 2016-07-25 13:52:17 +02:00
Torkel Ödegaard 9f14b209bd fix(html): moved body tag, fixes #5648 2016-07-25 12:21:51 +02:00
Torkel Ödegaard d4e2bb70e9 Merge branch 'v3.1.x'
Conflicts:
	package.json
2016-07-25 12:20:59 +02:00
Torkel Ödegaard 66a72e9ece changed version to 3.1.1 2016-07-25 12:20:21 +02:00
Torkel Ödegaard ee0d6ecfe6 Merge branch 'master' of github.com:grafana/grafana 2016-07-25 12:04:58 +02:00
Torkel Ödegaard def4d8f8dc docs(): updated changelog 2016-07-25 12:04:43 +02:00
Torkel Ödegaard 9fd7676846 Merge branch 'v3.1.x' 2016-07-25 12:03:40 +02:00
Torkel Ödegaard 0de0f4d014 feat(templating): fixed issue with template variables set to reload on dashboard load being issued multiple times, fixes #5637 2016-07-25 12:02:59 +02:00
bmundt f6b1d5a84a Added '!=' option for where clause in the influx query builder (#5646) 2016-07-25 10:36:38 +02:00
Torkel Ödegaard 9f777a535b fix(): removed dashboard version to schema version migration 2016-07-23 13:29:48 +02:00
Torkel Ödegaard 6d28365e84 docs(): updated changelog 2016-07-23 12:59:07 +02:00
Torkel Ödegaard 7a2e8324b9 Merge branch 'v3.1.x' 2016-07-23 12:54:23 +02:00
Torkel Ödegaard ddf579f204 fix(mixed data sources): fix when using two graphite data sources in mixed mode, fixes #5617 2016-07-23 12:54:11 +02:00
Torkel Ödegaard b943e41434 Merge branch 'master' of github.com:grafana/grafana 2016-07-23 12:01:48 +02:00
Torkel Ödegaard 4a33e2023f Merge branch 'v3.1.x' 2016-07-23 12:01:27 +02:00
Torkel Ödegaard 3abbf08a17 tech(): upgrade jquery to 2.2.4, closes #5627 2016-07-23 12:00:45 +02:00
Torkel Ödegaard 474a821767 fix(elasticsearch): fix json escape logic when doing terms template value lookup, fixes #5485 2016-07-23 11:52:49 +02:00
Torkel Ödegaard 14eba30f63 feat(alerting): more work on notifications 2016-07-23 11:50:48 +02:00
Peter Bonney 62e162c44c Update dashboard.md (#5640)
The key returned by `GET /api/dashboards/db/:slug` is "dashboard" (not "model").
2016-07-23 11:46:20 +02:00
Torkel Ödegaard a6c6094775 feat(alerting): started reworking notifications 2016-07-22 16:45:17 +02:00
Mitsuhiro Tanda 490ea18638 (cloudwatch) fix, don't block by white list (#5632) 2016-07-22 13:15:18 +02:00
Torkel Ödegaard 7eb2d2cf47 feat(alerting): working on state management 2016-07-22 13:14:09 +02:00
Torkel Ödegaard 783d697529 feat(alerting): more output when testing alert 2016-07-21 21:54:12 +02:00
Torkel Ödegaard b073fe0eba feat(alerting): more work on handling result and saving state 2016-07-21 17:31:46 +02:00
Torkel Ödegaard f0fc336e88 feat(alerting): worked on alert condition eval tests 2016-07-21 16:19:28 +02:00
Torkel Ödegaard 3ad38eefd2 feat(alerting): test results look better 2016-07-21 13:57:19 +02:00
Torkel Ödegaard f6a160b270 feat(alerting): testing alert is starting to work 2016-07-21 13:09:12 +02:00
Torkel Ödegaard 9e91aacd34 feat(alerting): progress on testing alerts 2016-07-21 10:29:11 +02:00
Torkel Ödegaard fb636344a6 feat(alerting): began work on testing alert rule from UI without having to save it 2016-07-20 16:13:36 +02:00
Torkel Ödegaard 0ce55600bb feat(alerting): progress on alerting backend 2016-07-20 14:28:02 +02:00
Torkel Ödegaard 3219d98a92 feat(alerting): starting work on condition evaluation 2016-07-20 09:30:31 +02:00
Torkel Ödegaard f872d5cfa3 feat(alerting): more refactoring work in backend code 2016-07-19 22:36:59 +02:00
Torkel Ödegaard 2a30baef05 feat(alerting): progress on updating extractor to work with new alert model 2016-07-19 21:00:41 +02:00
Torkel Ödegaard f60efed5d8 feat(alerting): progress on refactoring backend alert rule model 2016-07-19 17:45:37 +02:00
Torkel Ödegaard 20fcffb71e feat(alerting): working on alerting conditions model 2016-07-19 16:15:26 +02:00
Christos Trochalakis 824bf9f029 feat(graphite): added groupByNodes func def, closes #5612 2016-07-19 14:23:13 +03:00
Torkel Ödegaard f38c954639 feat(alerting): more work on alert conditions 2016-07-19 11:54:41 +02:00
Torkel Ödegaard 29d308e447 feat(alerting): refactoring alert model to use conditions concept 2016-07-19 11:24:27 +02:00
Torkel Ödegaard 0f555d6ab5 fix(alerting): minor fix 2016-07-19 09:28:49 +02:00
Torkel Ödegaard b0fe69822a Merge branch 'master' into alerting
Conflicts:
	public/app/core/services/alert_srv.ts
	public/app/partials/confirm_modal.html
2016-07-18 18:22:35 +02:00
Torkel Ödegaard 3f861dd039 Merge branch 'v3.1.x' 2016-07-18 16:27:27 +02:00
Torkel Ödegaard 3ae327320a fix(prometheus): fixed svg link in prometheus dashboard, fixes #5604 2016-07-18 16:27:02 +02:00
Torkel Ödegaard 78d0badffe Merge branch 'v3.1.x' of github.com:grafana/grafana into v3.1.x 2016-07-18 16:22:31 +02:00
Torkel Ödegaard 575b015fe0 fix(panel rendering): Fixed png panel rendering timing issue, #5606 2016-07-18 16:18:00 +02:00
Torkel Ödegaard b9a2546a10 fix(iframe): fixed issue with using full height of iframe, fixes #5605 2016-07-18 16:17:46 +02:00
Torkel Ödegaard 7ad0904fdb :Merge branch 'master' of github.com:grafana/grafana 2016-07-18 16:16:44 +02:00
Torkel Ödegaard b9c4107361 docs(): updated changelog 2016-07-18 16:16:35 +02:00
Torkel Ödegaard ffd865c7ca fix(panel rendering): Fixed png panel rendering timing issue, #5606 2016-07-18 16:13:50 +02:00
Torkel Ödegaard e507bb6dd7 fix(iframe): fixed issue with using full height of iframe, fixes #5605 2016-07-18 15:41:06 +02:00
Torkel Ödegaard 8f8ee28e64 docs(): updated changelog 2016-07-18 14:06:31 +02:00
Torkel Ödegaard 6c6dae1c92 Merge branch 'elasticsearch_precision_threshold' of https://github.com/lucasrodcosta/grafana into lucasrodcosta-elasticsearch_precision_threshold 2016-07-18 13:56:34 +02:00
Torkel Ödegaard c82d5f86ac fix(singlestat): fixed minor editor blur issue on decimal option that did not cause update of rendered value, fixes #5004 2016-07-18 11:24:41 +02:00
Loren West 51940fa209 Tooltip detatch too soon on mobile click (#5598)
* Tooltip detatch too soon on mobile click

* Fixed syntax error
2016-07-18 09:04:06 +02:00
Torkel Ödegaard f13b869aa4 feat(alerting): work on alerting 2016-07-14 13:32:16 +02:00
Jack Meagher 2c77f2231e Do not substitute #[A-Z] in graphite target when invalid ref (#5581)
* Do not substitute #[A-Z] in graphite target when invalid ref

In the case where #[A-Z] does not reference another query, such as #J when there
are only 2 queries, do not perform the substitution. This prevents the situation
target name without a query labelled J (10th query).

* Do not substitute #[A-Z] in graphite target when invalid ref

In the case where #[A-Z] does not reference another query, such as #J when there
are only 2 queries, do not perform the substitution. This prevents the situation
target name without a query labelled J (10th query).
2016-07-14 10:29:22 +02:00
Torkel Ödegaard 624cd6fc0a feat(alerting): cleanup, removed alert changes table and code 2016-07-13 11:58:55 +02:00
Torkel Ödegaard 82eebf64b6 fix(graph): Fix so that zoom works even when no data exists, fixes #5570 2016-07-13 10:02:53 +02:00
Torkel Ödegaard cc5c45112a Merge branch 'master' of github.com:grafana/grafana 2016-07-12 15:55:10 +02:00
Torkel Ödegaard 4bb4d7f7d3 Merge branch 'v3.1.x' 2016-07-12 15:54:31 +02:00
Torkel Ödegaard 383b313027 Update CHANGELOG.md 2016-07-12 15:17:04 +02:00
Torkel Ödegaard 0f9f903e09 Update latest.json 2016-07-12 15:16:46 +02:00
Torkel Ödegaard 6c2a61001a docs(): updated download links 2016-07-12 13:19:20 +02:00
Torkel Ödegaard d007363e7c bumbped version from beta1 to stable 2016-07-12 08:42:28 +02:00
Torkel Ödegaard b2acac3a41 feat(apps): more polish on app dashboard save warning, #5529 2016-07-12 08:41:56 +02:00
Torkel Ödegaard f3db2fa262 feat(plugins): hide link on small screens 2016-07-11 19:16:35 +02:00
Torkel Ödegaard 5b4fd8e9c8 Merge branch 'v3.1.x' of github.com:grafana/grafana into v3.1.x 2016-07-11 19:07:32 +02:00
Torkel Ödegaard 81af8f072c feat(links): updated links to grafana.net 2016-07-11 19:07:16 +02:00
Torkel Ödegaard d9096110f8 Merge branch 'master' into alerting
Conflicts:
	pkg/api/dashboard.go
	pkg/models/dashboards.go
	pkg/services/sqlstore/dashboard.go
2016-07-11 18:28:07 +02:00
Torkel Ödegaard 817f24e6fb Merge remote-tracking branch 'origin/development' 2016-07-11 15:24:24 +02:00
Bryan Irvine eafb0f3248 get rid of weird line breaks and use action (#4926)
* get rid of weird line breaks and use action

When using restarts/stops/starts you'd get weird output sometimes, Strange line breaks 'OK' status overlapping the next lines etc...
This fixes those moves OK to the right place and colorizes them correctly.

* added : for more uniformity

when doing a restart the output looked like:
Stopping Grafana Server ...                                [  OK  ]
Starting Grafana Server: ...                               [  OK  ]

The Stopping line did not have a colon. I added it just to make it look better.
2016-07-11 15:23:39 +02:00
stuart nelson eb35f8cb89 [prometheus] Use panelId and target.refId for requestId
Using these two values ties requests to a
particular query position within a panel, ensuring
that requests are canceled if:

- Duplicate requests with the same query are sent
- Requests from the same query position (but a
different query) are sent

The last point is important as it identifies
queries by a physical location in the dashboard
instead of with the query expression.  If a
different query from the same position in a panel
is sent, the previous request should be canceled.
2016-07-11 14:47:14 +02:00
Torkel Ödegaard 9055beff1a fix(table): fixed merge issue 2016-07-11 11:09:20 +02:00
Torkel Ödegaard e518f50248 docs(): updated changelog 2016-07-11 10:09:49 +02:00
Torkel Ödegaard 08202dcb83 Merge branch 'v3.1.x' 2016-07-11 09:39:17 +02:00
Torkel Ödegaard 65683ab241 feat(table): added sanitize html option to column styles for table panel, fixes #4596 2016-07-11 09:38:06 +02:00
Torkel Ödegaard 4c4cb20bde tech(sass): changed sass lint version to 1.7.0 2016-07-08 22:12:10 +02:00
Torkel Ödegaard 4133526d8d feat(build): updated sass lint 2016-07-08 21:04:58 +02:00
Alexander Akulov 010dbddf59 Fix double slashes in POST request to ES (#5536) 2016-07-08 18:24:08 +02:00
Torkel Ödegaard 12d455f3c3 Merge branch 'v3.1.x' of github.com:grafana/grafana into v3.1.x 2016-07-08 18:23:15 +02:00
Torkel Ödegaard 615b692442 feat(apps): fixed unit tests 2016-07-08 18:21:25 +02:00
Torkel Ödegaard ebdf0564eb feat(apps): plugin dashboard sync is starting to work 2016-07-08 17:44:57 +02:00
Torkel Ödegaard 68a8d9bc91 feat(apps): more work on plugin dashboard sync 2016-07-08 13:41:46 +02:00
Torkel Ödegaard 85be7dd902 feat(apps): progress on app dashboard sync 2016-07-08 12:26:51 +02:00
Torkel Ödegaard d44325affd feat(apps): progress on app dashboard imports 2016-07-08 09:35:06 +02:00
Fraser Savage 5a8efa9a52 Update configuration.md (#5527)
Insert missing backtick.
2016-07-08 07:12:26 +02:00
Torkel Ödegaard b62f1f00cd feat(apps): auto update dashboard dashboards, #5529 2016-07-07 18:11:03 +02:00
Torkel Ödegaard 3f83bf6e47 Merge branch 'v3.1.x' 2016-07-07 14:48:41 +02:00
Torkel Ödegaard 4545b4d323 fix(login): minor fix redirect on login change 2016-07-07 14:48:22 +02:00
bmundt e58ccc5a83 Hex units (#5530)
* added hex units

* deleted blank line, to fix style error

* added unit tests

* updated unit tests and changed the way it handles negative hex0x
2016-07-07 08:54:51 +02:00
Torkel Ödegaard 60abe75615 Merge branch 'v3.1.x' 2016-07-06 10:10:25 +02:00
Torkel Ödegaard d74eb8c188 fix(login): fixed so that you get redirect back to the page or dashboard you where on when you clicked on sign in link, fixes #3312 2016-07-06 10:09:53 +02:00
Torkel Ödegaard 89c3880a59 Merge branch 'master' of github.com:grafana/grafana 2016-07-06 08:26:24 +02:00
Torkel Ödegaard 7c7e26bc18 feat(templating): refactoring template variable handling for variables that change on time refresh, closes #5021 2016-07-06 08:25:46 +02:00
Torkel Ödegaard 069100099d Merge branch 'reflect_panel_repeat_when_time_range_changed' of https://github.com/mtanda/grafana 2016-07-06 07:40:51 +02:00
Adrián López 65aa6df45c Warn user if there are no mappings (#5246) 2016-07-06 07:31:42 +02:00
Torkel Ödegaard aad76d9220 Merge branch 'master' of github.com:grafana/grafana 2016-07-06 07:23:20 +02:00
Torkel Ödegaard 9088023116 fix(error handling): improved dashboard init error handling and notifications 2016-07-06 07:23:09 +02:00
Torkel Ödegaard ad1d7f0ffb Update package.json 2016-07-06 07:22:29 +02:00
Torkel Ödegaard 41bffd503d Update CHANGELOG.md 2016-07-06 07:22:03 +02:00
Torkel Ödegaard b4493155fc fix(error handling): improved dashboard init error handling and notifications 2016-07-06 07:18:58 +02:00
Torkel Ödegaard c1b7bd0f1b Merge branch 'notify_migration_error' of https://github.com/mtanda/grafana 2016-07-06 06:34:17 +02:00
Torkel Ödegaard 6a8c774dcc fix(graph): show graph panel render errors as panel errors, fixes #5414 2016-07-06 06:31:32 +02:00
Torkel Ödegaard 435aa88c05 Merge branch 'issue_5372' of https://github.com/kipe/grafana into kipe-issue_5372 2016-07-06 06:05:50 +02:00
Torkel Ödegaard 782427b5f2 Update latest.json 2016-07-06 05:28:49 +02:00
herver 9c73b2fa1c Support data units for both IEC (Binary) and Metric (Decimal) variants (#5473) 2016-07-06 05:27:35 +02:00
Torkel Ödegaard 53f110c942 Merge branch 'master' of github.com:grafana/grafana 2016-07-05 18:02:23 +02:00
Torkel Ödegaard fd5f7c2e34 fix(): updated changelog 2016-07-05 18:02:10 +02:00
Torkel Ödegaard 5595fc2683 refactor(): refactored date handling and locale handling in #5517 2016-07-05 17:59:43 +02:00
Torkel Ödegaard f31960d325 Update latest.json 2016-07-05 16:39:36 +02:00
Torkel Ödegaard c029e47a12 Merge branch 'moment-locale' of https://github.com/gofore/grafana into gofore-moment-locale 2016-07-05 16:22:33 +02:00
Joona Romppanen 438a73c58a Added moment.js locales. Set locale from window.navigator at app init(). Use firstDayOfWeek on time picker 2016-07-05 17:08:44 +03:00
Torkel Ödegaard 460820a117 conf(): updated sample config and root_url to better explain it 2016-07-05 14:10:23 +02:00
Carl Bergquist 9312a13e6e Merge pull request #5496 from joemiller/doc-update
grammar fix in docs
2016-07-03 09:44:00 -07:00
Torkel Ödegaard 8bd6b953b8 fix(elasticsearch): fix json escape logic when doing terms template value lookup, fixes #5485 2016-07-02 12:01:04 -04:00
joe miller a6554a85c0 grammar fix in docs 2016-07-02 08:27:31 -07:00
Carl Bergquist c047dacf18 Merge pull request #5442 from mtanda/snapshot_orig_url
(snapshot) save original url
2016-07-01 13:09:34 -07:00
Mitsuhiro Tanda 630d0d0793 (snapshot) add open original dashboard button 2016-07-02 02:26:27 +09:00
Kimmo Huoman 522a3408e9 Export CSV in the same format as presented in Table panel. Fixes issue #5372.
The data is exported in the same exact format as presented in the table panel.
This is achieved by using the same renderer as the UI uses.
2016-07-01 20:21:53 +03:00
Mitsuhiro Tanda cc519adcfc (snapshot) restrict saving original url for local snapshot 2016-07-02 02:16:23 +09:00
Mitsuhiro Tanda 7aaa15ad95 (snapshot) save original url 2016-07-02 02:16:23 +09:00
bergquist 07e522bb64 Merge branch 'influxdb_stop_hidden_queries' 2016-07-01 02:09:40 +02:00
bergquist 22ba51a631 Merge branch 'master' into influxdb_stop_hidden_queries 2016-07-01 02:09:10 +02:00
bergquist b47a307106 Merge branch 'master' into influxdb_stop_hidden_queries 2016-07-01 02:06:19 +02:00
Andris Raugulis 1c293781e3 Log to default log directory, only if custom configuration failed. (#5393) 2016-06-30 16:37:06 -07:00
Kevin Fitzpatrick f2baa5b210 Make Generic OAuth Configs ENV VARS-friendly
Use underscores instead of dashes.
2016-06-30 15:07:55 -07:00
Kevin Fitzpatrick b4646b6c3a Allow users to use a generic oauth that conforms to the github style.
Enables users to set their own link text.
2016-06-30 15:07:55 -07:00
Carl Bergquist 603e5fe0bf Merge pull request #5469 from stuartnelson3/create-unique-prometheus-req-id
[prometheus] Use `panelId` and `target.refId` for requestId
2016-06-30 13:13:01 -07:00
stuart nelson 0590c51524 [prometheus] Use panelId and target.refId for requestId
Using these two values ties requests to a
particular query position within a panel, ensuring
that requests are canceled if:

- Duplicate requests with the same query are sent
- Requests from the same query position (but a
different query) are sent

The last point is important as it identifies
queries by a physical location in the dashboard
instead of with the query expression.  If a
different query from the same position in a panel
is sent, the previous request should be canceled.
2016-06-30 11:29:02 +02:00
Torkel Ödegaard 5676a35d9a fix(css): added responsive media query for phones that fix header wrap 2016-06-29 14:35:58 -07:00
Torkel Ödegaard ae8fabdad3 fix(modal): fixed duplicate confirm modal issue 2016-06-29 14:26:21 -07:00
Carl Bergquist b289497db6 Merge pull request #5455 from rakotomandimby/patch-1
Update debian.md to Debian Jessie
2016-06-29 12:35:32 -07:00
Carl Bergquist fe7438c7ff Merge pull request #5461 from mtanda/pr_cloudwatch_add_metrics
(cloudwatch) add metrics
2016-06-29 12:08:44 -07:00
Carl Bergquist 7b84c4b4dc Merge pull request #5465 from tmc/patch-1
properly quote font-family on singlestat
2016-06-29 12:07:53 -07:00
Travis Cline bca6101609 properly quote font-family on singlestat 2016-06-29 11:03:07 -07:00
Soulou aa064b18e8 Test environment override for secret and url with credentials 2016-06-29 13:49:41 +02:00
Mitsuhiro Tanda 9ca5ba96be reorder metrics/dimensions 2016-06-29 14:11:01 +09:00
Mitsuhiro Tanda 511f8d3213 add cloudwatch metrics and dimensions 2016-06-29 13:55:16 +09:00
bergquist 4fc16c36ed feat(alerting): saves new state when alert updates 2016-06-29 00:05:48 +02:00
Torkel Ödegaard 5a65dc5d23 Merge branch 'alerting' of github.com:grafana/grafana into alerting 2016-06-28 14:04:38 -07:00
Torkel Ödegaard 9b4c0cca07 fix(flot): fixed flot issue introduced in alerting branch 2016-06-28 14:04:29 -07:00
Carl Bergquist 3460c12491 Merge pull request #5454 from Scalingo/node_version_package_json
Fix node version in package.json
2016-06-28 14:26:30 -04:00
Soulou e2c5fac9df Predefine url to let the environment variable overrider do its job 2016-06-28 17:45:55 +02:00
Soulou 03d0f11407 Accept URL parameter [database] config 2016-06-28 15:31:34 +02:00
Rakotomandimby Mihamina 16e2c660ac Update debian.md 2016-06-28 15:58:00 +03:00
Soulou 122b0d20a9 Fix node version in package.json
Value was incoherent since
https://github.com/grafana/grafana/commit/1900c81d9f9507ed4dbd18e95569480dfd0922f7
2016-06-28 14:36:15 +02:00
Othyus f3a6848710 feat(sidemenu): add style(margin and witdh) for the input and label filter 2016-06-28 08:30:36 +02:00
Othyus 31317abbeb feat(sidemenu): add limit for shown organizations 2016-06-28 08:11:37 +02:00
bergquist 6bf42dde18 tech(alerting): remove some logging 2016-06-27 01:27:30 +02:00
Mitsuhiro Tanda 8af3bb739c refactor 2016-06-26 22:39:34 +09:00
bergquist 4ed6b99d9a Merge branch 'alerting_notifications' into alerting 2016-06-26 04:05:56 +02:00
bergquist af216ecf83 tech(cli): remove loop and head straight for plugindir 2016-06-26 03:47:15 +02:00
bergquist 07be2c89a3 tech(cli): lets use the fact that we have a compiler 2016-06-26 03:47:15 +02:00
bergquist 88e208bddf feat(gf-form): add support for small input fields 2016-06-25 23:30:51 +02:00
Carl Bergquist 92835f0a04 Merge pull request #5434 from saboorian/master
Escape html chararcters in singlestat renderer
2016-06-25 20:49:16 +02:00
bergquist aecd487775 Merge branch 'f1yegor-master' 2016-06-25 20:42:38 +02:00
bergquist 241b9ee329 fix(kbn): add calculator for opn,rpm and wpm 2016-06-25 20:42:24 +02:00
bergquist 4cbde7e747 Merge branch 'master' of https://github.com/f1yegor/grafana into f1yegor-master 2016-06-25 20:38:43 +02:00
bergquist 12570bb959 feat(singlestat): add serie name as an value option
closes #4740
2016-06-25 20:17:23 +02:00
bergquist 8b8bfa8a17 fix(singlestat): rename seriename scoped var 2016-06-25 20:17:05 +02:00
Torkel Ödegaard b31fccb889 Merge branch 'master' of github.com:grafana/grafana 2016-06-25 17:53:42 +02:00
Carl Bergquist ab104bcfd7 Merge pull request #5401 from alexanderzobnin/issue-4740
Issue #4740 - able to use $SeriesName variable in prefix of postfix.
2016-06-25 17:49:44 +02:00
Torkel Ödegaard 35f135f6c2 Merge branch 'master' of github.com:grafana/grafana 2016-06-25 17:46:07 +02:00
Torkel Ödegaard 6dad6241ed docs(): updated changelog 2016-06-25 17:45:39 +02:00
Carl Bergquist 2d4cb50490 Merge pull request #5394 from hailthemelody/master
fix z-index order in Series Overrides
2016-06-25 17:43:47 +02:00
Torkel Ödegaard 0d6222c803 Merge branch 'master' of github.com:grafana/grafana 2016-06-25 17:43:22 +02:00
Torkel Ödegaard b275fa8109 fix(alerts): fixed login and other alert popups not showing, fixes #5435 2016-06-25 17:42:08 +02:00
Carl Bergquist c223994155 Merge pull request #5411 from mtanda/pr_dynamodb_add_metrics
add cloudwatch metrics
2016-06-25 17:36:50 +02:00
bergquist ff15a90e6d fix(login): fixes broken validation for login 2016-06-25 17:34:47 +02:00
bergquist 638a8a1528 docs(changelog): add note about closing #4674
closes #4674
2016-06-25 16:37:28 +02:00
bergquist 16fa631ea0 tech(tests): remove unused code that breaks gorename 2016-06-25 16:34:42 +02:00
bergquist c2689b0c2b Merge branch 'kfitzpatrick-recreate-4675' 2016-06-25 16:31:11 +02:00
bergquist 690a74c6b7 feat(login): invert naming for dissallow user pass login 2016-06-25 16:30:41 +02:00
Torkel Ödegaard 346ca3fc89 Merge branch 'master' into alerting 2016-06-25 09:56:57 -04:00
bergquist 092b6517dc Merge branch 'recreate-4675' of https://github.com/kfitzpatrick/grafana into kfitzpatrick-recreate-4675 2016-06-25 15:53:42 +02:00
Mohammad Mehdi Saboorian 1e486398cc Escape html chararcters in singlestat renderer 2016-06-25 13:43:58 +04:30
Torkel Ödegaard 23345c563c changed version in master to 3.2-pre 2016-06-24 16:51:55 +02:00
Torkel Ödegaard 60f45c965c Merge branch 'master' of github.com:grafana/grafana 2016-06-24 10:25:44 +02:00
Mitsuhiro Tanda 6ef27a87e4 fix catch clause 2016-06-24 13:44:10 +09:00
Kevin Fitzpatrick 040586604b Allow configuration to disable the username and password login interface.
Used for when admins only want users to login via OAuth.
2016-06-23 10:09:13 -07:00
Alexander Zobnin e593cc3e9f Issue #4740 - change variable $SeriesName to $seriesName. 2016-06-23 19:35:50 +03:00
Torkel Ödegaard efad4bcb56 docs(): updated changelog 2016-06-23 17:45:29 +02:00
Torkel Ödegaard 9435e70b37 docs(): spelling fix 2016-06-23 17:31:22 +02:00
bergquist 48e1a17ac2 feat(alerting): remove dummie values from email notifier 2016-06-23 16:30:12 +02:00
bergquist 6121d15ba7 feat(alerting): more aggressive requirements for parsing alertrules 2016-06-23 16:08:18 +02:00
bergquist 8b05af2f90 feat(alerting): add exeuction time to alertResult 2016-06-23 15:52:45 +02:00
bergquist 2063fee4fe docs(changelog): add note about cli fix #5410 2016-06-23 15:16:26 +02:00
Torkel Ödegaard c3e1955792 docs(): updated export docs 2016-06-23 13:21:30 +02:00
bergquist 6af2d99862 style(light-theme): make text-color-weak a little bit darker
otherwise its not possible to see which queries are disabled
in the query editor
2016-06-23 13:17:53 +02:00
Emmanuel Quentin 6487814007 Avoid to request influxdb when query is hidden 2016-06-23 13:11:16 +02:00
bergquist f95be63c43 feat(alerting): move response handling to seperate file 2016-06-23 12:57:10 +02:00
bergquist 67197d54f9 feat(alerting): add triggeredAlerts as json to alert_state 2016-06-23 11:14:40 +02:00
bergquist 488b42377b feat(alerting): update state if not been updated for 15min 2016-06-23 11:03:27 +02:00
Torkel Ödegaard 838284c09f docs(): updated changelog 2016-06-23 10:38:11 +02:00
Torkel Ödegaard 1d35b90484 docs(): updated download links 2016-06-23 10:35:47 +02:00
Mitsuhiro Tanda 44b2a292eb notify dashboard migration fail 2016-06-23 16:56:18 +09:00
Torkel Ödegaard f3c1a894de changed version to 3.1-beta1 2016-06-23 09:12:17 +02:00
bergquist eb54fbaef5 docs(changelog): add note about cli fix #5410 2016-06-23 08:41:25 +02:00
bergquist af1c8dc5d9 feat(cli): adds support for dist/plugin.json location for plugins
ref #5410
2016-06-23 08:35:40 +02:00
bergquist 2123fbdf9b feat(cli): make remove command an alias for uninstall 2016-06-23 08:21:55 +02:00
Mitsuhiro Tanda 16dc095329 (templating) support asc/desc sort 2016-06-23 11:26:41 +09:00
Mitsuhiro Tanda 8987cfe0a2 (templating) add sort order option 2016-06-23 11:26:41 +09:00
Mitsuhiro Tanda 09f7222e79 add cloudwatch metrics 2016-06-23 11:24:21 +09:00
bergquist 14169c5092 tech(docker): add memcached exporter target for prom 2016-06-22 17:36:22 +02:00
bergquist 925806df87 tech(alerting): add recovery logging 2016-06-22 13:43:11 +02:00
Othyus e204c308bf feat(sidemenu): filtering organizations by an input, issue #2609 2016-06-22 13:04:38 +02:00
Torkel Ödegaard 0555525f97 tech(): updated list of docker stuff 2016-06-22 11:01:11 +02:00
bergquist 7952723b71 feat(alerting): add warn/crit filter 2016-06-22 08:09:45 +02:00
bergquist b5a29b6246 test(alerting): add tests for when to send notifcations 2016-06-22 07:58:30 +02:00
bergquist 6edae37ac9 feat(alerting): rename state response method 2016-06-22 07:23:31 +02:00
Torkel Ödegaard 24a54cd95b feat(units): refactoring #5404 2016-06-21 21:08:07 +02:00
Torkel Ödegaard a7a5f36b49 Merge branch 'issue-2971' of https://github.com/alexanderzobnin/grafana into alexanderzobnin-issue-2971 2016-06-21 21:00:00 +02:00
Alexander Zobnin ab0155c861 Issue #2971 - add time units for use in singlestat panel. 2016-06-21 20:56:34 +03:00
Torkel Ödegaard 53c424caf8 docs(): title change 2016-06-21 18:25:24 +02:00
Torkel Ödegaard 23cfbac4ec feat(docs): updated import / export docs 2016-06-21 18:24:25 +02:00
Torkel Ödegaard f23d72001d fix(dashboard): fixed issue triggering refresh after leaving fullscreen/edit mode with time range change 2016-06-21 17:21:45 +02:00
Torkel Ödegaard 302ad5f1f9 Merge branch 'master' of github.com:grafana/grafana 2016-06-21 17:08:16 +02:00
Torkel Ödegaard 257e6c469e feat(collectd): updated collectd config 2016-06-21 17:07:01 +02:00
bergquist ef9766eb96 docs(3.1): initial post about whats new in 3.1 2016-06-21 16:29:17 +02:00
Alexander Zobnin cc433c1fbd Issue #4740 - able to use $SeriesName variable in prefix of postfix. 2016-06-21 15:48:18 +03:00
bergquist aa9e524e73 tech(docker): add node exporter to prometheus 2016-06-21 11:46:08 +02:00
Carl Bergquist 3b1ae3f7d2 Merge pull request #5396 from hailthemelody/fix_issue_template_typos
fix typos in GitHub Issue Template
2016-06-21 10:27:41 +02:00
hailthemelody cccfe47bf0 fix typos in GitHub Issue Template 2016-06-20 21:39:11 -04:00
hailthemelody 13d1fec2cb fix z-index order in Series Overrides 2016-06-20 20:54:01 -04:00
Carl Bergquist 87ab97b5ed Merge pull request #5391 from wkruse/prometheus-annotations-doc
Add Prometheus annotations doc
2016-06-20 18:49:00 +02:00
Wadim Kruse 3b47b1ecbd Add Prometheus annotations doc 2016-06-20 18:36:05 +02:00
bergquist 403fdebca3 docs(alerting): rewrite alert docs 2016-06-20 17:05:16 +02:00
bergquist 5d62c84a19 feat(alerting): adds default checkbox to ui 2016-06-20 16:19:15 +02:00
bergquist f5297db8f3 tech(alerting): remove console log that spams tests 2016-06-20 15:30:00 +02:00
bergquist fa309ec925 feat(alerting): add default notification group 2016-06-20 15:24:48 +02:00
bergquist 0a85efbf18 feat(alerting): add datasource type to settings 2016-06-20 11:44:06 +02:00
bergquist a18506e2e4 feat(alerting): changing notifications should require org admin 2016-06-20 11:32:55 +02:00
bergquist 0c5da9155f feat(alerting): only expose DTO info when requesting all notifications 2016-06-20 11:31:20 +02:00
bergquist 12706fd6db Revert "docs(changelog): add note about singlestat to datetime func"
This reverts commit 8efa94e42a.
2016-06-20 11:04:01 +02:00
Carl Bergquist d8be2f1ecc Merge pull request #5389 from grafana/revert-5383-issue-4747
Revert "issue #4747 - add date and time units to singlestat panel."
2016-06-20 11:02:43 +02:00
Carl Bergquist b6f9d9feb0 Revert "issue #4747 - add date and time units to singlestat panel." 2016-06-20 11:02:29 +02:00
bergquist 8efa94e42a docs(changelog): add note about singlestat to datetime func 2016-06-20 10:59:47 +02:00
Carl Bergquist b94527f661 Merge pull request #5383 from alexanderzobnin/issue-4747
issue #4747 - add date and time units to singlestat panel.
2016-06-20 10:57:08 +02:00
bergquist 96e5ad3f5c Merge branch 'alerting' into alerting_notifications 2016-06-20 10:45:05 +02:00
bergquist dd8c3d0355 Merge branch 'master' into alerting 2016-06-20 10:44:48 +02:00
bergquist 3adee1eda0 tech(sass): sasslint fixes for css3
Pseudo-elements must start with double colons pseudo-element
2016-06-20 10:37:47 +02:00
bergquist 7c09a140c7 test(alerting): fixes broken tests for alerting thresholds 2016-06-20 10:06:18 +02:00
bergquist 4c4164bb40 test(alerting): adds test email creater 2016-06-20 07:49:08 +02:00
Alexander Zobnin 398e9f5195 issue #4747 - add date and time units to singlestat panel. 2016-06-17 22:51:08 +03:00
bergquist adea539b8d feat(alerting): add link to panel png 2016-06-17 16:43:14 +02:00
bergquist ea4b14ac22 feat(alerting): rename critical -> crit 2016-06-17 16:40:48 +02:00
bergquist 212fd27252 feat(alerting): add support for email notifications 2016-06-17 15:30:17 +02:00
bergquist 774add94c1 feat(alerting): skip warn check if crit is triggered 2016-06-17 15:24:17 +02:00
Torkel Ödegaard 90c063060a fix(png): fixed phantomjs rendering issue with graph and y-axis label rotation, fixes #5220 2016-06-17 14:36:10 +02:00
Torkel Ödegaard 3bcda9268a feat(styleguide): removed unused/empty tabs 2016-06-17 14:18:24 +02:00
Torkel Ödegaard e2b398a6bf Merge branch 'master' of github.com:grafana/grafana 2016-06-17 14:16:25 +02:00
Torkel Ödegaard fa10fc994a fix(graph): remove panel width cache, causing issues, does not handle window resize and fullscreen to dashboard, #5297 2016-06-17 14:16:01 +02:00
Drew Farris cb2b8dea96 OpenTSDB: consistent options for http requests (#5233)
* OpenTSDB: consistent options for http requests

 . the get function wasn't using the same request options wrt to credentials/auth as
   the timeseries http request

* OpenTSDB: `_get` `_performTimeSeriesQuery` refactor copied code
2016-06-17 14:04:40 +02:00
Torkel Ödegaard 9bcd5de8ff fix(share): fixed PNG render link generated from share modal when opened from edit mode, fixes #5295 2016-06-17 14:03:59 +02:00
Torkel Ödegaard 9f9fca1e76 feat(datasource): added suggest urls for each data source, #4577 2016-06-17 13:35:29 +02:00
Alexander Zobnin fdf46c6a10 Issue 4577 (#5379)
* Add default-url property for datasource-http-settings directive.
This will allow to set default url for datasource.

* Fixed spelling.

* Use typeahead for url suggestion.
2016-06-17 13:18:00 +02:00
Torkel Ödegaard 305a6ae110 feat(dashboards): dashboard sharing fixes 2016-06-17 11:36:35 +02:00
Torkel Ödegaard 10daf1d63a Revert "Enable the "limit" param in /api/search"
This reverts commit 3d77685108.
2016-06-17 11:22:39 +02:00
bergquist 90e3d8afda Merge branch 'alerting' into alerting_notifications 2016-06-17 09:55:58 +02:00
bergquist c96108226c fix(alerting): use alert frequency 2016-06-17 09:55:42 +02:00
bergquist 764c58ba8d Merge branch 'alerting' into alerting_notifications 2016-06-17 09:54:38 +02:00
bergquist 9481fcb830 fix(alerting): use alert frequency 2016-06-17 09:54:11 +02:00
Torkel Ödegaard 23aa614baf feat(rendering): fixed issue with png rendering, recently introduced by profiler refactoring 2016-06-17 08:49:11 +02:00
bergquist ebada26b85 Merge branch 'alerting' into alerting_notifications 2016-06-17 08:27:58 +02:00
bergquist e8a324c7f5 feat(alerting): add frequency back to alert model 2016-06-17 08:27:38 +02:00
Torkel Ödegaard 5c35fac8fe fix(dataproxy): removed accidental debug code 2016-06-17 08:11:37 +02:00
bergquist 946dc0ecf3 Merge branch 'alerting' into alerting_notifications 2016-06-17 07:44:39 +02:00
bergquist 1771ab032e Merge branch 'master' into alerting 2016-06-17 07:44:21 +02:00
bergquist 8b2f6fffc9 test(dashboards): comment code in broken tests 2016-06-17 07:43:57 +02:00
Torkel Ödegaard 32479503bd fix(build): another windows build issue 2016-06-16 21:10:30 +02:00
Torkel Ödegaard b06ec734f1 fix(build): windows, another windows build fix, #5370 2016-06-16 18:21:12 +02:00
bergquist b035074613 tech(alerting): disable update state api 2016-06-16 17:02:45 +02:00
bergquist a0418da160 Merge branch 'alerting' into alerting_notifications 2016-06-16 16:49:16 +02:00
bergquist 8ec311ade4 Merge branch 'master' into alerting 2016-06-16 16:29:41 +02:00
bergquist 3c4d2b8ca1 feat(alerting): add basic body for webhooks 2016-06-16 16:25:23 +02:00
bergquist 6705efef6f feat(alerting): make some settings properties required 2016-06-16 16:18:40 +02:00
bergquist f3009dc23b fix(alerting): broken link 2016-06-16 16:06:40 +02:00
bergquist b907ce341c feat(alerting): enables deletes for alert notifications 2016-06-16 15:21:44 +02:00
bergquist 149c2ae913 feat(alerting): add submenu for alerting 2016-06-16 15:21:23 +02:00
Torkel Ödegaard b039a81375 feat(build): fixing windows build issue, #5370 2016-06-16 14:36:19 +02:00
bergquist 7f767224af feat(alerting): basic support for creating and updating notifications 2016-06-16 14:29:20 +02:00
Joel Smith 46fe9a167e Update file_export.ts (#5325)
Prepended first line to export file containing
`sep=;\n`
which I believe should be all that is required for Excel to interpret the CSV file as semicolon delimited.
2016-06-16 14:27:00 +02:00
Torkel Ödegaard 79eb971fad docs(): updated changelog 2016-06-16 10:49:40 +02:00
Torkel Ödegaard 81e9aa4de4 feat(datasource): cancel in flight data source requests, refeatoring #5321 2016-06-16 10:48:26 +02:00
bergquist c51facfaef style(alerting): move filter below HR 2016-06-16 09:23:53 +02:00
bergquist 00fc2e2593 test(alerting): fixes broken unittest 2016-06-16 09:09:09 +02:00
Torkel Ödegaard 6d3521c240 Merge branch 'cancel-in-flight-repeats' of https://github.com/stuartnelson3/grafana into stuartnelson3-cancel-in-flight-repeats 2016-06-16 08:57:31 +02:00
bergquist 72e23bca5f tech(alerting): improve/cleanup logging 2016-06-16 08:56:19 +02:00
Torkel Ödegaard 23e0240410 fix(build): removed logging call that caused wrong dependency to be used 2016-06-16 08:55:36 +02:00
bergquist 4d03e04172 feat(alerting): enable email notifiter 2016-06-16 08:29:49 +02:00
Torkel Ödegaard 1ae24b366f feat(profiler): fixed issues with frontend perf profiler 2016-06-16 08:28:50 +02:00
bergquist 2e809cae05 tech(alerting): enforce POST for webhooks 2016-06-16 08:16:16 +02:00
bergquist efea3bc9cb feat(alerting): skeleton commit for webhook 2016-06-16 08:16:16 +02:00
bergquist a3b7ea7704 feat(alerting): skeleton for alert notification configuration page 2016-06-16 08:16:16 +02:00
bergquist 4c5d2d6079 style(alerting): remove unused code 2016-06-16 08:16:16 +02:00
bergquist b9b65cf2d4 tech(alerting): add logging about failed notifications 2016-06-16 08:16:16 +02:00
bergquist 9a8416416d feat(alerting): converter for db model to notification 2016-06-16 08:16:16 +02:00
bergquist 6eca26e8ec style(alerting): improve formating 2016-06-16 08:16:16 +02:00
bergquist dbf3795aaf feat(alerting): add sql layer for alert notifications 2016-06-16 08:16:16 +02:00
bergquist 8b91e57ef6 feat(alerting): notification query 2016-06-16 08:16:16 +02:00
Torkel Ödegaard 2ceb58d0c4 feat(elasticsearch): removed dashboard import migration 2016-06-16 08:11:40 +02:00
Torkel Ödegaard e1f63a3346 docs(): updated changelog 2016-06-16 08:10:15 +02:00
Torkel Ödegaard ec0b09450c Merge branch 'export-dashboard'
Conflicts:
	conf/defaults.ini
	pkg/setting/setting.go
	public/app/core/components/grafana_app.ts
	public/app/core/core.ts
	public/app/features/dashboard/dashboardCtrl.js
2016-06-16 08:06:43 +02:00
Torkel Ödegaard 4b78ab5bcd feat(graph): graph tooltip sort order PR refactored/changed #4944, changed the layout graph display options, #4944 2016-06-15 17:20:55 +02:00
Torkel Ödegaard ae554a736b change(graphite): removed graphite png option in graph panel, closes #5367 2016-06-15 14:20:44 +02:00
bergquist 779ea55ee0 style(alerting): rename executor -> handler 2016-06-15 11:49:20 +02:00
bergquist 777ca4cd7d style(alerting): rename level.level to level.value 2016-06-15 11:39:25 +02:00
Torkel Ödegaard a893152141 feat(alerting): thesholds unification 2016-06-15 10:41:21 +02:00
Torkel Ödegaard f03e8292a2 feat(alerting): progress on threshold unification 2016-06-14 17:00:51 +02:00
Torkel Ödegaard ed7a539ddb feat(alerting): thresholds rethink 2016-06-14 16:45:51 +02:00
Carl Bergquist f842e28b85 Merge pull request #5343 from utkarshcmu/opentsdb-template
Implemented nested template variables functionality for Opentsdb
2016-06-14 07:43:41 +02:00
utkarshcmu 33aa3f0fc5 Made tag_values query more robust 2016-06-13 14:21:46 -07:00
Torkel Ödegaard dac8b35a1a feat(alerting): renamed scheduler to handler 2016-06-13 15:58:22 +02:00
bergquist 7f22b9eb6e tech(alerting): expression -> settings 2016-06-13 15:18:19 +02:00
bergquist bb6888885e fix(alerting): makes valid to save more explicit 2016-06-13 15:01:07 +02:00
bergquist 0d60b042c8 style(alerting): revemo commented code 2016-06-13 14:57:24 +02:00
bergquist ca33622698 style(alerting): rename max retries 2016-06-13 14:54:06 +02:00
bergquist 3ad90c389c style(alerting): improve naming 2016-06-13 14:01:57 +02:00
utkarshcmu e4e042e389 CHANGELOG entry 2016-06-13 04:53:21 -07:00
bergquist 04436c8a52 test(alerting): make sure the worst state is captured 2016-06-13 13:45:26 +02:00
utkarshcmu f3003a97ef Added required documentation 2016-06-13 04:34:23 -07:00
utkarshcmu 6550bc97ba Added unit tests 2016-06-13 04:24:27 -07:00
utkarshcmu 862de3a9dc Added templated dependency in Opentsdb 2016-06-13 03:59:12 -07:00
bergquist 6cb4bdd6cb feat(alerting): adds a result list to alertresult
Since one query can return multiple series we might be
interested in getting the result for each serie
2016-06-13 11:44:47 +02:00
bergquist a77824939f chore(alerting): remove alerting model.json 2016-06-13 11:10:28 +02:00
bergquist 1e41eb8c97 tech(alerting): remove frequency from alert model 2016-06-13 10:42:36 +02:00
bergquist 94f059838c feat(alerting): implemention duration parser 2016-06-13 10:40:46 +02:00
bergquist 2cf72715fb test(alerting): fixes broken unit tests 2016-06-13 09:33:14 +02:00
bergquist d52fc8d0ad Merge branch 'alert_ui_take2' into alerting 2016-06-13 09:20:00 +02:00
Torkel Ödegaard 9216492d55 Merge branch 'alert_handles' into alert_ui_take2
Conflicts:
	pkg/services/alerting/commands.go
2016-06-13 07:53:13 +02:00
bergquist 77746f277d chore(alerting): move transformers to seperate package 2016-06-13 07:46:54 +02:00
bergquist 22407fc897 fix(metrics): 64bit aligns standardcounter
Due to a bug in golang the 64bit variable i
need to come first to be 64bit aligned.
https://golang.org/pkg/sync/atomic/#pkg-note-BUG

closes #5341
2016-06-13 06:56:16 +02:00
Carl Bergquist dba6fe8af3 Merge pull request #5340 from hailthemelody/master
update pricing to include 1 million free API requests per month
2016-06-13 06:54:00 +02:00
hailthemelody ef9500a8f0 update pricing to include 1 million free API requests per month 2016-06-12 11:41:43 -04:00
Torkel Ödegaard e3b281dbac feat(alerting): more work on alerting thresholds 2016-06-12 11:43:18 +02:00
Torkel Ödegaard 5b6fb3b124 feat(alerting): level handle progress 2016-06-11 23:52:25 +02:00
Torkel Ödegaard ec640bd5da feat(alerting): more work on alerting ui 2016-06-11 23:31:49 +02:00
Torkel Ödegaard 1500c0e954 feat(alerting): alert threshold handles progress 2016-06-11 22:33:02 +02:00
Torkel Ödegaard f387e39b67 mend 2016-06-11 14:37:52 +02:00
Torkel Ödegaard 0b919c752b feat(alerting): poc of dragable alert handles 2016-06-11 14:37:33 +02:00
Torkel Ödegaard 66c2594262 feat(alerting): sql update fixes 2016-06-11 14:08:55 +02:00
Torkel Ödegaard 71c1c0ab65 feat(alerting): trying to get things to work with new model 2016-06-11 13:49:11 +02:00
Torkel Ödegaard 0ef6801117 Merge branch 'master' into alert_ui_take2 2016-06-11 12:17:14 +02:00
Torkel Ödegaard bf1ea560e9 feat(logging): error logging improvements 2016-06-11 12:16:33 +02:00
Torkel Ödegaard 77a5e3f14d feat(alerting): minor fixes 2016-06-11 11:54:46 +02:00
Torkel Ödegaard 086b59483e feat(loggin): disable logging by default so unit tests are not full of logging 2016-06-11 11:38:25 +02:00
Torkel Ödegaard 382f396247 feat(alerting): more model changes 2016-06-11 10:54:24 +02:00
Torkel Ödegaard a362984c57 feat(alerting): renamed AlertRuleModel to just Alert, think making a distinction between an Alert and an Alert Rule is just confusing and was a mistake on my part 2016-06-11 10:26:48 +02:00
Torkel Ödegaard 2b4a9954b1 feat(alerting): progress on alerting UI and model, refactoring of dashboard parser and tests into extractor component, moved tests from sqlstore to alerting package 2016-06-11 10:13:33 +02:00
bergquist 1fa9ae810b test(alerting): enable disabled tests 2016-06-10 15:49:23 +02:00
bergquist 83c422e6ef feat(alerting): implement transform objects 2016-06-10 15:31:17 +02:00
Torkel Ödegaard c18017381b Merge branch 'alert_ui_take2' of github.com:grafana/grafana into alert_ui_take2
Conflicts:
	public/app/plugins/panel/graph/alert_tab_ctrl.ts
2016-06-10 14:52:17 +02:00
Torkel Ödegaard 48cbeb96bf feat(alerting): updated rule model and UI 2016-06-10 14:49:54 +02:00
bergquist ea8fb66f73 test(alerting): fixes broken unittests 2016-06-10 13:47:54 +02:00
bergquist 3c0b5fe78e tech(alerting): add graphite dateformat replacer 2016-06-10 13:26:19 +02:00
bergquist 8cd1d17916 feat(alerting): new alerting model\ 2016-06-10 13:15:16 +02:00
bergquist 0c69c5afb1 test(alerting): fixes broken unittests 2016-06-10 11:37:03 +02:00
bergquist ef35184a80 feat(alerting): rename alertrule model to alertruleDAO 2016-06-10 10:00:00 +02:00
bergquist b17298c97c test(alerting): remove unused code to enable gorename 2016-06-10 07:11:14 +02:00
bergquist fdf051ad5a feat(alerting): begin alert rule storage refactoring 2016-06-09 22:21:28 +02:00
stuart nelson 048bcf19f6 Use panel+ref for unique id
Previously, if a user changed the query between
requests, the previous query would not be
canceled. This handles that edge-case.
2016-06-09 15:17:17 +02:00
stuart nelson 8797be9f89 Add existence check for canceler. 2016-06-09 15:16:53 +02:00
bergquist 3898f427f5 feat(alerting): update the ux model 2016-06-09 15:10:50 +02:00
bergquist 1e4761854e Merge branch 'alerting_definitions' into alert_ui_take2 2016-06-09 13:03:40 +02:00
stuart nelson cc64d65c2f Rename cacheKey to exprID/requestID
Depending on context in the code, rename cacheKey
to exprID when it identifies a unique expression,
and rename cacheKey to requestID when it is
identifying a request.
2016-06-09 12:57:55 +02:00
Torkel Ödegaard 55af988e02 feat(alerting): mocking with new alert rule model 2016-06-09 12:14:50 +02:00
stuart nelson efdb990e56 Return an error for a canceled request.
Allow the datasource to decide how to handle a
canceled request.
2016-06-09 12:13:17 +02:00
stuart nelson bc7c2cd3f5 Create cacheKey at top-level
Responsibility is now to pass the cacheKey through
to `datasourceRequest` in each datasources'
implementation of `query`.
2016-06-09 11:36:46 +02:00
bergquist 66d47a9303 tech(alerting): go vet fix 2016-06-09 10:49:25 +02:00
Torkel Ödegaard c85bb47675 Merge branch 'alerting_definitions' into alert_ui_take2 2016-06-09 10:46:03 +02:00
Torkel Ödegaard dee5f582d7 Merge branch 'master' into alerting_definitions 2016-06-09 10:45:16 +02:00
Torkel Ödegaard 1584dac00a Merge branch 'master' of github.com:grafana/grafana 2016-06-09 10:43:46 +02:00
Torkel Ödegaard 79986e5593 Merge branch 'query-part-refactor'
Conflicts:
	public/app/plugins/datasource/influxdb/query_part.ts
2016-06-09 10:43:07 +02:00
Torkel Ödegaard b8aa8b3079 feat(prometheus): restore old prometheus query editor, revert this commit in prometheus query editor v2 branch 2016-06-09 10:37:33 +02:00
bergquist 544073b7e1 feat(alerting): make sure saved alerts are valid 2016-06-09 10:27:23 +02:00
Torkel Ödegaard 071c16b73c feat(alerting): start on new ui 2016-06-09 10:13:34 +02:00
bergquist a1f97e0b77 feat(alerting): add heartbeat writer 2016-06-09 10:00:34 +02:00
Mark Baas ced3bafa99 returns correct index (#5275) 2016-06-09 08:13:31 +02:00
Mukesh 755ec552de Bugfix: org select btn was not working on profile (#5317) 2016-06-09 00:43:38 +02:00
stuart nelson 18f9f6c159 Add in-flight identifier for Prometheus requests
Repeat Prometheus requests with the same query
will cancel preceding requests.
2016-06-08 18:05:46 +02:00
stuart nelson 6da7ed9706 Add support for canceling in-flight requests
Repeat requests, if they already exist in the
in-flight request map, will cause the previous
request to cancel.

The implementation of the unique key is the
responsibility of individual datasources.
2016-06-08 18:04:31 +02:00
Torkel Ödegaard a66027830b Merge branch 'alerting_definitions' of github.com:grafana/grafana into alerting_definitions 2016-06-08 09:42:31 +02:00
Torkel Ödegaard 26d93d7130 Merge branch 'master' into alerting_definitions 2016-06-08 09:36:50 +02:00
bergquist ffac5c1299 docs(changelog): add note about changelog 2016-06-08 09:35:34 +02:00
Carl Bergquist fe5673134f Merge pull request #5292 from Thib17/master
Enable the "limit" param in /api/search
2016-06-08 09:19:58 +02:00
bergquist 366fb11416 style(alerting): add fmt fixes 2016-06-08 08:50:11 +02:00
Torkel Ödegaard 1d8fdc09e7 feat(logging): added log format option, #4590 2016-06-08 08:48:46 +02:00
Torkel Ödegaard 7d6cda4916 Merge branch 'master' of github.com:grafana/grafana 2016-06-08 08:10:22 +02:00
Torkel Ödegaard b25cb60259 Merge branch 'new-logger'
Conflicts:
	CHANGELOG.md
2016-06-08 08:09:59 +02:00
Torkel Ödegaard 87e98f01cd feat(logging): updated syslog writer to work with log15 log interface, closes #4590 2016-06-08 08:09:29 +02:00
Karl 22cda198ae Apply EscapeFilter to username to address grafana/grafana#5121 (#5279) 2016-06-08 07:28:16 +02:00
Tom Hukins d1c06a93df Fix a typo (#5306) 2016-06-08 07:27:52 +02:00
Torkel Ödegaard eed0d9c8d2 feat(graph performance): graph performance tweaks, refactoring #5297 2016-06-08 07:23:44 +02:00
Torkel Ödegaard bf82fdb678 Merge branch 'perf_graph_js' of https://github.com/mtanda/grafana into mtanda-perf_graph_js 2016-06-08 06:53:28 +02:00
Torkel Ödegaard e1e7fbf83d Merge branch 'master' of github.com:grafana/grafana 2016-06-08 06:51:43 +02:00
Torkel Ödegaard c739428c30 feat(profiling): refactorign profiling code, #5286 2016-06-08 06:51:10 +02:00
Torkel Ödegaard 2a7d2ffccb Merge branch 'profiling_in_dev' of https://github.com/mtanda/grafana into mtanda-profiling_in_dev 2016-06-08 05:47:30 +02:00
Zdenek Styblik 5eceabf810 fix(): Check Organization exists before User is added (#5302)
Commit adds a check whether Organization exists before User is added to
the organization.

Fixes #3151.
2016-06-08 05:46:21 +02:00
Torkel Ödegaard 67ad903556 feat(test metrics): fixed issue with built in Grafana test data source, fixes #5299 2016-06-08 05:45:13 +02:00
Torkel Ödegaard 36b0802789 fix(png): fixed issue with png rendering, fixes #5274 2016-06-08 05:29:38 +02:00
Torkel Ödegaard 93fdc18fd4 feat(logging): fixed dependencies 2016-06-07 15:59:50 +02:00
bergquist 8d4aa5d114 test(alerting): update dashboard json 2016-06-07 15:52:33 +02:00
Torkel Ödegaard e4ea24dfc4 Merge branch 'new-logger' into alerting_definitions
Conflicts:
	pkg/services/sqlstore/migrations/migrations_test.go
2016-06-07 15:51:22 +02:00
Torkel Ödegaard 73b0e6c37b feat(logging): disable migrator logging during test 2016-06-07 15:50:16 +02:00
Torkel Ödegaard d7c03359ea feat(alerting): fixed test issues 2016-06-07 14:54:30 +02:00
Torkel Ödegaard 3289225b77 feat(alerting): fixed test issues 2016-06-07 14:51:53 +02:00
Torkel Ödegaard 8105ec4660 feat(alerting): fixed test issues 2016-06-07 14:27:56 +02:00
Torkel Ödegaard 461e6ae4ac feat(alerting): added missing godep libs 2016-06-07 13:50:55 +02:00
Torkel Ödegaard 0d9c9526b9 feat(alerting): fixed graphite log issue 2016-06-07 13:47:22 +02:00
Torkel Ödegaard 0667d73660 Merge branch 'new-logger' into alerting_definitions
Conflicts:
	pkg/api/api.go
	pkg/setting/setting.go
2016-06-07 13:31:56 +02:00
Torkel Ödegaard 65aad44464 feat(logging): added uname to context logger 2016-06-07 12:20:46 +02:00
Torkel Ödegaard a02cf5beb7 feat(logging): added loging filters 2016-06-07 12:11:41 +02:00
bergquist b76b42f209 docs(changelog): add note about deb post install script 2016-06-07 12:09:56 +02:00
Carl Bergquist ee88b0dc35 Merge pull request #5282 from nazco/patch-1
restart grafana after upgrade
2016-06-07 12:03:42 +02:00
Torkel Ödegaard 3dc7706c45 feat(loggin): improved http request panic handling 2016-06-07 10:05:10 +02:00
Torkel Ödegaard 9741af2031 feat(logging): progress on new logging #4590 2016-06-07 09:29:47 +02:00
Mitsuhiro Tanda 487b2089a9 cache label width 2016-06-07 14:28:08 +09:00
Mitsuhiro Tanda b28368c859 cache panel width 2016-06-07 14:04:06 +09:00
Torkel Ödegaard 22778e6efd feat(logging): a lot of progress on moving to new logging lib, #4590 2016-06-06 23:06:44 +02:00
Thibault Chataigner 3d77685108 Enable the "limit" param in /api/search 2016-06-06 16:15:20 +00:00
Mitsuhiro Tanda 25899b72d2 use applyAsync for compile (#5287) 2016-06-06 17:18:18 +02:00
Mitsuhiro Tanda f877afb74d use async apply (#5258) 2016-06-06 17:18:10 +02:00
Torkel Ödegaard 34e17f7282 feat(alerting): requests looks to be working again 2016-06-06 17:11:46 +02:00
Torkel Ödegaard d1acfb4494 feat(alerting): minor progress 2016-06-06 14:24:14 +02:00
Torkel Ödegaard 7a34c129fe feat(alerting): things are compiling and tests pass 2016-06-06 13:50:47 +02:00
Torkel Ödegaard 0cbf4ae773 feat(alerting): began work on splitting scheduler into scheduler and engine 2016-06-06 11:56:58 +02:00
Mitsuhiro Tanda 83c76981b2 fix profiling code 2016-06-06 17:42:11 +09:00
Mitsuhiro Tanda 975b53b318 enable profiling in development mode 2016-06-06 17:42:11 +09:00
Torkel Ödegaard a191b9b1cf feat(alerting): moved alerting models back to alerting package, models is more for storage dtos 2016-06-06 10:31:21 +02:00
Torkel Ödegaard 70cb8400c3 feat(alerting): changed name of root Alerts nav item and page from Alerts to Alerting 2016-06-06 09:17:29 +02:00
Torkel Ödegaard f36a44c49a Merge branch 'master' into alerting_definitions
Conflicts:
	conf/defaults.ini
	pkg/api/dashboard.go
2016-06-06 08:43:01 +02:00
Karl 2f5ae85d33 Initial patch for grafana/grafana#4267 (#5280) 2016-06-06 07:15:37 +02:00
Ben Oswald 51878aeca8 change start to restart also for systemctl
I've forgotten to update the systemctl start to restart in my first commit
2016-06-05 16:27:57 +02:00
Ben Oswald 1d2eb0f903 restart grafana after upgrade
The current script only tries to start the already running grafana process after an upgrade. This leads to errors due to changed js and css hashes while grafana is delivering the old ones. To load the new sources we need to restart grafana after an upgrade.
2016-06-05 16:19:53 +02:00
f1 d002cab28f add reads/min and etc to unitFormats 2016-06-05 00:57:04 +02:00
Torkel Ödegaard 7cbaf06097 feat(instrumentation): check if enabled in http api metrics route 2016-06-03 21:22:34 +02:00
Torkel Ödegaard 1059a35bbc feat(instrumentation): documented instrumentation options, closes #4696 2016-06-03 18:38:19 +02:00
Torkel Ödegaard 064e474b0a Merge branch 'metrics_reporting' 2016-06-03 18:06:41 +02:00
Torkel Ödegaard aef2b6b45f feat(instrumentation): finial polish 2016-06-03 17:15:17 +02:00
Torkel Ödegaard 35a7a3a52b feat(instrumentation): added some more timers 2016-06-03 17:00:39 +02:00
Torkel Ödegaard e0c6048820 feat(instrumentation): added gauge and http endpoint 2016-06-03 16:15:36 +02:00
Torkel Ödegaard ffb12d122f Update ISSUE_TEMPLATE.md 2016-06-03 15:34:08 +02:00
bergquist 6a49d4ed6b feat(alerting): remove orgid from alertrule query 2016-06-03 15:24:53 +02:00
bergquist b08f8bab71 Merge branch 'dakerfp-patch-3' 2016-06-03 15:09:18 +02:00
Torkel Ödegaard 1a05ae2eaa feat(instrumentation): more work 2016-06-03 15:06:57 +02:00
bergquist 961c31a747 test(util): add unit test for string util 2016-06-03 15:06:54 +02:00
bergquist d1a345bb03 Merge branch 'patch-3' of https://github.com/dakerfp/grafana into dakerfp-patch-3 2016-06-03 15:02:46 +02:00
bergquist 2cf797b567 tech(alerting): minor refactoring and code style 2016-06-03 15:01:42 +02:00
Carl Bergquist 236aed112f Merge pull request #5255 from dakerfp/patch-1
Unify signal registration in a single syscall.
2016-06-03 14:59:42 +02:00
bergquist 65eb373808 Merge branch 'master' into alerting_definitions 2016-06-03 13:48:36 +02:00
bergquist 3d7facf6ee fix(cli): fixes broken import 2016-06-03 13:40:48 +02:00
Torkel Ödegaard eee49a4995 feat(instrumentation): added meter, histogram and new timer, timer now send p25, p75, p90, p99 percentiles in 1000 sample exp decaying sample 2016-06-03 12:50:51 +02:00
bergquist 6de1399cf0 fix(cli): fixes broken import 2016-06-03 12:35:17 +02:00
bergquist d0ac258474 Merge branch 'master' into alerting_definitions 2016-06-03 12:22:46 +02:00
bergquist 15aeb4aec2 tech(cli): rename log to logger to separate from server logger 2016-06-03 12:22:30 +02:00
bergquist 5bbfe39f84 tech(alerting): replace goreq with native http 2016-06-03 11:38:56 +02:00
bergquist 9c7e6a2133 feat(alerting): add basic auth support for graphite 2016-06-03 11:07:55 +02:00
Torkel Ödegaard 86f0007768 feat(instrumentation): added influxdb client 2016-06-03 09:18:21 +02:00
Torkel Ödegaard 3065d10931 feat(timing): timing is now working with graphite and influxdb 2016-06-03 09:17:36 +02:00
bergquist eab81a7781 style(alerting): go lint fixes 2016-06-03 09:11:20 +02:00
bergquist 50d98b161c feat(alerting): adds support for retries 2016-06-03 09:04:20 +02:00
bergquist 68f01d57d3 tech(alerting): use range in loops when possible 2016-06-03 08:44:22 +02:00
Torkel Ödegaard 4c4189d631 Update ISSUE_TEMPLATE.md 2016-06-03 08:38:48 +02:00
Torkel Ödegaard 015b409f2f Update ISSUE_TEMPLATE.md 2016-06-03 08:38:07 +02:00
bergquist cc65dd8bcf tech(alerting): use pointers for updating alertjobs 2016-06-03 08:33:53 +02:00
bergquist 910253bc42 tech(alerting): remove datasource ref from alertjob 2016-06-03 07:40:47 +02:00
Torkel Ödegaard e2c794ff31 feat(instrumentation): lots of refactoring to support tag based backend, #4696 2016-06-02 21:06:49 +02:00
Torkel Ödegaard 2a9b51d836 feat(instrumentation): influxdb is working, now need to find a way to better support tags, #4696 2016-06-02 16:56:07 +02:00
bergquist 0bea0cc5b9 feat(alerting): add interface for alert backend 2016-06-02 16:34:25 +02:00
bergquist 510360a509 docs(elastic): updates readme 2016-06-02 14:56:31 +02:00
Torkel Ödegaard 6b2a4fe8e8 feat(instrumentation): work on settings model for internal metrics publishing, #4696 2016-06-02 14:32:17 +02:00
Torkel Ödegaard 49fe90874a Merge branch 'v3.0.x' 2016-06-02 12:09:10 +02:00
Torkel Ödegaard acbaef1907 fix(influxdb): fixed issue with backslash escaping in tag filter, fixes #5249 2016-06-02 12:08:13 +02:00
Torkel Ödegaard 74101eaf7c feat(instrumentation): changed name to senders 2016-06-02 12:04:50 +02:00
Torkel Ödegaard 8ab324988c Merge branch 'v3.0.x' 2016-06-02 09:57:20 +02:00
Torkel Ödegaard 1283461b89 fix(gzip): add plugin proxy to gzip exclusion, fixes #5237 2016-06-02 09:56:53 +02:00
Torkel Ödegaard 38790e2c4b fix(elasticsearch): fixed templating lucene / json escaping issue, fixes #5228, fixes #5227 2016-06-02 09:54:28 +02:00
Carl Bergquist aa718b4dce Merge pull request #5253 from minkikim89/fix_seperate_typo
fixed separate typo
2016-06-02 07:42:04 +02:00
Daker Fernandes Pinheiro 2d09dfd34f Using variadic argument to StringFallback implementation 2016-06-02 01:46:18 -03:00
Daker Fernandes Pinheiro 48e4de823a Unify signal registration in a single syscall. 2016-06-02 01:34:37 -03:00
bergquist 65d8403a04 fix(metrics_reporting): adds missing formating varialbe 2016-06-01 15:16:17 +02:00
bergquist a8ac37f517 feat(usage_metrics): add timer metrics 2016-06-01 15:04:58 +02:00
bergquist b2c0679a7f feat(metrics): initial graphite metrics writer for internal stats 2016-06-01 13:31:11 +02:00
bergquist 69229211b2 fix(alerting): move backend to seperate file 2016-06-01 11:25:29 +02:00
bergquist 4e1f801f6c feat(alerting): add serie name to failed alert description 2016-05-31 21:02:26 +02:00
bergquist 76758d270f feat(alerting): set basic description text of status ok 2016-05-31 20:03:15 +02:00
Carl Bergquist 8db00073b4 Merge pull request #5232 from peggyl/peggyl/fix-tags-popover-text
Fix wording of the dashboard tags popover text
2016-05-31 19:47:24 +02:00
Peggy Li d36c1769e0 Fix wording of the dashboard tags popover text 2016-05-31 17:29:31 +00:00
bergquist 68f148880d feat(alerting): add alert info at log page 2016-05-31 16:26:06 +02:00
bergquist 7c3dbe2a38 chore(alerting): move aggregations into alerting package 2016-05-31 15:29:56 +02:00
bergquist 7224ea5229 chore(alerting): convert alert levels to float 2016-05-31 14:18:12 +02:00
bergquist 338fdcb576 feat(alerting): add copy of AlertRule to AlertResult 2016-05-31 13:27:12 +02:00
bergquist 1ded0b30c2 fix(alerting): fix broken model bind in alerting tab 2016-05-31 13:12:05 +02:00
Carl Bergquist 53ecb4c1ae Merge pull request #5222 from akiomik/patch-1
Fixed assets urls in 500.html
2016-05-31 07:59:24 +02:00
Akiomi KAMAKURA 616dd5c4a5 Fixed assets urls in 500.html 2016-05-31 14:26:13 +09:00
bergquist d1daa2c817 style(alerting): give better info about actual value 2016-05-30 19:21:28 +02:00
bergquist b75631e021 chore(alerting): move alert result to models 2016-05-30 19:08:04 +02:00
bergquist 1498db11a9 feat(alerting): extracts alert rule reading 2016-05-30 18:52:38 +02:00
bergquist c5c261e955 feat(alerting): improve spacing in alerting tab 2016-05-30 17:50:35 +02:00
bergquist 3d5c27df91 test(alerting): add tests for multi serie checks 2016-05-30 14:58:32 +02:00
bergquist 411568351d feat(alerting): revert operand positions 2016-05-30 14:47:59 +02:00
bergquist 2edb0ad94d feat(influxdb): adds spread functionallity
closes #5211
2016-05-30 14:23:24 +02:00
bergquist 077be210da tech(alerting): change interval -> frequency 2016-05-30 09:31:05 +02:00
bergquist 16a9e56eca tech(alerting): change queryrange to int from str 2016-05-30 09:18:22 +02:00
bergquist 51511dd654 feat(alerting): save alert state 2016-05-30 09:03:14 +02:00
bergquist 1686d86c3b Merge branch 'master' into alerting_definitions 2016-05-30 08:26:08 +02:00
Carl Bergquist f8a535c6e8 Merge pull request #5195 from matschaffer/cloudwatch_metric_update_elasticbeanstalk
Add metrics for AWS/ElasticBeanstalk
2016-05-30 08:05:09 +02:00
Carl Bergquist f1bd614770 Merge pull request #5183 from nfnty/master
package.json: Upgrade grunt-contrib-compress, Fixes #5071
2016-05-30 08:02:00 +02:00
Torkel Ödegaard c8965d0f9a feat(export): export will add templatize constant variables 2016-05-28 20:27:44 +02:00
Torkel Ödegaard 53bb264375 Merge branch 'master' into export-dashboard 2016-05-28 17:17:51 +02:00
Torkel Ödegaard 1ea54049d0 feat(templating): added new template variable type constant 2016-05-28 16:59:29 +02:00
Torkel Ödegaard ca8543348b docker(): added collectd system metrics collector that writes to graphite, just for testing 2016-05-28 10:13:51 +02:00
hc4 cf87e8ecf5 Fix parsing of intervals. defined in ms (#5151)
* Fix parsing of intervals. defined in ms

Fix parsing of intervals. defined in ms.
Increase accuracy for sub-second inrevals.
Closes #5008

* Tests for sub-ms intervals

Unit test for https://github.com/grafana/grafana/commit/2034d4b9710b0cb9fd0cdf14aa9981cd0417eda4
2016-05-27 17:26:20 +02:00
Carl Bergquist a6afd85526 Merge pull request #5197 from minkikim89/fixtypo
Fixed type
2016-05-27 16:57:07 +02:00
Torkel Ödegaard 0d4c76a029 feat(import): save gnetId for dashbards imported from grafana.net 2016-05-27 16:42:32 +02:00
Torkel Ödegaard c3708b3096 feat(import): import directly from grafana.net id/url now works 2016-05-27 16:11:05 +02:00
bergquist e80000ce94 tech(alerting): skip if operator does not exist 2016-05-27 15:53:18 +02:00
bergquist 1f990da5c3 tech(alerting): use the timeseries ctor function 2016-05-27 15:51:34 +02:00
bergquist 5f2447976c style(alerting): add note about making timeseries model safer 2016-05-27 15:28:47 +02:00
bergquist 22d8723c1d feat(alerting): generelize aggregator functions 2016-05-27 15:17:48 +02:00
bergquist abc1ae3956 feat(alerting): add timeserie aggregation functions 2016-05-27 14:59:13 +02:00
Torkel Ödegaard 22a7eaf2e7 Merge branch 'master' into export-dashboard 2016-05-27 13:52:53 +02:00
Torkel Ödegaard 540def2c39 feat(import): working on unit tests for import ctrl 2016-05-27 13:52:19 +02:00
bergquist 205afd7212 style(alerting): remove some logging 2016-05-27 12:13:09 +02:00
bergquist 422234d03a feat(alerting): abstract graphite from executor 2016-05-27 12:06:41 +02:00
bergquist 3d66ec816d chore(alerting): minor refactoring 2016-05-27 10:34:44 +02:00
Torkel Ödegaard bf90fbc678 fix(templating): fixed failing templating unit test 2016-05-27 09:23:08 +02:00
Tim Bielawa 2b9d260686 docs(rebuild): Include new http api preferences docs in menus (#5194)
This updates the mkdocs.yml source file such that the HTTP Preferences
API is included in the website navigation bar and in the HTTP API
overview page.

This commit also refreshes the docs/README.md file with more verbose
instructions for building and viewing the documentation locally.

* Original issue: #5069 Document org & user preferences HTTP docs
* Original PR: #5087

Closes #5193
2016-05-27 08:58:42 +02:00
Torkel Ödegaard f6633c8189 feat(export): minor dupe fix 2016-05-27 08:34:12 +02:00
Mat Schaffer 18f704533f Add enhanced elasticbeanstalk metrics 2016-05-27 11:47:53 +09:00
Mat Schaffer aedba5411c Add basic metrics for AWS/ElasticBeanstalk 2016-05-27 11:30:16 +09:00
Torkel Ödegaard e83d13848e Merge branch 'master' into export-dashboard
Conflicts:
	public/app/features/dashboard/submenu/submenu.ts
2016-05-26 14:22:22 +02:00
Torkel Ödegaard 696fad702f Merge branch 'v3.0.x'
Conflicts:
	public/app/features/templating/templateValuesSrv.js
2016-05-26 14:21:17 +02:00
Torkel Ödegaard 724a511995 fix(templating): fixed issue with value being shown instead of it's text representation, fixes #5172 2016-05-26 13:18:02 +02:00
Torkel Ödegaard 90c9c70416 fix(): another fix for panel image rendering 2016-05-26 08:49:55 +02:00
Torkel Ödegaard f8a4661d05 Merge branch 'master' of github.com:grafana/grafana 2016-05-26 08:37:19 +02:00
Torkel Ödegaard dd494e648a fix(rendering): fixed issue with phantomjs panel rendering 2016-05-26 07:45:53 +02:00
bergquist 8ac635b631 style(alerting): change const names 2016-05-26 07:41:23 +02:00
Jared Wiltshire c9d6321f38 Allow for proxying Authorization header and automatically convert (#4832)
Authorization header to X-DS-Authorization in backend_srv.js
2016-05-26 07:13:29 +02:00
Mukesh 4038b4d17e Set active org through admin api (#5179) 2016-05-26 06:51:23 +02:00
nfnty 46551e9d65 package.json: Upgrade grunt-contrib-compress, Fixes #5071 2016-05-26 01:03:22 +02:00
bergquist 957cb407c5 feat(alerting): naiv graphite executor 2016-05-25 17:21:20 +02:00
Torkel Ödegaard 1060eeb197 feat(dashboard): include org id query parameter in dashboard url, #1613 2016-05-25 17:06:41 +02:00
Torkel Ödegaard 201d30a944 fix(export): style fixes and markup fixes for share modal 2016-05-25 13:01:40 +02:00
bergquist b2a4d8083e feat(alerting): add datasource ref to alert rule 2016-05-25 12:57:49 +02:00
Torkel Ödegaard fc2a069180 feat(export): fixed refactoring issue with dynamic dashbord srv 2016-05-25 12:45:52 +02:00
Torkel Ödegaard 392407136d Merge branch 'export-dashboard' of github.com:grafana/grafana into export-dashboard 2016-05-25 12:33:30 +02:00
Torkel Ödegaard ba6573af61 Merge branch 'master' into export-dashboard
Conflicts:
	public/app/features/dashboard/submenu/submenu.ts
2016-05-25 12:32:56 +02:00
Matt Toback 8d988f9582 Export dashboard bulletfactory (#5160)
* create descriptions and styles for share dropdown

* Updating actual modal layout for Sharing

* Updated the modals to follow the new styles, fixed the wrapping issue on the main menu. Standardized buttons.
2016-05-25 12:30:27 +02:00
Torkel Ödegaard f923edc424 Merge branch 'v3.0.x' 2016-05-25 12:29:35 +02:00
Torkel Ödegaard 2712d9ae8b Update latest.json 2016-05-25 12:23:32 +02:00
Torkel Ödegaard 3312a042dd docs(): updated download links 2016-05-25 11:50:00 +02:00
Torkel Ödegaard 5040570ea9 docs(): updated changelog 2016-05-25 11:07:29 +02:00
Torkel Ödegaard f5c5d1b1da Merge branch 'master' of github.com:grafana/grafana 2016-05-25 11:04:27 +02:00
Torkel Ödegaard 2cd6c2e7e0 Merge branch 'v3.0.x' 2016-05-25 11:04:12 +02:00
Torkel Ödegaard 0daadc954c fix(templating): fixed issue with detecting data source variable in other template variable definition, fixes #5165 2016-05-25 10:46:55 +02:00
bergquist ec98b7d672 docs(changelog): add note about fix for 5167 2016-05-25 10:01:49 +02:00
bergquist 8c2b6b532d fix(preferences): fixes broken default home dashboard
closes #5167
2016-05-25 09:56:45 +02:00
Torkel Ödegaard 71d62012e1 fix(panel): fixed issue with fullscreen panel view and switching to another dashboard, fixes #5163 2016-05-25 09:46:15 +02:00
Torkel Ödegaard 41deea90ee feat(dashboard): template variable changes updates url, closes #5002 2016-05-24 16:34:17 +02:00
Torkel Ödegaard a81806d3d0 feat(dashboard): sync time range with url, closes #458 2016-05-24 16:32:28 +02:00
bergquist 0f58f8a679 feat(alerting): add timeout handler for check execution 2016-05-24 10:30:39 +02:00
Torkel Ödegaard 5607a114f9 updated changelog 2016-05-24 09:53:28 +02:00
Torkel Ödegaard e81614b9e9 Merge branch 'v3.0.x' 2016-05-24 09:50:41 +02:00
Torkel Ödegaard 6f094ef215 fix(templating): fixed issue with nested template variables and multi select, the child variable selection state is now updated like single select variables, so if none matches the first option is selected, fixes #4861 2016-05-24 09:50:23 +02:00
Torkel Ödegaard 366baea099 docs(): updated changelog 2016-05-24 08:14:40 +02:00
Torkel Ödegaard dc9dcd045d Merge branch 'master' of github.com:grafana/grafana 2016-05-24 08:11:52 +02:00
Torkel Ödegaard 10c47ee27c feat(footer): some minor changes to footer to make it look good in light theme, closes #4889 2016-05-24 08:11:28 +02:00
Torkel Ödegaard 8f0240a295 Merge branch 'footer' 2016-05-24 07:53:13 +02:00
Torkel Ödegaard fd08c821f9 Merge branch 'v3.0.x'
Conflicts:
	package.json
2016-05-24 07:52:27 +02:00
Torkel Ödegaard c41c771e9a fix(home dashboard): fixed handling error when default dashboard is not found, fixes #5141 2016-05-24 07:39:58 +02:00
bergquist 448ee5812c feat(alerting): make sure the map contains the responding alert 2016-05-24 07:24:45 +02:00
Zdenek Styblik fff5aa3020 Add missing option Read-Only Editor to auto_assign_org_role description (#5139)
Commit adds missing option `Read-Only Editor` to `auto_assign_org_role` description.
2016-05-23 21:24:23 +02:00
Torkel Ödegaard f1ec270e3e bumped version to 3.0.4 2016-05-23 21:24:02 +02:00
Torkel Ödegaard a3f2f574c6 fix(singlestat): fixed Gauge positioning issue, fixes #5143 2016-05-23 21:23:31 +02:00
Utkarsh Bhatnagar ec19a97156 [Bug Fix] #5136 (#5142) 2016-05-23 21:00:06 +02:00
Torkel Ödegaard 9a7817a271 Merge branch 'master' into footer
Conflicts:
	pkg/api/frontendsettings.go
2016-05-23 20:59:23 +02:00
Utkarsh Bhatnagar 8a0d5aa38d [Bug Fix] #5136 (#5142) 2016-05-23 20:58:21 +02:00
Trent White a52869507e hide footer on non-dashboard pages 2016-05-23 12:46:13 -04:00
Torkel Ödegaard c77d72b29f feat(prometheus): progress on new prometheus query editor, #5117 2016-05-23 18:03:17 +02:00
Trent White 76d18e7156 remove height: 100% on .main-view 2016-05-23 11:45:54 -04:00
bergquist 7229fb7a76 tech(alerting): change from array to map 2016-05-23 17:04:57 +02:00
bergquist 77ec575b46 tech(alerting): fixes broken unit-tests 2016-05-23 14:51:41 +02:00
bergquist 9d500df2bb chore(alerting): remove redundant code 2016-05-23 14:36:24 +02:00
bergquist 9f8c67e352 feat(alerting): only start unfinnished jobs 2016-05-23 14:14:02 +02:00
Torkel Ödegaard 9e6056551d docs(): updated download links 2016-05-23 14:13:30 +02:00
Torkel Ödegaard bbea698af3 Update latest.json 2016-05-23 12:30:46 +02:00
bergquist cb21bf41b0 tech(alerting): split code into different files 2016-05-23 12:15:36 +02:00
bergquist b496b6a252 test(alerting): add test for alertjob selection 2016-05-23 12:04:34 +02:00
Torkel Ödegaard 9eec68985d docs(): updated download links 2016-05-23 11:49:07 +02:00
bergquist 4fce82344e feat(alerting): async exeuction on a shoestring 2016-05-23 11:47:41 +02:00
bergquist f95fa51322 feat(alerting): make rule execution async 2016-05-23 11:17:07 +02:00
Torkel Ödegaard cd82f579bd docs(): updated changelog 2016-05-23 11:08:08 +02:00
Torkel Ödegaard 93665f49b1 Merge branch 'v3.0.x' 2016-05-23 11:06:53 +02:00
bergquist a7fcb3a2cc feat(alerting): add dummie executor 2016-05-23 10:59:28 +02:00
Torkel Ödegaard dc77d555f9 fix(elasticsearch): fixed templating issue with elasticsearch, fixes #5135 2016-05-23 10:58:31 +02:00
Torkel Ödegaard dfe3806d01 fix(elasticsearch): fixed query editor issue with elasticsearch 2016-05-23 10:14:40 +02:00
bergquist f05cae23d2 feat(alerting): alert rule selector 2016-05-23 10:07:04 +02:00
Torkel Ödegaard cfc7710205 docs(): changelog updated 2016-05-23 09:31:52 +02:00
Torkel Ödegaard c60d737928 Merge branch 'v3.0.x'
Conflicts:
	package.json
2016-05-23 09:29:14 +02:00
Torkel Ödegaard 1da149d9e1 feat(annotations): annotations can now use a template variable as data source, closes #5054 2016-05-23 09:28:14 +02:00
bergquist 411178d384 tech(alerting): disable feature toggle
this feature toggle caused migration tests to fail
2016-05-23 08:24:10 +02:00
bergquist 45b2b4bc52 feat(alerting): add feature toggles for alerting functions 2016-05-23 08:00:42 +02:00
Torkel Ödegaard 43ba563a1c fix(logging): change log level to trace for plugin proxy logging call, fixes #5126 2016-05-23 07:55:55 +02:00
minki 05cb6048ae fixed separate typo 2016-05-23 09:32:18 +09:00
minki 70d6b32e14 Fixed type 2016-05-22 05:38:57 +09:00
Trent White 75940c1f5d turn watch all back on 2016-05-21 13:21:31 -04:00
Mitsuhiro Tanda 1d27a7f93d (cloudwatch) fix wrong cache key of credentials (#5124) 2016-05-21 09:02:04 +02:00
Trent White cffcc4c7a5 make footer unordered list. add new icons. 2016-05-20 16:44:19 -04:00
Trent White c727c3c441 resize and color of links 2016-05-20 15:58:14 -04:00
Torkel Ödegaard fb4dc77f36 docs(): updated changelog with 3.0.3 fixes 2016-05-20 15:26:19 +02:00
Torkel Ödegaard 9eb7b192b8 Merge branch 'master' of github.com:grafana/grafana 2016-05-20 15:16:05 +02:00
Torkel Ödegaard 06d63dda6e Merge branch 'v3.0.x' 2016-05-20 15:15:30 +02:00
Torkel Ödegaard e6f251011f fix(panel span): fixed issue setting panel span while in fullscren and also an issue when changing repeat variable while in fullscreen view, fixes #4957 2016-05-20 15:15:02 +02:00
Torkel Ödegaard 6a813aa33d fix(export): better error handling 2016-05-20 14:45:22 +02:00
bergquist 9d016a2756 feat(alerting): add migration for create and update 2016-05-20 14:23:24 +02:00
David J. Felix 441682b598 Fix linking for /dashboard-solo/ proxy prefix (#5116)
Fixes #5109
2016-05-20 14:01:12 +02:00
Mitsuhiro Tanda 9c672f6ec1 (prometheus) support new legend format (with backward compatibility) (#5096)
* (prometheus) support new legend format (with backward compatibility)

* (prometheus) use regex replace for legend format

* (prometheus) allow white space
2016-05-20 12:29:10 +02:00
Torkel Ödegaard 35c05463e7 Merge branch 'v3.0.x' 2016-05-20 12:23:50 +02:00
Torkel Ödegaard f00cbc0aeb fix(panel height): fixed issue with singlestat height, fixes #4679, fixes #4894, fixes #5113 2016-05-20 12:23:26 +02:00
Torkel Ödegaard ee86d24797 fix(elasticsearch): minor editor layout fix 2016-05-20 10:31:22 +02:00
Torkel Ödegaard 58a9324db0 Merge branch 'v3.0.x' 2016-05-20 10:24:54 +02:00
Torkel Ödegaard e0e8fd6637 fix(templating): fixed handling of numeric values in tempalting query results, fixes #5097 2016-05-20 10:24:24 +02:00
Torkel Ödegaard 2416ee04c8 fix(templating): fixed detection of nested template variables, fixes #5103 2016-05-20 09:58:07 +02:00
Torkel Ödegaard 91c6ebb06c Merge branch 'v3.0.x' 2016-05-20 09:06:39 +02:00
Torkel Ödegaard df0ddc0b50 fix(prometheus): fixed bug in prometheus query editor, fixes #5107 2016-05-20 09:03:52 +02:00
Torkel Ödegaard 2e02abffc0 fix(render): fixed issue with image renderer caused by disabling angular debug info 2016-05-20 08:34:35 +02:00
Torkel Ödegaard e47957ce6d Merge branch 'master' of github.com:grafana/grafana 2016-05-20 08:32:40 +02:00
Torkel Ödegaard c54e688272 Merge branch 'v3.0.x' 2016-05-20 08:31:51 +02:00
Torkel Ödegaard 37821e6d63 fix(share modal): fixed link in share modal when sub app url is /dashboard/, fixes #5109 2016-05-20 08:31:27 +02:00
Torkel Ödegaard a3ee388b66 Merge branch 'master' into query-part-refactor 2016-05-19 14:52:18 +02:00
Torkel Ödegaard 855e913bbd feat(dashboards): began work on dashboard list 2016-05-19 11:03:10 +02:00
Richard Hartmann 78360ece8a ISSUE_TEMPLATE.md: Improve wording and fix typos (#5101) 2016-05-19 10:59:38 +02:00
Richard Hartmann 7c46423727 ISSUE_TEMPLATE.md: Fix typo (#5099) 2016-05-19 10:34:12 +02:00
Torkel Ödegaard fb74d10573 feat(export): added grafana version to requires array, #5084 2016-05-19 10:21:16 +02:00
Torkel Ödegaard 430bcf192f feat(export): templetize annotations and template vars, #5084 2016-05-19 10:01:31 +02:00
Torkel Ödegaard cac723dab3 Merge branch 'master' into export-dashboard 2016-05-19 08:48:24 +02:00
bergquist 402499c071 Merge branch 'master' into alerting_definitions 2016-05-19 08:47:34 +02:00
bergquist 617d18e587 feat(panel): active tab is now placed in querystring aswell 2016-05-19 08:42:21 +02:00
bergquist a379b0057a feat(alerting): link to dashboard goes directly to alerting tab 2016-05-19 08:13:20 +02:00
bergquist ef4f5147be Merge branch 'master' into alerting_definitions 2016-05-19 08:05:35 +02:00
bergquist 2b06ceda71 feat(panels): adds queryparameter for choose active tab in edit mode 2016-05-19 08:00:48 +02:00
Torkel Ödegaard 1bb4ca22e7 fix(test): fixed failing unsaved changes test 2016-05-19 07:58:44 +02:00
Tim Bielawa 24a410ae8f docs(preferences): Document user and org preferences (#5087)
closes #5069
2016-05-18 18:31:59 +02:00
Torkel Ödegaard 673984a7db feat(export): more export stuff 2016-05-18 15:53:13 +02:00
Torkel Ödegaard 10339090b8 fix(annotations): fixed annotation error handling, fixes #5077 2016-05-18 15:22:40 +02:00
Torkel Ödegaard b6dcf6bd02 Merge branch 'v3.0.x' 2016-05-18 14:23:59 +02:00
Torkel Ödegaard 280e7bb04d Merge branch 'master' of github.com:grafana/grafana 2016-05-18 14:23:41 +02:00
Torkel Ödegaard 03551a5961 Merge remote-tracking branch 'origin/development' 2016-05-18 14:23:21 +02:00
Torkel Ödegaard d474eba53a fix(logging): fixed reading config level from config file, fixes #5079 2016-05-18 14:18:08 +02:00
Mitsuhiro Tanda 392cb2a714 (cloudwatch) update changelog (#5080)
* update cloudwatch.md

* update changelog
2016-05-18 13:27:19 +02:00
bergquist 92ac370415 tech(docker): rename fake data writers 2016-05-18 12:29:37 +02:00
Torkel Ödegaard c41e3dcb91 updated changelog 2016-05-18 12:04:37 +02:00
Torkel Ödegaard 602d1a5fbc Merge branch 'v3.0.x' 2016-05-18 12:02:53 +02:00
Torkel Ödegaard cd80884b76 fix(dashboard timepicker): fixed issue with time picker and UTC when reading time from url, fixes #5078 2016-05-18 12:01:11 +02:00
Torkel Ödegaard bfadc932d7 Merge branch 'master' of github.com:grafana/grafana 2016-05-18 11:50:56 +02:00
Torkel Ödegaard 0cd2e150d5 feat(snapshots): performance improvements to deep clone, makes snapshot's a lot quicker for big dashboards with a lot of panels and data 2016-05-18 11:50:40 +02:00
Carl Bergquist 5aaaeb05a0 Merge pull request #5075 from mtanda/prometheus_templating_fix
(prometheus) fix metric find query
2016-05-18 11:40:33 +02:00
Torkel Ödegaard 26ea0bc360 feat(export): work on export 2016-05-18 11:11:53 +02:00
Mitsuhiro Tanda a86d218891 (prometheus) fix metric find query 2016-05-18 16:36:57 +09:00
Torkel Ödegaard 6632f883c0 Merge branch 'master' into export-dashboard
Conflicts:
	.floo
	.flooignore
2016-05-18 08:08:15 +02:00
Mitsuhiro Tanda 66bcae353c (prometheus) pass dashboard time range to template query (#5007)
* (prometheus) pass dashboard time range to template query

* (prometheus) add passing time test of templating
2016-05-18 07:56:23 +02:00
Mitsuhiro Tanda 07d355851e (cloudwatch) assume role support (#5065)
* (cloudwatch) assume role support

* save godep

* (cloudwatch) add assumeRoleArn field

* (cloudwatch) set cred provider for sts

* (cloudwatch) fix test
2016-05-18 07:54:24 +02:00
Mitsuhiro Tanda 8d2f350ad1 (prometheus) fix prometheus link 2016-05-18 07:50:30 +02:00
Mitsuhiro Tanda fc1891320e (prometheus) fix prometheus link (#5074) 2016-05-18 07:49:32 +02:00
Utkarsh Bhatnagar 8a9455d901 Fixed singlestat mapping typo (#5070) 2016-05-18 07:44:01 +02:00
Torkel Ödegaard 46b6ab7db7 Merge branch 'master' of github.com:grafana/grafana 2016-05-17 21:51:31 +02:00
Torkel Ödegaard 958f97232f fix(pluginlist): fixed issue with plugin list, fixes #5068 2016-05-17 21:51:19 +02:00
Torkel Ödegaard 05d064ca8d export(): moved to share modal 2016-05-17 21:18:47 +02:00
Carl Bergquist 47f88346d2 Merge pull request #5058 from hijklmno/master
Add dBm as an option in energy units
2016-05-17 15:57:05 +02:00
bergquist b5fc12fb80 docs(opentsdb): add working image of add datasource for opentsdb
closes #4984
2016-05-17 15:32:33 +02:00
Torkel Ödegaard 83f5080274 feat(angular): disable debug in production for angular compiler 2016-05-17 15:00:48 +02:00
Torkel Ödegaard c133a00125 feat(alerting): minor progress on scheduler 2016-05-17 14:31:52 +02:00
Torkel Ödegaard df50fa2332 feat(export): export dashboard modal 2016-05-17 11:17:11 +02:00
Torkel Ödegaard ad7a1e15b4 feat(export): began working on export modal 2016-05-17 10:29:57 +02:00
bergquist efe6fd154b tech(docker): add default writer for influxdb 2016-05-17 09:03:52 +02:00
bergquist fb8296524e tech(docker): add default fake-data-gen for prometheus 2016-05-17 09:03:52 +02:00
Torkel Ödegaard 00957a42d4 Merge branch 'v3.0.x' 2016-05-17 08:40:28 +02:00
Torkel Ödegaard 99db89067e fix(): reverted RESTART_ON_UPGRADE change 2016-05-17 08:34:34 +02:00
hijklmno f1b5a265ab fix trailing whitespace in kbn.js 2016-05-16 15:35:42 -07:00
hijklmno 451e917e7d Add dBm as an option in energy units 2016-05-16 15:24:31 -07:00
Torkel Ödegaard d443079cf6 fix(): fixed sass issue 2016-05-16 18:48:13 +02:00
Torkel Ödegaard 163e55c0eb Update latest.json 2016-05-16 18:07:42 +02:00
bergquist fa19e0d9c6 style(modal): use standard valid styles 2016-05-16 17:03:01 +02:00
bergquist 6435fa6b99 fix(modal): add undefined check 2016-05-16 16:48:28 +02:00
bergquist 8dbb5bad4b test(alerting): fix broken unit tests 2016-05-16 16:20:28 +02:00
Torkel Ödegaard 77b7cdfadb feat(alerting): added few fields to alert rule 2016-05-16 15:39:09 +02:00
bergquist 2ce9d4571c fix(alerting): fix spacing 2016-05-16 14:29:54 +02:00
Torkel Ödegaard 495404ef73 Merge branch 'master' into alerting_definitions 2016-05-16 14:12:56 +02:00
Torkel Ödegaard 09f11cf66e updated 2016-05-16 14:11:55 +02:00
Torkel Ödegaard 4ea3002572 added floobits stuff 2016-05-16 14:02:34 +02:00
Torkel Ödegaard 840cd7b2e1 doc(): updated changelog 2016-05-16 13:58:38 +02:00
Torkel Ödegaard 0760528f4a Merge branch 'v3.0.x' 2016-05-16 13:57:44 +02:00
Torkel Ödegaard 7f0fe31881 docs(): updated download links 2016-05-16 13:41:50 +02:00
Mitsuhiro Tanda f585d22ce7 (templating) update dynamic dashboard only if variable is changed 2016-05-16 19:26:24 +09:00
bergquist 80f7fe8646 feat(alerting): add confirm text dialog when deleting dashboards with alerts 2016-05-16 11:54:28 +02:00
Torkel Ödegaard 2be8658034 Merge remote-tracking branch 'origin/development' 2016-05-16 11:40:12 +02:00
Torkel Ödegaard 494bee1d6b bumped version 2016-05-16 11:39:16 +02:00
bergquist 31698a1c55 Merge branch 'master' into alerting_definitions 2016-05-16 09:28:14 +02:00
Torkel Ödegaard 7cd663bbe8 feat(import): more import work 2016-05-14 10:00:43 +02:00
Torkel Ödegaard d9d46096dd feat(import): lots of work on dashboard import 2016-05-13 17:39:22 +02:00
bergquist da68f7d31a feat(docker): fake data writer for opentsdb 2016-05-13 16:53:28 +02:00
bergquist 41ed0e670a feat(docker): fake data writer for graphite 2016-05-13 16:25:03 +02:00
bergquist 579b36754a Merge branch 'master' into development 2016-05-13 14:30:47 +02:00
bergquist 9e5a8c3fc8 docs(changelog): add info about configurable theme 2016-05-13 11:38:54 +02:00
Carl Bergquist 83707f7b35 Merge pull request #5011 from acmnu/default_theme
Add new parameter to config: default_theme.
2016-05-13 11:36:32 +02:00
Torkel Ödegaard ca8df67947 feat(import): things are starting to work 2016-05-13 11:26:02 +02:00
Mitsuhiro Tanda 3b85901b95 reflect panel repeat status when variable updated 2016-05-13 16:29:11 +09:00
Anton Chevychalov c6744925c4 Add new parameter to config: default_theme. 2016-05-12 18:21:11 +03:00
bergquist 88b2f48493 Merge branch 'master' into development 2016-05-12 16:22:18 +02:00
Torkel Ödegaard 0d3e06e68a feat(wizard): merged wizard poc 2016-05-12 14:45:32 +02:00
Torkel Ödegaard bf890719ff Merge remote-tracking branch 'origin/wizard' into export-dashboard2 2016-05-12 10:52:24 +02:00
Torkel Ödegaard 28eae1e7ff Merge branch 'master' into export-dashboard
Conflicts:
	packaging/publish/publish.sh
	public/app/features/dashboard/dynamicDashboardSrv.js
	public/test/specs/dynamicDashboardSrv-specs.js
2016-05-12 10:50:37 +02:00
Torkel Ödegaard 2c7447eaca feat(): started work on new import system 2016-05-11 16:18:52 +02:00
Torkel Ödegaard b170b6ec8b feat(query part): moved query part editor from influxdb to core 2016-05-11 14:52:44 +02:00
bergquist e69658128c docs(alerting): change api url layout 2016-05-11 14:08:45 +02:00
bergquist c76c2f30a8 tech(alerting): add default values for alerts 2016-05-11 13:04:03 +02:00
bergquist b58be91e71 feat(alerting): add delete button for removing alerts 2016-05-11 11:11:45 +02:00
bergquist 18bf2b2391 docs(alerting): add syles for optional params 2016-05-11 10:47:51 +02:00
Torkel Ödegaard 5b42753b8b feat(export): progress on dashboard export 2016-05-10 21:09:15 +02:00
Torkel Ödegaard 79a8017fe9 feat(export): more progress on dashboard export 2016-05-10 20:31:47 +02:00
Torkel Ödegaard db664c61a4 Merge branch 'master' into export-dashboard 2016-05-10 16:46:58 +02:00
bergquist dd47f7382a docs(alerting): initial info 2016-05-10 16:40:46 +02:00
bergquist 33108df13f docs(conf): add warning about alerting in conf file 2016-05-10 16:32:20 +02:00
Torkel Ödegaard cca37caf33 feat(prometheus): began work on prometheus query model 2016-05-10 15:48:07 +02:00
bergquist 1fe2055743 tech(alerting): disable DEL for alert rules in the api 2016-05-10 15:02:11 +02:00
Torkel Ödegaard 4358687bfa Merge branch 'master' into query-part-refactor 2016-05-10 14:38:49 +02:00
Torkel Ödegaard d3bbc245c9 feat(query_part): began query part refactor to be able to reuse it in prometheus query editor 2016-05-10 14:32:25 +02:00
bergquist 5ee1b6ca97 docs(changelog): add note about merged PR 2016-05-10 12:54:25 +02:00
Carl Bergquist c522341136 Merge pull request #4944 from Gueust/optional_tooltip_ordering
Add optional tooltip ordering (against the development branch)
2016-05-10 12:51:44 +02:00
bergquist 2cebe151f2 Merge branch 'master' into development 2016-05-10 12:40:17 +02:00
bergquist 1bb8bc58b8 feat(alerting): add parameteters for filtering alerts 2016-05-10 09:45:56 +02:00
bergquist b8421a478f feat(alerting): move state filter to the right 2016-05-10 08:26:40 +02:00
bergquist 2ddffc8234 feat(alerting): add support for multiple state in ui 2016-05-09 16:32:35 +02:00
bergquist b2cf2e877a test(alerting): improve unit test 2016-05-09 15:19:11 +02:00
bergquist 9da2e6e907 feat(alerting): update path 2016-05-09 15:17:26 +02:00
bergquist 1be513fabd feat(alerting): add support for alert page filter 2016-05-09 14:44:44 +02:00
bergquist 3e462f2914 chore(alerting): style refactoring 2016-05-09 12:10:53 +02:00
bergquist 35c73902da Merge branch 'master' into alerting_definitions 2016-05-09 11:34:56 +02:00
bergquist 47070f2d1f chore(alerting): struct names and url refactoring 2016-05-09 11:25:21 +02:00
bergquist 74d5410a38 feat(alerting): add inital doc page 2016-05-06 15:59:38 +02:00
bergquist 27274f37e8 feat(alerting): update paths for alert state 2016-05-06 14:37:41 +02:00
bergquist 26941284da feat(alerting): add limit and since id options for alert logs 2016-05-04 09:57:53 +02:00
bergquist 7757d6d636 feat(alerting): set default title for alerts 2016-05-04 08:22:44 +02:00
bergquist 2ccb3956a6 feat(alerting): set default value for query 2016-05-03 17:55:41 +02:00
bergquist 1624dc9dfd feat(alerting): separate operator and level 2016-05-03 17:31:04 +02:00
bergquist 27c34745a6 feat(alerting): add link to alerts in side menu 2016-05-03 16:46:10 +02:00
Torkel Ödegaard bb6f4fff87 feat(export/import): minor progress 2016-05-03 16:40:21 +02:00
bergquist 4ea0e6ca93 feat(alerting): remove delete option from alerts page 2016-05-03 16:39:52 +02:00
bergquist 3c7e793c1f feat(alerting): add color to alert state icons 2016-05-03 16:36:49 +02:00
bergquist b0a16a9e6b Merge branch 'master' into alerting_definitions 2016-05-03 14:32:31 +02:00
bergquist 02ae1f79f7 docs(changelog): add node about range to text mappings in singlestat 2016-05-03 10:42:01 +02:00
Torkel Ödegaard f42b47e65b Merge branch 'master' into export-dashboard
Conflicts:
	public/app/features/dashboard/dashnav/dashnav.ts
2016-05-03 10:26:40 +02:00
Torkel Ödegaard de26a17dc7 feat(footer): began work on page footer 2016-05-03 09:00:58 +02:00
bergquist 1c082670c4 feat(alerting): make alertname link to status page 2016-05-02 18:06:17 +02:00
bergquist 7c5c7c6f32 feat(alerting): renames go to dashboard -> edit 2016-05-02 18:02:33 +02:00
bergquist bac89775e2 tech(alerting): fixes broken refactoring 2016-05-02 18:00:10 +02:00
bergquist 9083392341 feat(alerting): to straight for panel in alert link 2016-05-02 17:37:08 +02:00
bergquist b606d9b7da test(alerting): fixes broken test 2016-05-02 16:27:02 +02:00
bergquist 743a6fa37c feat(alerting): add support for deleting alert rules 2016-05-02 16:07:19 +02:00
bergquist a573d2504c feat(alerting): pixels have been pushed 2016-05-02 15:37:18 +02:00
bergquist 05459de344 feat(alerting): add gf icons for alerts page 2016-05-02 15:31:40 +02:00
bergquist 3eab0cde70 feat(alerting): add gf icons for alert state page 2016-05-02 15:20:58 +02:00
bergquist 9c5b4e6f25 feat(alerting): auto convert thresholds if existing 2016-05-02 14:41:29 +02:00
bergquist bc892789c1 feat(alerting): change state from ALERT to CRITICAL 2016-05-02 14:33:38 +02:00
bergquist ca959d1ab0 Merge branch 'master' into alerting_definitions 2016-05-02 13:22:58 +02:00
bergquist de5a39f320 Revert "Revert "Merge branch 'utkarshcmu-rangeMaps'""
This reverts commit 58b91befde.
2016-05-02 13:17:57 +02:00
Jean-Baptiste Lespiau c555bbce3d Add optional tooltip ordering 2016-05-01 01:32:36 +02:00
bergquist de7544fabd fix(alerting): set alertin enabled to false 2016-04-29 15:40:16 +02:00
Torkel Ödegaard f8b4fcdc42 Merge branch 'master' into export-dashboard
Conflicts:
	packaging/publish/publish.sh
2016-04-29 15:01:47 +02:00
Torkel Ödegaard 2546ec062b Merge branch 'master' into dash-edit-mode
Conflicts:
	public/app/features/dashboard/partials/settings.html
2016-04-29 14:50:17 +02:00
bergquist 6d66d9f42d feat(alerting): adds fearture toogle for alerting 2016-04-29 14:35:58 +02:00
Lucas Costa 9b84b88518 Add support to Elasticsearch precision_threshold 2016-04-28 19:23:45 -03:00
bergquist bd30a4d23e Merge branch 'master' into alerting_definitions 2016-04-28 16:04:28 +02:00
bergquist 16cede30f6 feat(alerting): move alertingtab to seperate directive 2016-04-28 16:03:14 +02:00
bergquist f442adca47 feat(alerting): adds api endpoints for alerts per dashboard and panel 2016-04-28 15:13:42 +02:00
bergquist 1f414c1372 test(alerting): add test that validates rule updates do not change state 2016-04-28 11:47:14 +02:00
bergquist ecfbc2edca feat(alerting): adds alert history page 2016-04-28 11:42:03 +02:00
bergquist 5bc3672296 Merge branch 'master' into alerting_definitions 2016-04-28 11:03:33 +02:00
bergquist 0f0fa0c257 feat(alerting): adds endpoint for getting alert states log 2016-04-28 10:59:46 +02:00
bergquist 3ecc13506c feat(alerting): adds alert state go ui 2016-04-28 08:53:34 +02:00
bergquist 1631673485 feat(alerting): dont change state when updating alert definitions 2016-04-28 08:42:51 +02:00
bergquist e7be7d2835 feat(alerting): add api endpoint for alert state 2016-04-28 08:23:50 +02:00
bergquist 6a5ecb3fca feat(alerting): adds basic page for listing alerts 2016-04-27 13:02:28 +02:00
bergquist 3cf6532515 feat(alerting): add json encoding name for properties 2016-04-27 11:44:04 +02:00
bergquist 44dd98e277 tech(alerting): rename alerting sql server 2016-04-27 09:25:11 +02:00
bergquist 7041169ffb feat(alerting): add datasource name field 2016-04-27 09:06:19 +02:00
bergquist 973db1ac38 feat(alerting): add api route for alert changes 2016-04-27 08:59:33 +02:00
bergquist 2e097f4af1 Merge branch 'master' into alerting_definitions 2016-04-26 17:38:29 +02:00
bergquist 9b50313f11 feat(alerting): add api endpoints for listing alerts 2016-04-26 17:36:50 +02:00
bergquist 996eec3ce2 tech(alerting): refactored save alerts code 2016-04-26 16:31:13 +02:00
bergquist 55e83a3d62 feat(alerting): rename alerting dashboard names 2016-04-26 16:06:29 +02:00
bergquist 3ef2be13df feat(alerting): move alert deletion to alert code 2016-04-26 15:48:29 +02:00
bergquist bb42579b0f Merge branch 'master' into alerting_definitions 2016-04-25 16:42:33 +02:00
bergquist ddd826616b feat(alerting): serialize whole target obj from dashboard 2016-04-25 16:38:27 +02:00
bergquist 25f6ec8b53 feat(alerting): add support for alert_rule updates 2016-04-25 16:18:28 +02:00
bergquist c83af353b2 feat(alerting): renames alert table to alert_rule 2016-04-25 14:42:24 +02:00
bergquist 8ca7ccae38 feat(alerting): add functionallity for converting tresholds to alerts 2016-04-25 14:18:45 +02:00
bergquist f167ce19ab test(alerting): add test for deleting alerts 2016-04-25 13:00:05 +02:00
bergquist bdd3e2ad73 Merge branch 'master' into alerting_definitions 2016-04-25 11:22:35 +02:00
bergquist 5d5999561a test(dashboard): add failing test for deleting dashboards 2016-04-25 08:46:15 +02:00
bergquist 44310921b5 test(alerting): add commented failed test 2016-04-25 08:34:48 +02:00
bergquist 03e6fc951f feat(alerting): delete alerts when dashboard gets deleted 2016-04-23 14:14:18 +02:00
bergquist ec6dbe3067 tests(alerting): connect alerts to dashboard 2016-04-23 10:41:50 +02:00
bergquist 84115c8038 feat(alerting): delete alerts when panels are removed 2016-04-22 17:49:50 +02:00
bergquist 8bb62a79d0 feat(alerting): excisting alerts are now updated 2016-04-22 16:51:24 +02:00
bergquist ba5978abd3 Merge branch 'master' into alerting_definitions 2016-04-22 15:52:56 +02:00
bergquist d21f97e69b feat(alerting): adds basic alerting tab 2016-04-21 11:47:30 +02:00
bergquist 96e88ee84d refactor(alerting): changes interval to string from int 2016-04-20 16:57:03 +02:00
bergquist 262821e7e7 feat(alerting): tests that alertes can be read from db 2016-04-20 16:46:24 +02:00
bergquist ef92fd4ebc feat(alerting): renames error_level to crit_level 2016-04-20 15:02:49 +02:00
bergquist 7860a2a1b8 feat(alerting): make sure dashboard id exists 2016-04-20 09:55:32 +02:00
Mitsuhiro Tanda ab9abee67b (cloudwatch) add test for interval variable 2016-04-20 01:27:44 +09:00
bergquist ca3ad7d17c tests(alerting): add tests for saving alerts 2016-04-19 16:52:20 +02:00
Mitsuhiro Tanda 2e5a1328a8 (cloudwatch) support interval template variable 2016-04-19 22:57:34 +09:00
bergquist 832e38af34 feat(alerting): limit alerts to one per panel 2016-04-19 15:34:23 +02:00
bergquist daa5468801 feat(alerting): parses dashboard alerts 2016-04-18 14:15:03 +02:00
bergquist 769016783f feat(alerting): add aggregator field 2016-04-18 11:10:52 +02:00
bergquist bcf10a6483 Merge branch 'master' into alerting_definitions 2016-04-18 10:28:40 +02:00
Matt Toback a7e8e64d78 The beginnings of the build mode and rows 2016-04-15 19:52:18 -04:00
Torkel Ödegaard 5f6ecac3f9 poc(editmode): experimental edit mode 2016-04-15 15:11:40 -04:00
Torkel Ödegaard 0f71838fdf feat(dash export): dashboard export can now replace datasource names with variable and add inputs section 2016-04-14 21:13:01 -04:00
Torkel Ödegaard 4d0b14fbb4 feat(exporter): stared work on dashboard exporter that cleans up repeated panels etc 2016-04-14 17:31:34 -04:00
Torkel Ödegaard 1f9922a5aa refactor(): moved dashboard_srv and DashboardCtrl to typescript 2016-04-14 16:53:19 -04:00
bergquist 91a1a823e2 feat(alerting): add basic tables for alerting definitions 2016-04-13 10:33:45 +02:00
Torkel Ödegaard 75649c49d5 Merge branch 'master' into wizard 2016-04-11 18:18:09 -04:00
Torkel Ödegaard 437b880b3e feat(plugins): work on setup wizard started 2016-03-25 22:14:29 +01:00
3896 changed files with 986494 additions and 69297 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
root = true
[*.go]
indent_style = tabs
indent_style = tab
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
+3
View File
@@ -0,0 +1,3 @@
{
"url": "https://floobits.com/raintank/grafana"
}
+12
View File
@@ -0,0 +1,12 @@
#*
*.o
*.pyc
*.pyo
*~
extern/
node_modules/
tmp/
data/
vendor/
public_gen/
dist/
+3 -3
View File
@@ -12,11 +12,11 @@ grunt karma:dev
### Run tests for backend assets before commit
```
test -z "$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
test -z "$(gofmt -s -l . | grep -v -E 'vendor/(github.com|golang.org|gopkg.in)' | tee /dev/stderr)"
```
### Run tests for frontend assets before commit
```
grunt test
godep go test -v ./pkg/...
npm test
go test -v ./pkg/...
```
+9 -12
View File
@@ -1,20 +1,17 @@
Thank you! For helping us make Grafana even better.
* **I'm submitting a ...**
- [ ] Bug report
- [ ] Feature request
- [ ] Question / Support request: **Please do not** open a github issue. [Support Options](http://grafana.org/support/)
To help us respond to your issues faster, please make sure to add as much information as possible.
If this issue is about a plugin, please open the issue in that repository.
Start your issues title with [Feature Request] / [Bug] / [Question] or no tag if your unsure. Also, please be aware that GitHub now supports uploading of screenshots; look at the bottom of this input field.
Please include some basic information:
- What grafana version are you using?
Please include this information:
- What Grafana version are you using?
- What datasource are you using?
- What OS are you running grafana on?
- What did you do?
- What was the expected result?
- What happenend instead?
- What happened instead?
If you question/bug relates to a metric query / unexpected data visualization, please include:
**IMPORTANT** If it relates to metric data viz:
- An image or text representation of your metric query
- The raw query and response from your data source (check this in chrome dev tools network tab)
- The raw query and response for the network request (check this in chrome dev tools network tab, here you can see metric requests and other request, please include the request body and request response)
+2 -1
View File
@@ -25,6 +25,7 @@ public/css/*.min.css
*.swp
.idea/
*.iml
.vscode/
/data/*
/bin/*
@@ -37,4 +38,4 @@ profile.cov
.notouch
/pkg/cmd/grafana-cli/grafana-cli
/pkg/cmd/grafana-server/grafana-server
/examples/*/dist
/examples/*/dist
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
test -z "$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
test -z "$(gofmt -s -l . | grep -v vendor/src/ | tee /dev/stderr)"
if [ $? -gt 0 ]; then
echo "Some files aren't formatted, please run 'go fmt ./pkg/...' to format your source code before committing"
exit 1
+1 -1
View File
@@ -10,4 +10,4 @@
"disallowSpacesInsideArrayBrackets": true,
"disallowSpacesInsideParentheses": true,
"validateIndentation": 2
}
}
+122 -1
View File
@@ -1,4 +1,124 @@
# 3.0.2 Stable (unreleased)
# 4.0-beta2 (unrelased)
### Bugfixes
* **Graph Panel**: Log base scale on right Y-axis had no effect, max value calc was not applied, [#6534](https://github.com/grafana/grafana/issues/6534)
* **Graph Panel**: Bar width if bars was only used in series override, [#6528](https://github.com/grafana/grafana/issues/6528)
* **UI/Browser**: Fixed issue with page/view header gradient border not showing in Safari, [#6530](https://github.com/grafana/grafana/issues/6530)
* **Cloudwatch**: Fixed cloudwatch datasource requesting to many datapoints, [#6544](https://github.com/grafana/grafana/issues/6544)
* **UX**: Panel Drop zone visible after duplicating panel, and when entering fullscreen/edit view, [#6598](https://github.com/grafana/grafana/issues/6598)
* **Templating**: Newly added variable was not visible directly only after dashboard reload, [#6622](https://github.com/grafana/grafana/issues/6622)
### Enhancements
* **Singlestat**: Support repeated template variables in prefix/postfix [#6595](https://github.com/grafana/grafana/issues/6595)
* **Templating**: Don't persist variable options with refresh option [#6586](https://github.com/grafana/grafana/issues/6586)
* **Alerting**: Add ability to have OR conditions (and mixing AND & OR) [#6579](https://github.com/grafana/grafana/issues/6579)
# 4.0-beta1 (2016-11-09)
### Enhancements
* **Login**: Adds option to disable username/password logins, closes [#4674](https://github.com/grafana/grafana/issues/4674)
* **SingleStat**: Add seriename as option in singlestat panel, closes [#4740](https://github.com/grafana/grafana/issues/4740)
* **Localization**: Week start day now dependant on browser locale setting, closes [#3003](https://github.com/grafana/grafana/issues/3003)
* **Templating**: Update panel repeats for variables that change on time refresh, closes [#5021](https://github.com/grafana/grafana/issues/5021)
* **Templating**: Add support for numeric and alphabetical sorting of variable values, closes [#2839](https://github.com/grafana/grafana/issues/2839)
* **Elasticsearch**: Support to set Precision Threshold for Unique Count metric, closes [#4689](https://github.com/grafana/grafana/issues/4689)
* **Navigation**: Add search to org swithcer, closes [#2609](https://github.com/grafana/grafana/issues/2609)
* **Database**: Allow database config using one propertie, closes [#5456](https://github.com/grafana/grafana/pull/5456)
* **Graphite**: Add support for groupByNodes, closes [#5613](https://github.com/grafana/grafana/pull/5613)
* **Influxdb**: Add support for elapsed(), closes [#5827](https://github.com/grafana/grafana/pull/5827)
* **OpenTSDB**: Add support for explicitTags for OpenTSDB>=2.3, closes [#6360](https://github.com/grafana/grafana/pull/6361)
* **OAuth**: Add support for generic oauth, closes [#4718](https://github.com/grafana/grafana/pull/4718)
* **Cloudwatch**: Add support to expand multi select template variable, closes [#5003](https://github.com/grafana/grafana/pull/5003)
* **Background Tasks**: Now support automatic purging of old snapshots, closes [#4087](https://github.com/grafana/grafana/issues/4087)
* **Background Tasks**: Now support automatic purging of old rendered images, closes [#2172](https://github.com/grafana/grafana/issues/2172)
* **Dashboard**: After inactivity hide nav/row actions, fade to nice clean view, can be toggled with `d v`, also added kiosk mode, toggled via `d k` [#6476](https://github.com/grafana/grafana/issues/6476)
* **Dashboard**: Improved dashboard row menu & add panel UX [#6442](https://github.com/grafana/grafana/issues/6442)
* **Graph Panel**: Support for stacking null values [#2912](https://github.com/grafana/grafana/issues/2912), [#6287](https://github.com/grafana/grafana/issues/6287), thanks @benrubson!
### Breaking changes
* **SystemD**: Change systemd description, closes [#5971](https://github.com/grafana/grafana/pull/5971)
* **lodash upgrade**: Upgraded lodash from 2.4.2 to 4.15.0, this contains a number of breaking changes that could effect plugins. closes [#6021](https://github.com/grafana/grafana/pull/6021)
### Bug fixes
* **Table Panel**: Fixed problem when switching to Mixed datasource in metrics tab, fixes [#5999](https://github.com/grafana/grafana/pull/5999)
* **Playlist**: Fixed problem with play order not matching order defined in playlist, fixes [#5467](https://github.com/grafana/grafana/pull/5467)
* **Graph panel**: Fixed problem with auto decimals on y axis when datamin=datamax, fixes [#6070](https://github.com/grafana/grafana/pull/6070)
* **Snapshot**: Can view embedded panels/png rendered panels in snapshots without login, fixes [#3769](https://github.com/grafana/grafana/pull/3769)
* **Elasticsearch**: Fix for query template variable when looking up terms without query, no longer relies on elasticsearch default field, fixes [#3887](https://github.com/grafana/grafana/pull/3887)
* **Elasticsearch**: Fix for displaying IP address used in terms aggregations, fixes [#4393](https://github.com/grafana/grafana/pull/4393)
* **PNG Rendering**: Fix for server side rendering when using auth proxy, fixes [#5906](https://github.com/grafana/grafana/pull/5906)
* **OpenTSDB**: Fixed multi-value nested templating for opentsdb, fixes [#6455](https://github.com/grafana/grafana/pull/6455)
* **Playlist**: Remove playlist items when dashboard is removed, fixes [#6292](https://github.com/grafana/grafana/issues/6292)
# 3.1.2 (unreleased)
* **Templating**: Fixed issue when combining row & panel repeats, fixes [#5790](https://github.com/grafana/grafana/issues/5790)
* **Drag&Drop**: Fixed issue with drag and drop in latest Chrome(51+), fixes [#5767](https://github.com/grafana/grafana/issues/5767)
* **Internal Metrics**: Fixed issue with dots in instance_name when sending internal metrics to Graphite, fixes [#5739](https://github.com/grafana/grafana/issues/5739)
* **Grafana-CLI**: Add default plugin path for MAC OS, fixes [#5806](https://github.com/grafana/grafana/issues/5806)
* **Grafana-CLI**: Improve error message for upgrade-all command, fixes [#5885](https://github.com/grafana/grafana/issues/5885)
# 3.1.1 (2016-08-01)
* **IFrame embedding**: Fixed issue of using full iframe height, fixes [#5605](https://github.com/grafana/grafana/issues/5606)
* **Panel PNG rendering**: Fixed issue detecting render completion, fixes [#5605](https://github.com/grafana/grafana/issues/5606)
* **Elasticsearch**: Fixed issue with templating query and json parse error, fixes [#5615](https://github.com/grafana/grafana/issues/5615)
* **Tech**: Upgraded JQuery to 2.2.4 to fix Security vulnerabilitie in 2.1.4, fixes [#5627](https://github.com/grafana/grafana/issues/5627)
* **Graphite**: Fixed issue with mixed data sources and Graphite, fixes [#5617](https://github.com/grafana/grafana/issues/5617)
* **Templating**: Fixed issue with template variable query was issued multiple times during dashboard load, fixes [#5637](https://github.com/grafana/grafana/issues/5637)
* **Zoom**: Fixed issues with zoom in and out on embedded (iframed) panel, fixes [#4489](https://github.com/grafana/grafana/issues/4489), [#5666](https://github.com/grafana/grafana/issues/5666)
# 3.1.0 stable (2016-07-12)
### Bugfixes & Enhancements,
* **User Alert Notices**: Backend error alert popups did not show properly, fixes [#5435](https://github.com/grafana/grafana/issues/5435)
* **Table**: Added sanitize HTML option to allow links in table cells, fixes [#4596](https://github.com/grafana/grafana/issues/4596)
* **Apps**: App dashboards are automatically synced to DB at startup after plugin update, fixes [#5529](https://github.com/grafana/grafana/issues/5529)
# 3.1.0-beta1 (2016-06-23)
### Enhancements
* **Dashboard Export/Import**: Dashboard export now templetize data sources and constant variables, users pick these on import, closes [#5084](https://github.com/grafana/grafana/issues/5084)
* **Dashboard Url**: Time range changes updates url, closes [#458](https://github.com/grafana/grafana/issues/458)
* **Dashboard Url**: Template variable change updates url, closes [#5002](https://github.com/grafana/grafana/issues/5002)
* **Singlestat**: Add support for range to text mappings, closes [#1319](https://github.com/grafana/grafana/issues/1319)
* **Graph**: Adds sort order options for graph tooltip, closes [#1189](https://github.com/grafana/grafana/issues/1189)
* **Theme**: Add default theme to config file [#5011](https://github.com/grafana/grafana/pull/5011)
* **Page Footer**: Added page footer with links to docs, shows Grafana version and info if new version is available, closes [#4889](https://github.com/grafana/grafana/pull/4889)
* **InfluxDB**: Add spread function, closes [#5211](https://github.com/grafana/grafana/issues/5211)
* **Scripts**: Use restart instead of start for deb package script, closes [#5282](https://github.com/grafana/grafana/pull/5282)
* **Logging**: Moved to structured logging lib, and moved to component specific level filters via config file, closes [#4590](https://github.com/grafana/grafana/issues/4590)
* **OpenTSDB**: Support nested template variables in tag_values function, closes [#4398](https://github.com/grafana/grafana/issues/4398)
* **Datasource**: Pending data source requests are cancelled before new ones are issues (Graphite & Prometheus), closes [#5321](https://github.com/grafana/grafana/issues/5321)
### Breaking changes
* **Logging** : Changed default logging output format (now structured into message, and key value pairs, with logger key acting as component). You can also no change in config to json log ouput.
* **Graphite** : The Graph panel no longer have a Graphite PNG option. closes [#5367](https://github.com/grafana/grafana/issues/5367)
### Bug fixes
* **PNG rendering**: Fixed phantomjs rendering and y-axis label rotation. fixes [#5220](https://github.com/grafana/grafana/issues/5220)
* **CLI**: The cli tool now supports reading plugin.json from dist/plugin.json. fixes [#5410](https://github.com/grafana/grafana/issues/5410)
# 3.0.4 Patch release (2016-05-25)
* **Panel**: Fixed blank dashboard issue when switching to other dashboard while in fullscreen edit mode, fixes [#5163](https://github.com/grafana/grafana/pull/5163)
* **Templating**: Fixed issue with nested multi select variables and cascading and updating child variable selection state, fixes [#4861](https://github.com/grafana/grafana/pull/4861)
* **Templating**: Fixed issue with using templated data source in another template variable query, fixes [#5165](https://github.com/grafana/grafana/pull/5165)
* **Singlestat gauge**: Fixed issue with gauge render position, fixes [#5143](https://github.com/grafana/grafana/pull/5143)
* **Home dashboard**: Fixes broken home dashboard api, fixes [#5167](https://github.com/grafana/grafana/issues/5167)
# 3.0.3 Patch release (2016-05-23)
* **Annotations**: Annotations can now use a template variable as data source, closes [#5054](https://github.com/grafana/grafana/issues/5054)
* **Time picker**: Fixed issue timepicker and UTC when reading time from URL, fixes [#5078](https://github.com/grafana/grafana/issues/5078)
* **CloudWatch**: Support for Multiple Account by AssumeRole, closes [#3522](https://github.com/grafana/grafana/issues/3522)
* **Singlestat**: Fixed alignment and minium height issue, fixes [#5113](https://github.com/grafana/grafana/issues/5113), fixes [#4679](https://github.com/grafana/grafana/issues/4679)
* **Share modal**: Fixed link when using grafana under dashboard sub url, fixes [#5109](https://github.com/grafana/grafana/issues/5109)
* **Prometheus**: Fixed bug in query editor that caused it not to load when reloading page, fixes [#5107](https://github.com/grafana/grafana/issues/5107)
* **Elasticsearch**: Fixed bug when template variable query returns numeric values, fixes [#5097](https://github.com/grafana/grafana/issues/5097), fixes [#5088](https://github.com/grafana/grafana/issues/5088)
* **Logging**: Fixed issue with reading logging level value, fixes [#5079](https://github.com/grafana/grafana/issues/5079)
* **Timepicker**: Fixed issue with timepicker and UTC when reading time from URL, fixes [#5078](https://github.com/grafana/grafana/issues/5078)
* **Docs**: Added docs for org & user preferences HTTP API, closes [#5069](https://github.com/grafana/grafana/issues/5069)
* **Plugin list panel**: Now shows correct enable state for apps when not enabled, fixes [#5068](https://github.com/grafana/grafana/issues/5068)
* **Elasticsearch**: Templating & Annotation queries that use template variables are now formatted correctly, fixes [#5135](https://github.com/grafana/grafana/issues/5135)
# 3.0.2 Patch release (2016-05-16)
* **Templating**: Fixed issue mixing row repeat and panel repeats, fixes [#4988](https://github.com/grafana/grafana/issues/4988)
* **Templating**: Fixed issue detecting dependencies in nested variables, fixes [#4987](https://github.com/grafana/grafana/issues/4987), fixes [#4986](https://github.com/grafana/grafana/issues/4986)
@@ -9,6 +129,7 @@
# 3.0.1 Stable (2016-05-11)
### Bug fixes
* **Templating**: Fixed issue with new data source variable not persisting current selected value, fixes [#4934](https://github.com/grafana/grafana/issues/4934)
# 3.0.0-beta7 (2016-05-02)
-351
View File
@@ -1,351 +0,0 @@
{
"ImportPath": "github.com/grafana/grafana",
"GoVersion": "go1.5.1",
"Packages": [
"./pkg/..."
],
"Deps": [
{
"ImportPath": "github.com/BurntSushi/toml",
"Comment": "v0.1.0-21-g056c9bc",
"Rev": "056c9bc7be7190eaa7715723883caffa5f8fa3e4"
},
{
"ImportPath": "github.com/Unknwon/com",
"Rev": "d9bcf409c8a368d06c9b347705c381e7c12d54df"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/client",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/request",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/session",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/endpoints",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/signer/v4",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/private/waiter",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/service/cloudwatch",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
{
"ImportPath": "github.com/bmizerany/assert",
"Comment": "release.r60-6-ge17e998",
"Rev": "e17e99893cb6509f428e1728281c2ad60a6b31e3"
},
{
"ImportPath": "github.com/bradfitz/gomemcache/memcache",
"Comment": "release.r60-40-g72a6864",
"Rev": "72a68649ba712ee7c4b5b4a943a626bcd7d90eb8"
},
{
"ImportPath": "github.com/codegangsta/cli",
"Comment": "1.2.0-187-gc31a797",
"Rev": "c31a7975863e7810c92e2e288a9ab074f9a88f29"
},
{
"ImportPath": "github.com/davecgh/go-spew/spew",
"Rev": "2df174808ee097f90d259e432cc04442cf60be21"
},
{
"ImportPath": "github.com/fatih/color",
"Comment": "v0.1-16-g4f7bcef",
"Rev": "4f7bcef27eec7925456d0c30c5e7b0408b3339be"
},
{
"ImportPath": "github.com/franela/goreq",
"Rev": "3ddeded65be21dacb5a2e2d0b95af9ff6862a2b5"
},
{
"ImportPath": "github.com/go-ini/ini",
"Comment": "v0-48-g060d7da",
"Rev": "060d7da055ba6ec5ea7a31f116332fe5efa04ce0"
},
{
"ImportPath": "github.com/go-ldap/ldap",
"Comment": "v2.2.1",
"Rev": "07a7330929b9ee80495c88a4439657d89c7dbd87"
},
{
"ImportPath": "github.com/go-macaron/binding",
"Rev": "2502aaf4bce3a4e6451b4610847bfb8dffdb6266"
},
{
"ImportPath": "github.com/go-macaron/gzip",
"Rev": "4938e9be6b279d8426cb1c89a6bcf7af70b0c21d"
},
{
"ImportPath": "github.com/go-macaron/inject",
"Rev": "c5ab7bf3a307593cd44cb272d1a5beea473dd072"
},
{
"ImportPath": "github.com/go-macaron/session",
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
},
{
"ImportPath": "github.com/go-macaron/session/memcache",
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
},
{
"ImportPath": "github.com/go-macaron/session/mysql",
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
},
{
"ImportPath": "github.com/go-macaron/session/postgres",
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
},
{
"ImportPath": "github.com/go-macaron/session/redis",
"Rev": "66031fcb37a0fff002a1f028eb0b3a815c78306b"
},
{
"ImportPath": "github.com/go-sql-driver/mysql",
"Comment": "v1.2-171-g267b128",
"Rev": "267b128680c46286b9ca13475c3cca5de8f79bd7"
},
{
"ImportPath": "github.com/go-xorm/core",
"Comment": "v0.4.4-7-g9e608f7",
"Rev": "9e608f7330b9d16fe2818cfe731128b3f156cb9a"
},
{
"ImportPath": "github.com/go-xorm/xorm",
"Comment": "v0.4.4-44-gf561133",
"Rev": "f56113384f2c63dfe4cd8e768e349f1c35122b58"
},
{
"ImportPath": "github.com/gorilla/websocket",
"Rev": "c45a635370221f34fea2d5163fd156fcb4e38e8a"
},
{
"ImportPath": "github.com/gosimple/slug",
"Rev": "8d258463b4459f161f51d6a357edacd3eef9d663"
},
{
"ImportPath": "github.com/hashicorp/go-version",
"Rev": "7e3c02b30806fa5779d3bdfc152ce4c6f40e7b38"
},
{
"ImportPath": "github.com/jmespath/go-jmespath",
"Comment": "0.2.2",
"Rev": "3433f3ea46d9f8019119e7dd41274e112a2359a9"
},
{
"ImportPath": "github.com/jtolds/gls",
"Rev": "f1ac7f4f24f50328e6bc838ca4437d1612a0243c"
},
{
"ImportPath": "github.com/klauspost/compress/flate",
"Rev": "7b02889a2005228347aef0e76beeaee564d82f8c"
},
{
"ImportPath": "github.com/klauspost/compress/gzip",
"Rev": "7b02889a2005228347aef0e76beeaee564d82f8c"
},
{
"ImportPath": "github.com/klauspost/cpuid",
"Rev": "349c675778172472f5e8f3a3e0fe187e302e5a10"
},
{
"ImportPath": "github.com/klauspost/crc32",
"Rev": "6834731faf32e62a2dd809d99fb24d1e4ae5a92d"
},
{
"ImportPath": "github.com/kr/pretty",
"Comment": "go.weekly.2011-12-22-27-ge6ac2fc",
"Rev": "e6ac2fc51e89a3249e82157fa0bb7a18ef9dd5bb"
},
{
"ImportPath": "github.com/kr/text",
"Rev": "bb797dc4fb8320488f47bf11de07a733d7233e1f"
},
{
"ImportPath": "github.com/lib/pq",
"Comment": "go1.0-cutoff-13-g19eeca3",
"Rev": "19eeca3e30d2577b1761db471ec130810e67f532"
},
{
"ImportPath": "github.com/lib/pq/oid",
"Comment": "go1.0-cutoff-13-g19eeca3",
"Rev": "19eeca3e30d2577b1761db471ec130810e67f532"
},
{
"ImportPath": "github.com/mattn/go-colorable",
"Rev": "9cbef7c35391cca05f15f8181dc0b18bc9736dbb"
},
{
"ImportPath": "github.com/mattn/go-isatty",
"Rev": "56b76bdf51f7708750eac80fa38b952bb9f32639"
},
{
"ImportPath": "github.com/mattn/go-sqlite3",
"Comment": "v1.1.0-67-g7204887",
"Rev": "7204887cf3a42df1cfaa5505dc3a3427f6dded8b"
},
{
"ImportPath": "github.com/rainycape/unidecode",
"Rev": "836ef0a715aedf08a12d595ed73ec8ed5b288cac"
},
{
"ImportPath": "github.com/smartystreets/goconvey/convey",
"Comment": "1.5.0-356-gfbc0a1c",
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
},
{
"ImportPath": "github.com/smartystreets/goconvey/convey/assertions",
"Comment": "1.5.0-356-gfbc0a1c",
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
},
{
"ImportPath": "github.com/smartystreets/goconvey/convey/assertions/oglematchers",
"Comment": "1.5.0-356-gfbc0a1c",
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
},
{
"ImportPath": "github.com/smartystreets/goconvey/convey/gotest",
"Comment": "1.5.0-356-gfbc0a1c",
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
},
{
"ImportPath": "github.com/smartystreets/goconvey/convey/reporting",
"Comment": "1.5.0-356-gfbc0a1c",
"Rev": "fbc0a1c888f9f96263f9a559d1769905245f1123"
},
{
"ImportPath": "github.com/streadway/amqp",
"Rev": "150b7f24d6ad507e6026c13d85ce1f1391ac7400"
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "972f0c5fbe4ae29e666c3f78c3ed42ae7a448b0a"
},
{
"ImportPath": "golang.org/x/oauth2",
"Rev": "c58fcf0ffc1c772aa2e1ee4894bc19f2649263b2"
},
{
"ImportPath": "golang.org/x/sys/unix",
"Rev": "7a56174f0086b32866ebd746a794417edbc678a1"
},
{
"ImportPath": "gopkg.in/asn1-ber.v1",
"Comment": "v1",
"Rev": "9eae18c3681ae3d3c677ac2b80a8fe57de45fc09"
},
{
"ImportPath": "gopkg.in/bufio.v1",
"Comment": "v1",
"Rev": "567b2bfa514e796916c4747494d6ff5132a1dfce"
},
{
"ImportPath": "gopkg.in/ini.v1",
"Comment": "v0-16-g1772191",
"Rev": "177219109c97e7920c933e21c9b25f874357b237"
},
{
"ImportPath": "gopkg.in/macaron.v1",
"Rev": "1c6dd87797ae9319b4658cbd48d1d0420b279fd5"
},
{
"ImportPath": "gopkg.in/redis.v2",
"Comment": "v2.3.2",
"Rev": "e6179049628164864e6e84e973cfb56335748dea"
}
]
}
-2
View File
@@ -1,2 +0,0 @@
/pkg
/bin
@@ -1,45 +0,0 @@
package client
import (
"math"
"math/rand"
"time"
"github.com/aws/aws-sdk-go/aws/request"
)
// DefaultRetryer implements basic retry logic using exponential backoff for
// most services. If you want to implement custom retry logic, implement the
// request.Retryer interface or create a structure type that composes this
// struct and override the specific methods. For example, to override only
// the MaxRetries method:
//
// type retryer struct {
// service.DefaultRetryer
// }
//
// // This implementation always has 100 max retries
// func (d retryer) MaxRetries() uint { return 100 }
type DefaultRetryer struct {
NumMaxRetries int
}
// MaxRetries returns the number of maximum returns the service will use to make
// an individual API request.
func (d DefaultRetryer) MaxRetries() int {
return d.NumMaxRetries
}
// RetryRules returns the delay duration before retrying this request again
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
delay := int(math.Pow(2, float64(r.RetryCount))) * (rand.Intn(30) + 30)
return time.Duration(delay) * time.Millisecond
}
// ShouldRetry returns if the request should be retried.
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
if r.HTTPResponse.StatusCode >= 500 {
return true
}
return r.IsErrorRetryable()
}
@@ -1,144 +0,0 @@
package corehandlers
import (
"fmt"
"reflect"
"strconv"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
// ValidateParametersHandler is a request handler to validate the input parameters.
// Validating parameters only has meaning if done prior to the request being sent.
var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
if r.ParamsFilled() {
v := validator{errors: []string{}}
v.validateAny(reflect.ValueOf(r.Params), "")
if count := len(v.errors); count > 0 {
format := "%d validation errors:\n- %s"
msg := fmt.Sprintf(format, count, strings.Join(v.errors, "\n- "))
r.Error = awserr.New("InvalidParameter", msg, nil)
}
}
}}
// A validator validates values. Collects validations errors which occurs.
type validator struct {
errors []string
}
// validateAny will validate any struct, slice or map type. All validations
// are also performed recursively for nested types.
func (v *validator) validateAny(value reflect.Value, path string) {
value = reflect.Indirect(value)
if !value.IsValid() {
return
}
switch value.Kind() {
case reflect.Struct:
v.validateStruct(value, path)
case reflect.Slice:
for i := 0; i < value.Len(); i++ {
v.validateAny(value.Index(i), path+fmt.Sprintf("[%d]", i))
}
case reflect.Map:
for _, n := range value.MapKeys() {
v.validateAny(value.MapIndex(n), path+fmt.Sprintf("[%q]", n.String()))
}
}
}
// validateStruct will validate the struct value's fields. If the structure has
// nested types those types will be validated also.
func (v *validator) validateStruct(value reflect.Value, path string) {
prefix := "."
if path == "" {
prefix = ""
}
for i := 0; i < value.Type().NumField(); i++ {
f := value.Type().Field(i)
if strings.ToLower(f.Name[0:1]) == f.Name[0:1] {
continue
}
fvalue := value.FieldByName(f.Name)
err := validateField(f, fvalue, validateFieldRequired, validateFieldMin)
if err != nil {
v.errors = append(v.errors, fmt.Sprintf("%s: %s", err.Error(), path+prefix+f.Name))
continue
}
v.validateAny(fvalue, path+prefix+f.Name)
}
}
type validatorFunc func(f reflect.StructField, fvalue reflect.Value) error
func validateField(f reflect.StructField, fvalue reflect.Value, funcs ...validatorFunc) error {
for _, fn := range funcs {
if err := fn(f, fvalue); err != nil {
return err
}
}
return nil
}
// Validates that a field has a valid value provided for required fields.
func validateFieldRequired(f reflect.StructField, fvalue reflect.Value) error {
if f.Tag.Get("required") == "" {
return nil
}
switch fvalue.Kind() {
case reflect.Ptr, reflect.Slice, reflect.Map:
if fvalue.IsNil() {
return fmt.Errorf("missing required parameter")
}
default:
if !fvalue.IsValid() {
return fmt.Errorf("missing required parameter")
}
}
return nil
}
// Validates that if a value is provided for a field, that value must be at
// least a minimum length.
func validateFieldMin(f reflect.StructField, fvalue reflect.Value) error {
minStr := f.Tag.Get("min")
if minStr == "" {
return nil
}
min, _ := strconv.ParseInt(minStr, 10, 64)
kind := fvalue.Kind()
if kind == reflect.Ptr {
if fvalue.IsNil() {
return nil
}
fvalue = fvalue.Elem()
}
switch fvalue.Kind() {
case reflect.String:
if int64(fvalue.Len()) < min {
return fmt.Errorf("field too short, minimum length %d", min)
}
case reflect.Slice, reflect.Map:
if fvalue.IsNil() {
return nil
}
if int64(fvalue.Len()) < min {
return fmt.Errorf("field too short, minimum length %d", min)
}
// TODO min can also apply to number minimum value.
}
return nil
}
@@ -1,134 +0,0 @@
package corehandlers_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/stretchr/testify/require"
)
var testSvc = func() *client.Client {
s := &client.Client{
Config: aws.Config{},
ClientInfo: metadata.ClientInfo{
ServiceName: "mock-service",
APIVersion: "2015-01-01",
},
}
return s
}()
type StructShape struct {
RequiredList []*ConditionalStructShape `required:"true"`
RequiredMap map[string]*ConditionalStructShape `required:"true"`
RequiredBool *bool `required:"true"`
OptionalStruct *ConditionalStructShape
hiddenParameter *string
metadataStructureShape
}
type metadataStructureShape struct {
SDKShapeTraits bool
}
type ConditionalStructShape struct {
Name *string `required:"true"`
SDKShapeTraits bool
}
func TestNoErrors(t *testing.T) {
input := &StructShape{
RequiredList: []*ConditionalStructShape{},
RequiredMap: map[string]*ConditionalStructShape{
"key1": {Name: aws.String("Name")},
"key2": {Name: aws.String("Name")},
},
RequiredBool: aws.Bool(true),
OptionalStruct: &ConditionalStructShape{Name: aws.String("Name")},
}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.NoError(t, req.Error)
}
func TestMissingRequiredParameters(t *testing.T) {
input := &StructShape{}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Error(t, req.Error)
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList\n- missing required parameter: RequiredMap\n- missing required parameter: RequiredBool", req.Error.(awserr.Error).Message())
}
func TestNestedMissingRequiredParameters(t *testing.T) {
input := &StructShape{
RequiredList: []*ConditionalStructShape{{}},
RequiredMap: map[string]*ConditionalStructShape{
"key1": {Name: aws.String("Name")},
"key2": {},
},
RequiredBool: aws.Bool(true),
OptionalStruct: &ConditionalStructShape{},
}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Error(t, req.Error)
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList[0].Name\n- missing required parameter: RequiredMap[\"key2\"].Name\n- missing required parameter: OptionalStruct.Name", req.Error.(awserr.Error).Message())
}
type testInput struct {
StringField string `min:"5"`
PtrStrField *string `min:"2"`
ListField []string `min:"3"`
MapField map[string]string `min:"4"`
}
var testsFieldMin = []struct {
err awserr.Error
in testInput
}{
{
err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 5: StringField", nil),
in: testInput{StringField: "abcd"},
},
{
err: awserr.New("InvalidParameter", "2 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField", nil),
in: testInput{StringField: "abcd", ListField: []string{"a", "b"}},
},
{
err: awserr.New("InvalidParameter", "3 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField\n- field too short, minimum length 4: MapField", nil),
in: testInput{StringField: "abcd", ListField: []string{"a", "b"}, MapField: map[string]string{"a": "a", "b": "b"}},
},
{
err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 2: PtrStrField", nil),
in: testInput{StringField: "abcde", PtrStrField: aws.String("v")},
},
{
err: nil,
in: testInput{StringField: "abcde", PtrStrField: aws.String("value"),
ListField: []string{"a", "b", "c"}, MapField: map[string]string{"a": "a", "b": "b", "c": "c", "d": "d"}},
},
}
func TestValidateFieldMinParameter(t *testing.T) {
for i, c := range testsFieldMin {
req := testSvc.NewRequest(&request.Operation{}, &c.in, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Equal(t, c.err, req.Error, "%d case failed", i)
}
}
@@ -1,73 +0,0 @@
package credentials
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/stretchr/testify/assert"
)
func TestChainProviderGet(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
&stubProvider{
creds: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
},
},
}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
}
func TestChainProviderIsExpired(t *testing.T) {
stubProvider := &stubProvider{expired: true}
p := &ChainProvider{
Providers: []Provider{
stubProvider,
},
}
assert.True(t, p.IsExpired(), "Expect expired to be true before any Retrieve")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
stubProvider.expired = true
assert.True(t, p.IsExpired(), "Expect return of expired provider")
_, err = p.Retrieve()
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
}
func TestChainProviderWithNoProvider(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{},
}
assert.True(t, p.IsExpired(), "Expect expired with no providers")
_, err := p.Retrieve()
assert.Equal(t, ErrNoValidProvidersFoundInChain, err, "Expect no providers error returned")
}
func TestChainProviderWithNoValidProvider(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
},
}
assert.True(t, p.IsExpired(), "Expect expired with no providers")
_, err := p.Retrieve()
assert.Equal(t, ErrNoValidProvidersFoundInChain, err, "Expect no providers error returned")
}
@@ -1,76 +0,0 @@
// Package defaults is a collection of helpers to retrieve the SDK's default
// configuration and handlers.
package defaults
import (
"net/http"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/endpoints"
)
// A Defaults provides a collection of default values for SDK clients.
type Defaults struct {
Config *aws.Config
Handlers request.Handlers
}
// Get returns the SDK's default values with Config and handlers pre-configured.
func Get() Defaults {
cfg := Config()
handlers := Handlers()
cfg.Credentials = CredChain(cfg, handlers)
return Defaults{
Config: cfg,
Handlers: handlers,
}
}
// Config returns the default configuration.
func Config() *aws.Config {
return aws.NewConfig().
WithCredentials(credentials.AnonymousCredentials).
WithRegion(os.Getenv("AWS_REGION")).
WithHTTPClient(http.DefaultClient).
WithMaxRetries(aws.UseServiceDefaultRetries).
WithLogger(aws.NewDefaultLogger()).
WithLogLevel(aws.LogOff).
WithSleepDelay(time.Sleep)
}
// Handlers returns the default request handlers.
func Handlers() request.Handlers {
var handlers request.Handlers
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
handlers.Send.PushBackNamed(corehandlers.SendHandler)
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
return handlers
}
// CredChain returns the default credential chain.
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true)
return credentials.NewChainCredentials(
[]credentials.Provider{
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
&ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion),
ExpiryWindow: 5 * time.Minute,
},
})
}
-43
View File
@@ -1,43 +0,0 @@
package ec2metadata
import (
"path"
"github.com/aws/aws-sdk-go/aws/request"
)
// GetMetadata uses the path provided to request
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
op := &request.Operation{
Name: "GetMetadata",
HTTPMethod: "GET",
HTTPPath: path.Join("/", "meta-data", p),
}
output := &metadataOutput{}
req := c.NewRequest(op, nil, output)
return output.Content, req.Send()
}
// Region returns the region the instance is running in.
func (c *EC2Metadata) Region() (string, error) {
resp, err := c.GetMetadata("placement/availability-zone")
if err != nil {
return "", err
}
// returns region without the suffix. Eg: us-west-2a becomes us-west-2
return resp[:len(resp)-1], nil
}
// Available returns if the application has access to the EC2 Metadata service.
// Can be used to determine if application is running within an EC2 Instance and
// the metadata service is available.
func (c *EC2Metadata) Available() bool {
if _, err := c.GetMetadata("instance-id"); err != nil {
return false
}
return true
}
@@ -1,101 +0,0 @@
package ec2metadata_test
import (
"bytes"
"io/ioutil"
"net/http"
"net/http/httptest"
"path"
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
)
func initTestServer(path string, resp string) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI != path {
http.Error(w, "not found", http.StatusNotFound)
return
}
w.Write([]byte(resp))
}))
}
func TestEndpoint(t *testing.T) {
c := ec2metadata.New(session.New())
op := &request.Operation{
Name: "GetMetadata",
HTTPMethod: "GET",
HTTPPath: path.Join("/", "meta-data", "testpath"),
}
req := c.NewRequest(op, nil, nil)
assert.Equal(t, "http://169.254.169.254/latest", req.ClientInfo.Endpoint)
assert.Equal(t, "http://169.254.169.254/latest/meta-data/testpath", req.HTTPRequest.URL.String())
}
func TestGetMetadata(t *testing.T) {
server := initTestServer(
"/latest/meta-data/some/path",
"success", // real response includes suffix
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
resp, err := c.GetMetadata("some/path")
assert.NoError(t, err)
assert.Equal(t, "success", resp)
}
func TestGetRegion(t *testing.T) {
server := initTestServer(
"/latest/meta-data/placement/availability-zone",
"us-west-2a", // real response includes suffix
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
region, err := c.Region()
assert.NoError(t, err)
assert.Equal(t, "us-west-2", region)
}
func TestMetadataAvailable(t *testing.T) {
server := initTestServer(
"/latest/meta-data/instance-id",
"instance-id",
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
available := c.Available()
assert.True(t, available)
}
func TestMetadataNotAvailable(t *testing.T) {
c := ec2metadata.New(session.New())
c.Handlers.Send.Clear()
c.Handlers.Send.PushBack(func(r *request.Request) {
r.HTTPResponse = &http.Response{
StatusCode: int(0),
Status: http.StatusText(int(0)),
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
}
r.Error = awserr.New("RequestError", "send request failed", nil)
r.Retryable = aws.Bool(true) // network errors are retryable
})
available := c.Available()
assert.False(t, available)
}
@@ -1,47 +0,0 @@
package request_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
)
func TestHandlerList(t *testing.T) {
s := ""
r := &request.Request{}
l := request.HandlerList{}
l.PushBack(func(r *request.Request) {
s += "a"
r.Data = s
})
l.Run(r)
assert.Equal(t, "a", s)
assert.Equal(t, "a", r.Data)
}
func TestMultipleHandlers(t *testing.T) {
r := &request.Request{}
l := request.HandlerList{}
l.PushBack(func(r *request.Request) { r.Data = nil })
l.PushFront(func(r *request.Request) { r.Data = aws.Bool(true) })
l.Run(r)
if r.Data != nil {
t.Error("Expected handler to execute")
}
}
func TestNamedHandlers(t *testing.T) {
l := request.HandlerList{}
named := request.NamedHandler{Name: "Name", Fn: func(r *request.Request) {}}
named2 := request.NamedHandler{Name: "NotName", Fn: func(r *request.Request) {}}
l.PushBackNamed(named)
l.PushBackNamed(named)
l.PushBackNamed(named2)
l.PushBack(func(r *request.Request) {})
assert.Equal(t, 4, l.Len())
l.Remove(named)
assert.Equal(t, 2, l.Len())
}
-105
View File
@@ -1,105 +0,0 @@
// Package session provides a way to create service clients with shared configuration
// and handlers.
package session
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/endpoints"
)
// A Session provides a central location to create service clients from and
// store configurations and request handlers for those services.
//
// Sessions are safe to create service clients concurrently, but it is not safe
// to mutate the session concurrently.
type Session struct {
Config *aws.Config
Handlers request.Handlers
}
// New creates a new instance of the handlers merging in the provided Configs
// on top of the SDK's default configurations. Once the session is created it
// can be mutated to modify Configs or Handlers. The session is safe to be read
// concurrently, but it should not be written to concurrently.
//
// Example:
// // Create a session with the default config and request handlers.
// sess := session.New()
//
// // Create a session with a custom region
// sess := session.New(&aws.Config{Region: aws.String("us-east-1")})
//
// // Create a session, and add additional handlers for all service
// // clients created with the session to inherit. Adds logging handler.
// sess := session.New()
// sess.Handlers.Send.PushFront(func(r *request.Request) {
// // Log every request made and its payload
// logger.Println("Request: %s/%s, Payload: %s", r.ClientInfo.ServiceName, r.Operation, r.Params)
// })
//
// // Create a S3 client instance from a session
// sess := session.New()
// svc := s3.New(sess)
func New(cfgs ...*aws.Config) *Session {
def := defaults.Get()
s := &Session{
Config: def.Config,
Handlers: def.Handlers,
}
s.Config.MergeIn(cfgs...)
initHandlers(s)
return s
}
func initHandlers(s *Session) {
// Add the Validate parameter handler if it is not disabled.
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
if !aws.BoolValue(s.Config.DisableParamValidation) {
s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
}
}
// Copy creates and returns a copy of the current session, coping the config
// and handlers. If any additional configs are provided they will be merged
// on top of the session's copied config.
//
// Example:
// // Create a copy of the current session, configured for the us-west-2 region.
// sess.Copy(&aws.Config{Region: aws.String("us-west-2"})
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
newSession := &Session{
Config: s.Config.Copy(cfgs...),
Handlers: s.Handlers.Copy(),
}
initHandlers(newSession)
return newSession
}
// ClientConfig satisfies the client.ConfigProvider interface and is used to
// configure the service client instances. Passing the Session to the service
// client's constructor (New) will use this method to configure the client.
//
// Example:
// sess := session.New()
// s3.New(sess)
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
s = s.Copy(cfgs...)
endpoint, signingRegion := endpoints.NormalizeEndpoint(
aws.StringValue(s.Config.Endpoint), serviceName,
aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL))
return client.Config{
Config: s.Config,
Handlers: s.Handlers,
Endpoint: endpoint,
SigningRegion: signingRegion,
}
}
@@ -1,20 +0,0 @@
package session_test
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
)
func TestNewDefaultSession(t *testing.T) {
s := session.New(&aws.Config{Region: aws.String("region")})
assert.Equal(t, "region", *s.Config.Region)
assert.Equal(t, http.DefaultClient, s.Config.HTTPClient)
assert.NotNil(t, s.Config.Logger)
assert.Equal(t, aws.LogOff, *s.Config.LogLevel)
}
@@ -1,31 +0,0 @@
// Package endpoints validates regional endpoints for services.
package endpoints
//go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go
//go:generate gofmt -s -w endpoints_map.go
import "strings"
// EndpointForRegion returns an endpoint and its signing region for a service and region.
// if the service and region pair are not found endpoint and signingRegion will be empty.
func EndpointForRegion(svcName, region string) (endpoint, signingRegion string) {
derivedKeys := []string{
region + "/" + svcName,
region + "/*",
"*/" + svcName,
"*/*",
}
for _, key := range derivedKeys {
if val, ok := endpointsMap.Endpoints[key]; ok {
ep := val.Endpoint
ep = strings.Replace(ep, "{region}", region, -1)
ep = strings.Replace(ep, "{service}", svcName, -1)
endpoint = ep
signingRegion = val.SigningRegion
return
}
}
return
}
@@ -1,89 +0,0 @@
package endpoints
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
type endpointStruct struct {
Version int
Endpoints map[string]endpointEntry
}
type endpointEntry struct {
Endpoint string
SigningRegion string
}
var endpointsMap = endpointStruct{
Version: 2,
Endpoints: map[string]endpointEntry{
"*/*": {
Endpoint: "{service}.{region}.amazonaws.com",
},
"*/cloudfront": {
Endpoint: "cloudfront.amazonaws.com",
SigningRegion: "us-east-1",
},
"*/cloudsearchdomain": {
Endpoint: "",
SigningRegion: "us-east-1",
},
"*/iam": {
Endpoint: "iam.amazonaws.com",
SigningRegion: "us-east-1",
},
"*/importexport": {
Endpoint: "importexport.amazonaws.com",
SigningRegion: "us-east-1",
},
"*/route53": {
Endpoint: "route53.amazonaws.com",
SigningRegion: "us-east-1",
},
"*/sts": {
Endpoint: "sts.amazonaws.com",
SigningRegion: "us-east-1",
},
"ap-northeast-1/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"ap-southeast-1/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"ap-southeast-2/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"cn-north-1/*": {
Endpoint: "{service}.{region}.amazonaws.com.cn",
},
"eu-central-1/s3": {
Endpoint: "{service}.{region}.amazonaws.com",
},
"eu-west-1/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"sa-east-1/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"us-east-1/s3": {
Endpoint: "s3.amazonaws.com",
},
"us-east-1/sdb": {
Endpoint: "sdb.amazonaws.com",
SigningRegion: "us-east-1",
},
"us-gov-west-1/iam": {
Endpoint: "iam.us-gov.amazonaws.com",
},
"us-gov-west-1/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"us-gov-west-1/sts": {
Endpoint: "sts.us-gov-west-1.amazonaws.com",
},
"us-west-1/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
"us-west-2/s3": {
Endpoint: "s3-{region}.amazonaws.com",
},
},
}
@@ -1,28 +0,0 @@
package endpoints
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGlobalEndpoints(t *testing.T) {
region := "mock-region-1"
svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts"}
for _, name := range svcs {
ep, sr := EndpointForRegion(name, region)
assert.Equal(t, name+".amazonaws.com", ep)
assert.Equal(t, "us-east-1", sr)
}
}
func TestServicesInCN(t *testing.T) {
region := "cn-north-1"
svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts", "s3"}
for _, name := range svcs {
ep, _ := EndpointForRegion(name, region)
assert.Equal(t, name+"."+region+".amazonaws.com.cn", ep)
}
}
@@ -1,32 +0,0 @@
// Package ec2query provides serialisation of AWS EC2 requests and responses.
package ec2query
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/ec2.json build_test.go
import (
"net/url"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/internal/protocol/query/queryutil"
)
// Build builds a request for the EC2 protocol.
func Build(r *aws.Request) {
body := url.Values{
"Action": {r.Operation.Name},
"Version": {r.Service.APIVersion},
}
if err := queryutil.Parse(body, r.Params, true); err != nil {
r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err)
}
if r.ExpireTime == 0 {
r.HTTPRequest.Method = "POST"
r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
r.SetBufferBody([]byte(body.Encode()))
} else { // This is a pre-signed request
r.HTTPRequest.Method = "GET"
r.HTTPRequest.URL.RawQuery = body.Encode()
}
}
@@ -1,860 +0,0 @@
package ec2query_test
import (
"bytes"
"encoding/json"
"encoding/xml"
"io"
"io/ioutil"
"net/http"
"net/url"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/internal/protocol/ec2query"
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
"github.com/aws/aws-sdk-go/internal/signer/v4"
"github.com/aws/aws-sdk-go/internal/util"
"github.com/stretchr/testify/assert"
)
var _ bytes.Buffer // always import bytes
var _ http.Request
var _ json.Marshaler
var _ time.Time
var _ xmlutil.XMLNode
var _ xml.Attr
var _ = ioutil.Discard
var _ = util.Trim("")
var _ = url.Values{}
var _ = io.EOF
type InputService1ProtocolTest struct {
*aws.Service
}
// New returns a new InputService1ProtocolTest client.
func NewInputService1ProtocolTest(config *aws.Config) *InputService1ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice1protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService1ProtocolTest{service}
}
// newRequest creates a new request for a InputService1ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService1TestCaseOperation1 = "OperationName"
// InputService1TestCaseOperation1Request generates a request for the InputService1TestCaseOperation1 operation.
func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input *InputService1TestShapeInputShape) (req *aws.Request, output *InputService1TestShapeInputService1TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService1TestCaseOperation1,
}
if input == nil {
input = &InputService1TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService1TestShapeInputService1TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService1ProtocolTest) InputService1TestCaseOperation1(input *InputService1TestShapeInputShape) (*InputService1TestShapeInputService1TestCaseOperation1Output, error) {
req, out := c.InputService1TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService1TestShapeInputService1TestCaseOperation1Output struct {
metadataInputService1TestShapeInputService1TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService1TestShapeInputService1TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService1TestShapeInputShape struct {
Bar *string `type:"string"`
Foo *string `type:"string"`
metadataInputService1TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService1TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService2ProtocolTest struct {
*aws.Service
}
// New returns a new InputService2ProtocolTest client.
func NewInputService2ProtocolTest(config *aws.Config) *InputService2ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice2protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService2ProtocolTest{service}
}
// newRequest creates a new request for a InputService2ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService2TestCaseOperation1 = "OperationName"
// InputService2TestCaseOperation1Request generates a request for the InputService2TestCaseOperation1 operation.
func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input *InputService2TestShapeInputShape) (req *aws.Request, output *InputService2TestShapeInputService2TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService2TestCaseOperation1,
}
if input == nil {
input = &InputService2TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService2TestShapeInputService2TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService2ProtocolTest) InputService2TestCaseOperation1(input *InputService2TestShapeInputShape) (*InputService2TestShapeInputService2TestCaseOperation1Output, error) {
req, out := c.InputService2TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService2TestShapeInputService2TestCaseOperation1Output struct {
metadataInputService2TestShapeInputService2TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService2TestShapeInputService2TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService2TestShapeInputShape struct {
Bar *string `locationName:"barLocationName" type:"string"`
Foo *string `type:"string"`
Yuck *string `locationName:"yuckLocationName" queryName:"yuckQueryName" type:"string"`
metadataInputService2TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService2TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService3ProtocolTest struct {
*aws.Service
}
// New returns a new InputService3ProtocolTest client.
func NewInputService3ProtocolTest(config *aws.Config) *InputService3ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice3protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService3ProtocolTest{service}
}
// newRequest creates a new request for a InputService3ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService3TestCaseOperation1 = "OperationName"
// InputService3TestCaseOperation1Request generates a request for the InputService3TestCaseOperation1 operation.
func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input *InputService3TestShapeInputShape) (req *aws.Request, output *InputService3TestShapeInputService3TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService3TestCaseOperation1,
}
if input == nil {
input = &InputService3TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService3TestShapeInputService3TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService3ProtocolTest) InputService3TestCaseOperation1(input *InputService3TestShapeInputShape) (*InputService3TestShapeInputService3TestCaseOperation1Output, error) {
req, out := c.InputService3TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService3TestShapeInputService3TestCaseOperation1Output struct {
metadataInputService3TestShapeInputService3TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService3TestShapeInputService3TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService3TestShapeInputShape struct {
StructArg *InputService3TestShapeStructType `locationName:"Struct" type:"structure"`
metadataInputService3TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService3TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService3TestShapeStructType struct {
ScalarArg *string `locationName:"Scalar" type:"string"`
metadataInputService3TestShapeStructType `json:"-" xml:"-"`
}
type metadataInputService3TestShapeStructType struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService4ProtocolTest struct {
*aws.Service
}
// New returns a new InputService4ProtocolTest client.
func NewInputService4ProtocolTest(config *aws.Config) *InputService4ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice4protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService4ProtocolTest{service}
}
// newRequest creates a new request for a InputService4ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService4TestCaseOperation1 = "OperationName"
// InputService4TestCaseOperation1Request generates a request for the InputService4TestCaseOperation1 operation.
func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input *InputService4TestShapeInputShape) (req *aws.Request, output *InputService4TestShapeInputService4TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService4TestCaseOperation1,
}
if input == nil {
input = &InputService4TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService4TestShapeInputService4TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService4ProtocolTest) InputService4TestCaseOperation1(input *InputService4TestShapeInputShape) (*InputService4TestShapeInputService4TestCaseOperation1Output, error) {
req, out := c.InputService4TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService4TestShapeInputService4TestCaseOperation1Output struct {
metadataInputService4TestShapeInputService4TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService4TestShapeInputService4TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService4TestShapeInputShape struct {
ListArg []*string `type:"list"`
metadataInputService4TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService4TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService5ProtocolTest struct {
*aws.Service
}
// New returns a new InputService5ProtocolTest client.
func NewInputService5ProtocolTest(config *aws.Config) *InputService5ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice5protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService5ProtocolTest{service}
}
// newRequest creates a new request for a InputService5ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService5TestCaseOperation1 = "OperationName"
// InputService5TestCaseOperation1Request generates a request for the InputService5TestCaseOperation1 operation.
func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input *InputService5TestShapeInputShape) (req *aws.Request, output *InputService5TestShapeInputService5TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService5TestCaseOperation1,
}
if input == nil {
input = &InputService5TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService5TestShapeInputService5TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService5ProtocolTest) InputService5TestCaseOperation1(input *InputService5TestShapeInputShape) (*InputService5TestShapeInputService5TestCaseOperation1Output, error) {
req, out := c.InputService5TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService5TestShapeInputService5TestCaseOperation1Output struct {
metadataInputService5TestShapeInputService5TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService5TestShapeInputService5TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService5TestShapeInputShape struct {
ListArg []*string `locationName:"ListMemberName" locationNameList:"item" type:"list"`
metadataInputService5TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService5TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService6ProtocolTest struct {
*aws.Service
}
// New returns a new InputService6ProtocolTest client.
func NewInputService6ProtocolTest(config *aws.Config) *InputService6ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice6protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService6ProtocolTest{service}
}
// newRequest creates a new request for a InputService6ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService6TestCaseOperation1 = "OperationName"
// InputService6TestCaseOperation1Request generates a request for the InputService6TestCaseOperation1 operation.
func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input *InputService6TestShapeInputShape) (req *aws.Request, output *InputService6TestShapeInputService6TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService6TestCaseOperation1,
}
if input == nil {
input = &InputService6TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService6TestShapeInputService6TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService6ProtocolTest) InputService6TestCaseOperation1(input *InputService6TestShapeInputShape) (*InputService6TestShapeInputService6TestCaseOperation1Output, error) {
req, out := c.InputService6TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService6TestShapeInputService6TestCaseOperation1Output struct {
metadataInputService6TestShapeInputService6TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService6TestShapeInputService6TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService6TestShapeInputShape struct {
ListArg []*string `locationName:"ListMemberName" queryName:"ListQueryName" locationNameList:"item" type:"list"`
metadataInputService6TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService6TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService7ProtocolTest struct {
*aws.Service
}
// New returns a new InputService7ProtocolTest client.
func NewInputService7ProtocolTest(config *aws.Config) *InputService7ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice7protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService7ProtocolTest{service}
}
// newRequest creates a new request for a InputService7ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService7TestCaseOperation1 = "OperationName"
// InputService7TestCaseOperation1Request generates a request for the InputService7TestCaseOperation1 operation.
func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input *InputService7TestShapeInputShape) (req *aws.Request, output *InputService7TestShapeInputService7TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService7TestCaseOperation1,
}
if input == nil {
input = &InputService7TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService7TestShapeInputService7TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService7ProtocolTest) InputService7TestCaseOperation1(input *InputService7TestShapeInputShape) (*InputService7TestShapeInputService7TestCaseOperation1Output, error) {
req, out := c.InputService7TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService7TestShapeInputService7TestCaseOperation1Output struct {
metadataInputService7TestShapeInputService7TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService7TestShapeInputService7TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService7TestShapeInputShape struct {
BlobArg []byte `type:"blob"`
metadataInputService7TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService7TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService8ProtocolTest struct {
*aws.Service
}
// New returns a new InputService8ProtocolTest client.
func NewInputService8ProtocolTest(config *aws.Config) *InputService8ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "inputservice8protocoltest",
APIVersion: "2014-01-01",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &InputService8ProtocolTest{service}
}
// newRequest creates a new request for a InputService8ProtocolTest operation and runs any
// custom request initialization.
func (c *InputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opInputService8TestCaseOperation1 = "OperationName"
// InputService8TestCaseOperation1Request generates a request for the InputService8TestCaseOperation1 operation.
func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input *InputService8TestShapeInputShape) (req *aws.Request, output *InputService8TestShapeInputService8TestCaseOperation1Output) {
op := &aws.Operation{
Name: opInputService8TestCaseOperation1,
}
if input == nil {
input = &InputService8TestShapeInputShape{}
}
req = c.newRequest(op, input, output)
output = &InputService8TestShapeInputService8TestCaseOperation1Output{}
req.Data = output
return
}
func (c *InputService8ProtocolTest) InputService8TestCaseOperation1(input *InputService8TestShapeInputShape) (*InputService8TestShapeInputService8TestCaseOperation1Output, error) {
req, out := c.InputService8TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type InputService8TestShapeInputService8TestCaseOperation1Output struct {
metadataInputService8TestShapeInputService8TestCaseOperation1Output `json:"-" xml:"-"`
}
type metadataInputService8TestShapeInputService8TestCaseOperation1Output struct {
SDKShapeTraits bool `type:"structure"`
}
type InputService8TestShapeInputShape struct {
TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"`
metadataInputService8TestShapeInputShape `json:"-" xml:"-"`
}
type metadataInputService8TestShapeInputShape struct {
SDKShapeTraits bool `type:"structure"`
}
//
// Tests begin here
//
func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) {
svc := NewInputService1ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService1TestShapeInputShape{
Bar: aws.String("val2"),
Foo: aws.String("val1"),
}
req, _ := svc.InputService1TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&Bar=val2&Foo=val1&Version=2014-01-01`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
func TestInputService2ProtocolTestStructureWithLocationNameAndQueryNameAppliedToMembersCase1(t *testing.T) {
svc := NewInputService2ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService2TestShapeInputShape{
Bar: aws.String("val2"),
Foo: aws.String("val1"),
Yuck: aws.String("val3"),
}
req, _ := svc.InputService2TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&BarLocationName=val2&Foo=val1&Version=2014-01-01&yuckQueryName=val3`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
func TestInputService3ProtocolTestNestedStructureMembersCase1(t *testing.T) {
svc := NewInputService3ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService3TestShapeInputShape{
StructArg: &InputService3TestShapeStructType{
ScalarArg: aws.String("foo"),
},
}
req, _ := svc.InputService3TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&Struct.Scalar=foo&Version=2014-01-01`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
func TestInputService4ProtocolTestListTypesCase1(t *testing.T) {
svc := NewInputService4ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService4TestShapeInputShape{
ListArg: []*string{
aws.String("foo"),
aws.String("bar"),
aws.String("baz"),
},
}
req, _ := svc.InputService4TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&ListArg.1=foo&ListArg.2=bar&ListArg.3=baz&Version=2014-01-01`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
func TestInputService5ProtocolTestListWithLocationNameAppliedToMemberCase1(t *testing.T) {
svc := NewInputService5ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService5TestShapeInputShape{
ListArg: []*string{
aws.String("a"),
aws.String("b"),
aws.String("c"),
},
}
req, _ := svc.InputService5TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&ListMemberName.1=a&ListMemberName.2=b&ListMemberName.3=c&Version=2014-01-01`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
func TestInputService6ProtocolTestListWithLocationNameAndQueryNameCase1(t *testing.T) {
svc := NewInputService6ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService6TestShapeInputShape{
ListArg: []*string{
aws.String("a"),
aws.String("b"),
aws.String("c"),
},
}
req, _ := svc.InputService6TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&ListQueryName.1=a&ListQueryName.2=b&ListQueryName.3=c&Version=2014-01-01`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
svc := NewInputService7ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService7TestShapeInputShape{
BlobArg: []byte("foo"),
}
req, _ := svc.InputService7TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&BlobArg=Zm9v&Version=2014-01-01`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
svc := NewInputService8ProtocolTest(nil)
svc.Endpoint = "https://test"
input := &InputService8TestShapeInputShape{
TimeArg: aws.Time(time.Unix(1422172800, 0)),
}
req, _ := svc.InputService8TestCaseOperation1Request(input)
r := req.HTTPRequest
// build request
ec2query.Build(req)
assert.NoError(t, req.Error)
// assert body
assert.NotNil(t, r.Body)
body, _ := ioutil.ReadAll(r.Body)
assert.Equal(t, util.Trim(`Action=OperationName&TimeArg=2015-01-25T08%3A00%3A00Z&Version=2014-01-01`), util.Trim(string(body)))
// assert URL
assert.Equal(t, "https://test/", r.URL.String())
// assert headers
}
@@ -1,54 +0,0 @@
package ec2query
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/ec2.json unmarshal_test.go
import (
"encoding/xml"
"io"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
)
// Unmarshal unmarshals a response body for the EC2 protocol.
func Unmarshal(r *aws.Request) {
defer r.HTTPResponse.Body.Close()
if r.DataFilled() {
decoder := xml.NewDecoder(r.HTTPResponse.Body)
err := xmlutil.UnmarshalXML(r.Data, decoder, "")
if err != nil {
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err)
return
}
}
}
// UnmarshalMeta unmarshals response headers for the EC2 protocol.
func UnmarshalMeta(r *aws.Request) {
// TODO implement unmarshaling of request IDs
}
type xmlErrorResponse struct {
XMLName xml.Name `xml:"Response"`
Code string `xml:"Errors>Error>Code"`
Message string `xml:"Errors>Error>Message"`
RequestID string `xml:"RequestId"`
}
// UnmarshalError unmarshals a response error for the EC2 protocol.
func UnmarshalError(r *aws.Request) {
defer r.HTTPResponse.Body.Close()
resp := &xmlErrorResponse{}
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
if err != nil && err != io.EOF {
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err)
} else {
r.Error = awserr.NewRequestFailure(
awserr.New(resp.Code, resp.Message, nil),
r.HTTPResponse.StatusCode,
resp.RequestID,
)
}
}
@@ -1,816 +0,0 @@
package ec2query_test
import (
"bytes"
"encoding/json"
"encoding/xml"
"io"
"io/ioutil"
"net/http"
"net/url"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/internal/protocol/ec2query"
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
"github.com/aws/aws-sdk-go/internal/signer/v4"
"github.com/aws/aws-sdk-go/internal/util"
"github.com/stretchr/testify/assert"
)
var _ bytes.Buffer // always import bytes
var _ http.Request
var _ json.Marshaler
var _ time.Time
var _ xmlutil.XMLNode
var _ xml.Attr
var _ = ioutil.Discard
var _ = util.Trim("")
var _ = url.Values{}
var _ = io.EOF
type OutputService1ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService1ProtocolTest client.
func NewOutputService1ProtocolTest(config *aws.Config) *OutputService1ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice1protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService1ProtocolTest{service}
}
// newRequest creates a new request for a OutputService1ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService1ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService1TestCaseOperation1 = "OperationName"
// OutputService1TestCaseOperation1Request generates a request for the OutputService1TestCaseOperation1 operation.
func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1Request(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (req *aws.Request, output *OutputService1TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService1TestCaseOperation1,
}
if input == nil {
input = &OutputService1TestShapeOutputService1TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService1TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService1ProtocolTest) OutputService1TestCaseOperation1(input *OutputService1TestShapeOutputService1TestCaseOperation1Input) (*OutputService1TestShapeOutputShape, error) {
req, out := c.OutputService1TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService1TestShapeOutputService1TestCaseOperation1Input struct {
metadataOutputService1TestShapeOutputService1TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService1TestShapeOutputService1TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService1TestShapeOutputShape struct {
Char *string `type:"character"`
Double *float64 `type:"double"`
FalseBool *bool `type:"boolean"`
Float *float64 `type:"float"`
Long *int64 `type:"long"`
Num *int64 `locationName:"FooNum" type:"integer"`
Str *string `type:"string"`
TrueBool *bool `type:"boolean"`
metadataOutputService1TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService1TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService2ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService2ProtocolTest client.
func NewOutputService2ProtocolTest(config *aws.Config) *OutputService2ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice2protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService2ProtocolTest{service}
}
// newRequest creates a new request for a OutputService2ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService2ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService2TestCaseOperation1 = "OperationName"
// OutputService2TestCaseOperation1Request generates a request for the OutputService2TestCaseOperation1 operation.
func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1Request(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (req *aws.Request, output *OutputService2TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService2TestCaseOperation1,
}
if input == nil {
input = &OutputService2TestShapeOutputService2TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService2TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService2ProtocolTest) OutputService2TestCaseOperation1(input *OutputService2TestShapeOutputService2TestCaseOperation1Input) (*OutputService2TestShapeOutputShape, error) {
req, out := c.OutputService2TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService2TestShapeOutputService2TestCaseOperation1Input struct {
metadataOutputService2TestShapeOutputService2TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService2TestShapeOutputService2TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService2TestShapeOutputShape struct {
Blob []byte `type:"blob"`
metadataOutputService2TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService2TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService3ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService3ProtocolTest client.
func NewOutputService3ProtocolTest(config *aws.Config) *OutputService3ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice3protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService3ProtocolTest{service}
}
// newRequest creates a new request for a OutputService3ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService3ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService3TestCaseOperation1 = "OperationName"
// OutputService3TestCaseOperation1Request generates a request for the OutputService3TestCaseOperation1 operation.
func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1Request(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (req *aws.Request, output *OutputService3TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService3TestCaseOperation1,
}
if input == nil {
input = &OutputService3TestShapeOutputService3TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService3TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService3ProtocolTest) OutputService3TestCaseOperation1(input *OutputService3TestShapeOutputService3TestCaseOperation1Input) (*OutputService3TestShapeOutputShape, error) {
req, out := c.OutputService3TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService3TestShapeOutputService3TestCaseOperation1Input struct {
metadataOutputService3TestShapeOutputService3TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService3TestShapeOutputService3TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService3TestShapeOutputShape struct {
ListMember []*string `type:"list"`
metadataOutputService3TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService3TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService4ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService4ProtocolTest client.
func NewOutputService4ProtocolTest(config *aws.Config) *OutputService4ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice4protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService4ProtocolTest{service}
}
// newRequest creates a new request for a OutputService4ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService4ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService4TestCaseOperation1 = "OperationName"
// OutputService4TestCaseOperation1Request generates a request for the OutputService4TestCaseOperation1 operation.
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *aws.Request, output *OutputService4TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService4TestCaseOperation1,
}
if input == nil {
input = &OutputService4TestShapeOutputService4TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService4TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputShape, error) {
req, out := c.OutputService4TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService4TestShapeOutputService4TestCaseOperation1Input struct {
metadataOutputService4TestShapeOutputService4TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService4TestShapeOutputService4TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService4TestShapeOutputShape struct {
ListMember []*string `locationNameList:"item" type:"list"`
metadataOutputService4TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService4TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService5ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService5ProtocolTest client.
func NewOutputService5ProtocolTest(config *aws.Config) *OutputService5ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice5protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService5ProtocolTest{service}
}
// newRequest creates a new request for a OutputService5ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService5ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService5TestCaseOperation1 = "OperationName"
// OutputService5TestCaseOperation1Request generates a request for the OutputService5TestCaseOperation1 operation.
func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1Request(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (req *aws.Request, output *OutputService5TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService5TestCaseOperation1,
}
if input == nil {
input = &OutputService5TestShapeOutputService5TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService5TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService5ProtocolTest) OutputService5TestCaseOperation1(input *OutputService5TestShapeOutputService5TestCaseOperation1Input) (*OutputService5TestShapeOutputShape, error) {
req, out := c.OutputService5TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService5TestShapeOutputService5TestCaseOperation1Input struct {
metadataOutputService5TestShapeOutputService5TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService5TestShapeOutputService5TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService5TestShapeOutputShape struct {
ListMember []*string `type:"list" flattened:"true"`
metadataOutputService5TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService5TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService6ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService6ProtocolTest client.
func NewOutputService6ProtocolTest(config *aws.Config) *OutputService6ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice6protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService6ProtocolTest{service}
}
// newRequest creates a new request for a OutputService6ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService6ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService6TestCaseOperation1 = "OperationName"
// OutputService6TestCaseOperation1Request generates a request for the OutputService6TestCaseOperation1 operation.
func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1Request(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (req *aws.Request, output *OutputService6TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService6TestCaseOperation1,
}
if input == nil {
input = &OutputService6TestShapeOutputService6TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService6TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService6ProtocolTest) OutputService6TestCaseOperation1(input *OutputService6TestShapeOutputService6TestCaseOperation1Input) (*OutputService6TestShapeOutputShape, error) {
req, out := c.OutputService6TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService6TestShapeOutputService6TestCaseOperation1Input struct {
metadataOutputService6TestShapeOutputService6TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService6TestShapeOutputService6TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService6TestShapeOutputShape struct {
Map map[string]*OutputService6TestShapeStructureType `type:"map"`
metadataOutputService6TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService6TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService6TestShapeStructureType struct {
Foo *string `locationName:"foo" type:"string"`
metadataOutputService6TestShapeStructureType `json:"-" xml:"-"`
}
type metadataOutputService6TestShapeStructureType struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService7ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService7ProtocolTest client.
func NewOutputService7ProtocolTest(config *aws.Config) *OutputService7ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice7protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService7ProtocolTest{service}
}
// newRequest creates a new request for a OutputService7ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService7ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService7TestCaseOperation1 = "OperationName"
// OutputService7TestCaseOperation1Request generates a request for the OutputService7TestCaseOperation1 operation.
func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1Request(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (req *aws.Request, output *OutputService7TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService7TestCaseOperation1,
}
if input == nil {
input = &OutputService7TestShapeOutputService7TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService7TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService7ProtocolTest) OutputService7TestCaseOperation1(input *OutputService7TestShapeOutputService7TestCaseOperation1Input) (*OutputService7TestShapeOutputShape, error) {
req, out := c.OutputService7TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService7TestShapeOutputService7TestCaseOperation1Input struct {
metadataOutputService7TestShapeOutputService7TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService7TestShapeOutputService7TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService7TestShapeOutputShape struct {
Map map[string]*string `type:"map" flattened:"true"`
metadataOutputService7TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService7TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService8ProtocolTest struct {
*aws.Service
}
// New returns a new OutputService8ProtocolTest client.
func NewOutputService8ProtocolTest(config *aws.Config) *OutputService8ProtocolTest {
service := &aws.Service{
Config: aws.DefaultConfig.Merge(config),
ServiceName: "outputservice8protocoltest",
APIVersion: "",
}
service.Initialize()
// Handlers
service.Handlers.Sign.PushBack(v4.Sign)
service.Handlers.Build.PushBack(ec2query.Build)
service.Handlers.Unmarshal.PushBack(ec2query.Unmarshal)
service.Handlers.UnmarshalMeta.PushBack(ec2query.UnmarshalMeta)
service.Handlers.UnmarshalError.PushBack(ec2query.UnmarshalError)
return &OutputService8ProtocolTest{service}
}
// newRequest creates a new request for a OutputService8ProtocolTest operation and runs any
// custom request initialization.
func (c *OutputService8ProtocolTest) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
req := aws.NewRequest(c.Service, op, params, data)
return req
}
const opOutputService8TestCaseOperation1 = "OperationName"
// OutputService8TestCaseOperation1Request generates a request for the OutputService8TestCaseOperation1 operation.
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1Request(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (req *aws.Request, output *OutputService8TestShapeOutputShape) {
op := &aws.Operation{
Name: opOutputService8TestCaseOperation1,
}
if input == nil {
input = &OutputService8TestShapeOutputService8TestCaseOperation1Input{}
}
req = c.newRequest(op, input, output)
output = &OutputService8TestShapeOutputShape{}
req.Data = output
return
}
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (*OutputService8TestShapeOutputShape, error) {
req, out := c.OutputService8TestCaseOperation1Request(input)
err := req.Send()
return out, err
}
type OutputService8TestShapeOutputService8TestCaseOperation1Input struct {
metadataOutputService8TestShapeOutputService8TestCaseOperation1Input `json:"-" xml:"-"`
}
type metadataOutputService8TestShapeOutputService8TestCaseOperation1Input struct {
SDKShapeTraits bool `type:"structure"`
}
type OutputService8TestShapeOutputShape struct {
Map map[string]*string `locationNameKey:"foo" locationNameValue:"bar" type:"map" flattened:"true"`
metadataOutputService8TestShapeOutputShape `json:"-" xml:"-"`
}
type metadataOutputService8TestShapeOutputShape struct {
SDKShapeTraits bool `type:"structure"`
}
//
// Tests begin here
//
func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
svc := NewOutputService1ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><Str>myname</Str><FooNum>123</FooNum><FalseBool>false</FalseBool><TrueBool>true</TrueBool><Float>1.2</Float><Double>1.3</Double><Long>200</Long><Char>a</Char><RequestId>request-id</RequestId></OperationNameResponse>"))
req, out := svc.OutputService1TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "a", *out.Char)
assert.Equal(t, 1.3, *out.Double)
assert.Equal(t, false, *out.FalseBool)
assert.Equal(t, 1.2, *out.Float)
assert.Equal(t, int64(200), *out.Long)
assert.Equal(t, int64(123), *out.Num)
assert.Equal(t, "myname", *out.Str)
assert.Equal(t, true, *out.TrueBool)
}
func TestOutputService2ProtocolTestBlobCase1(t *testing.T) {
svc := NewOutputService2ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><Blob>dmFsdWU=</Blob><RequestId>requestid</RequestId></OperationNameResponse>"))
req, out := svc.OutputService2TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "value", string(out.Blob))
}
func TestOutputService3ProtocolTestListsCase1(t *testing.T) {
svc := NewOutputService3ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember><member>abc</member><member>123</member></ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
req, out := svc.OutputService3TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "abc", *out.ListMember[0])
assert.Equal(t, "123", *out.ListMember[1])
}
func TestOutputService4ProtocolTestListWithCustomMemberNameCase1(t *testing.T) {
svc := NewOutputService4ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember><item>abc</item><item>123</item></ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
req, out := svc.OutputService4TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "abc", *out.ListMember[0])
assert.Equal(t, "123", *out.ListMember[1])
}
func TestOutputService5ProtocolTestFlattenedListCase1(t *testing.T) {
svc := NewOutputService5ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><ListMember>abc</ListMember><ListMember>123</ListMember><RequestId>requestid</RequestId></OperationNameResponse>"))
req, out := svc.OutputService5TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "abc", *out.ListMember[0])
assert.Equal(t, "123", *out.ListMember[1])
}
func TestOutputService6ProtocolTestNormalMapCase1(t *testing.T) {
svc := NewOutputService6ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><Map><entry><key>qux</key><value><foo>bar</foo></value></entry><entry><key>baz</key><value><foo>bam</foo></value></entry></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
req, out := svc.OutputService6TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "bam", *out.Map["baz"].Foo)
assert.Equal(t, "bar", *out.Map["qux"].Foo)
}
func TestOutputService7ProtocolTestFlattenedMapCase1(t *testing.T) {
svc := NewOutputService7ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><Map><key>qux</key><value>bar</value></Map><Map><key>baz</key><value>bam</value></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
req, out := svc.OutputService7TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "bam", *out.Map["baz"])
assert.Equal(t, "bar", *out.Map["qux"])
}
func TestOutputService8ProtocolTestNamedMapCase1(t *testing.T) {
svc := NewOutputService8ProtocolTest(nil)
buf := bytes.NewReader([]byte("<OperationNameResponse><Map><foo>qux</foo><bar>bar</bar></Map><Map><foo>baz</foo><bar>bam</bar></Map><RequestId>requestid</RequestId></OperationNameResponse>"))
req, out := svc.OutputService8TestCaseOperation1Request(nil)
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
// set headers
// unmarshal response
ec2query.UnmarshalMeta(req)
ec2query.Unmarshal(req)
assert.NoError(t, req.Error)
// assert response
assert.NotNil(t, out) // ensure out variable is used
assert.Equal(t, "bam", *out.Map["baz"])
assert.Equal(t, "bar", *out.Map["qux"])
}
@@ -1,33 +0,0 @@
// Package query provides serialisation of AWS query requests, and responses.
package query
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/query.json build_test.go
import (
"net/url"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/internal/protocol/query/queryutil"
)
// Build builds a request for an AWS Query service.
func Build(r *aws.Request) {
body := url.Values{
"Action": {r.Operation.Name},
"Version": {r.Service.APIVersion},
}
if err := queryutil.Parse(body, r.Params, false); err != nil {
r.Error = awserr.New("SerializationError", "failed encoding Query request", err)
return
}
if r.ExpireTime == 0 {
r.HTTPRequest.Method = "POST"
r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
r.SetBufferBody([]byte(body.Encode()))
} else { // This is a pre-signed request
r.HTTPRequest.Method = "GET"
r.HTTPRequest.URL.RawQuery = body.Encode()
}
}
File diff suppressed because it is too large Load Diff
@@ -1,223 +0,0 @@
package queryutil
import (
"encoding/base64"
"fmt"
"net/url"
"reflect"
"sort"
"strconv"
"strings"
"time"
)
// Parse parses an object i and fills a url.Values object. The isEC2 flag
// indicates if this is the EC2 Query sub-protocol.
func Parse(body url.Values, i interface{}, isEC2 bool) error {
q := queryParser{isEC2: isEC2}
return q.parseValue(body, reflect.ValueOf(i), "", "")
}
func elemOf(value reflect.Value) reflect.Value {
for value.Kind() == reflect.Ptr {
value = value.Elem()
}
return value
}
type queryParser struct {
isEC2 bool
}
func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
value = elemOf(value)
// no need to handle zero values
if !value.IsValid() {
return nil
}
t := tag.Get("type")
if t == "" {
switch value.Kind() {
case reflect.Struct:
t = "structure"
case reflect.Slice:
t = "list"
case reflect.Map:
t = "map"
}
}
switch t {
case "structure":
return q.parseStruct(v, value, prefix)
case "list":
return q.parseList(v, value, prefix, tag)
case "map":
return q.parseMap(v, value, prefix, tag)
default:
return q.parseScalar(v, value, prefix, tag)
}
}
func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error {
if !value.IsValid() {
return nil
}
t := value.Type()
for i := 0; i < value.NumField(); i++ {
if c := t.Field(i).Name[0:1]; strings.ToLower(c) == c {
continue // ignore unexported fields
}
value := elemOf(value.Field(i))
field := t.Field(i)
var name string
if q.isEC2 {
name = field.Tag.Get("queryName")
}
if name == "" {
if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
name = field.Tag.Get("locationNameList")
} else if locName := field.Tag.Get("locationName"); locName != "" {
name = locName
}
if name != "" && q.isEC2 {
name = strings.ToUpper(name[0:1]) + name[1:]
}
}
if name == "" {
name = field.Name
}
if prefix != "" {
name = prefix + "." + name
}
if err := q.parseValue(v, value, name, field.Tag); err != nil {
return err
}
}
return nil
}
func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
// If it's empty, generate an empty value
if !value.IsNil() && value.Len() == 0 {
v.Set(prefix, "")
return nil
}
// check for unflattened list member
if !q.isEC2 && tag.Get("flattened") == "" {
prefix += ".member"
}
for i := 0; i < value.Len(); i++ {
slicePrefix := prefix
if slicePrefix == "" {
slicePrefix = strconv.Itoa(i + 1)
} else {
slicePrefix = slicePrefix + "." + strconv.Itoa(i+1)
}
if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil {
return err
}
}
return nil
}
func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
// If it's empty, generate an empty value
if !value.IsNil() && value.Len() == 0 {
v.Set(prefix, "")
return nil
}
// check for unflattened list member
if !q.isEC2 && tag.Get("flattened") == "" {
prefix += ".entry"
}
// sort keys for improved serialization consistency.
// this is not strictly necessary for protocol support.
mapKeyValues := value.MapKeys()
mapKeys := map[string]reflect.Value{}
mapKeyNames := make([]string, len(mapKeyValues))
for i, mapKey := range mapKeyValues {
name := mapKey.String()
mapKeys[name] = mapKey
mapKeyNames[i] = name
}
sort.Strings(mapKeyNames)
for i, mapKeyName := range mapKeyNames {
mapKey := mapKeys[mapKeyName]
mapValue := value.MapIndex(mapKey)
kname := tag.Get("locationNameKey")
if kname == "" {
kname = "key"
}
vname := tag.Get("locationNameValue")
if vname == "" {
vname = "value"
}
// serialize key
var keyName string
if prefix == "" {
keyName = strconv.Itoa(i+1) + "." + kname
} else {
keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname
}
if err := q.parseValue(v, mapKey, keyName, ""); err != nil {
return err
}
// serialize value
var valueName string
if prefix == "" {
valueName = strconv.Itoa(i+1) + "." + vname
} else {
valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname
}
if err := q.parseValue(v, mapValue, valueName, ""); err != nil {
return err
}
}
return nil
}
func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error {
switch value := r.Interface().(type) {
case string:
v.Set(name, value)
case []byte:
if !r.IsNil() {
v.Set(name, base64.StdEncoding.EncodeToString(value))
}
case bool:
v.Set(name, strconv.FormatBool(value))
case int64:
v.Set(name, strconv.FormatInt(value, 10))
case int:
v.Set(name, strconv.Itoa(value))
case float64:
v.Set(name, strconv.FormatFloat(value, 'f', -1, 64))
case float32:
v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32))
case time.Time:
const ISO8601UTC = "2006-01-02T15:04:05Z"
v.Set(name, value.UTC().Format(ISO8601UTC))
default:
return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
}
return nil
}
@@ -1,29 +0,0 @@
package query
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/query.json unmarshal_test.go
import (
"encoding/xml"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil"
)
// Unmarshal unmarshals a response for an AWS Query service.
func Unmarshal(r *aws.Request) {
defer r.HTTPResponse.Body.Close()
if r.DataFilled() {
decoder := xml.NewDecoder(r.HTTPResponse.Body)
err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result")
if err != nil {
r.Error = awserr.New("SerializationError", "failed decoding Query response", err)
return
}
}
}
// UnmarshalMeta unmarshals header response values for an AWS Query service.
func UnmarshalMeta(r *aws.Request) {
// TODO implement unmarshaling of request IDs
}
@@ -1,33 +0,0 @@
package query
import (
"encoding/xml"
"io"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
)
type xmlErrorResponse struct {
XMLName xml.Name `xml:"ErrorResponse"`
Code string `xml:"Error>Code"`
Message string `xml:"Error>Message"`
RequestID string `xml:"RequestId"`
}
// UnmarshalError unmarshals an error response for an AWS Query service.
func UnmarshalError(r *aws.Request) {
defer r.HTTPResponse.Body.Close()
resp := &xmlErrorResponse{}
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
if err != nil && err != io.EOF {
r.Error = awserr.New("SerializationError", "failed to decode query XML error response", err)
} else {
r.Error = awserr.NewRequestFailure(
awserr.New(resp.Code, resp.Message, nil),
r.HTTPResponse.StatusCode,
resp.RequestID,
)
}
}
File diff suppressed because it is too large Load Diff
@@ -1,217 +0,0 @@
// Package rest provides RESTful serialisation of AWS requests and responses.
package rest
import (
"bytes"
"encoding/base64"
"fmt"
"io"
"net/url"
"path"
"reflect"
"strconv"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
)
// RFC822 returns an RFC822 formatted timestamp for AWS protocols
const RFC822 = "Mon, 2 Jan 2006 15:04:05 GMT"
// Whether the byte value can be sent without escaping in AWS URLs
var noEscape [256]bool
func init() {
for i := 0; i < len(noEscape); i++ {
// AWS expects every character except these to be escaped
noEscape[i] = (i >= 'A' && i <= 'Z') ||
(i >= 'a' && i <= 'z') ||
(i >= '0' && i <= '9') ||
i == '-' ||
i == '.' ||
i == '_' ||
i == '~'
}
}
// Build builds the REST component of a service request.
func Build(r *aws.Request) {
if r.ParamsFilled() {
v := reflect.ValueOf(r.Params).Elem()
buildLocationElements(r, v)
buildBody(r, v)
}
}
func buildLocationElements(r *aws.Request, v reflect.Value) {
query := r.HTTPRequest.URL.Query()
for i := 0; i < v.NumField(); i++ {
m := v.Field(i)
if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) {
continue
}
if m.IsValid() {
field := v.Type().Field(i)
name := field.Tag.Get("locationName")
if name == "" {
name = field.Name
}
if m.Kind() == reflect.Ptr {
m = m.Elem()
}
if !m.IsValid() {
continue
}
switch field.Tag.Get("location") {
case "headers": // header maps
buildHeaderMap(r, m, field.Tag.Get("locationName"))
case "header":
buildHeader(r, m, name)
case "uri":
buildURI(r, m, name)
case "querystring":
buildQueryString(r, m, name, query)
}
}
if r.Error != nil {
return
}
}
r.HTTPRequest.URL.RawQuery = query.Encode()
updatePath(r.HTTPRequest.URL, r.HTTPRequest.URL.Path)
}
func buildBody(r *aws.Request, v reflect.Value) {
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
if payloadName := field.Tag.Get("payload"); payloadName != "" {
pfield, _ := v.Type().FieldByName(payloadName)
if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" {
payload := reflect.Indirect(v.FieldByName(payloadName))
if payload.IsValid() && payload.Interface() != nil {
switch reader := payload.Interface().(type) {
case io.ReadSeeker:
r.SetReaderBody(reader)
case []byte:
r.SetBufferBody(reader)
case string:
r.SetStringBody(reader)
default:
r.Error = awserr.New("SerializationError",
"failed to encode REST request",
fmt.Errorf("unknown payload type %s", payload.Type()))
}
}
}
}
}
}
func buildHeader(r *aws.Request, v reflect.Value, name string) {
str, err := convertType(v)
if err != nil {
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
} else if str != nil {
r.HTTPRequest.Header.Add(name, *str)
}
}
func buildHeaderMap(r *aws.Request, v reflect.Value, prefix string) {
for _, key := range v.MapKeys() {
str, err := convertType(v.MapIndex(key))
if err != nil {
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
} else if str != nil {
r.HTTPRequest.Header.Add(prefix+key.String(), *str)
}
}
}
func buildURI(r *aws.Request, v reflect.Value, name string) {
value, err := convertType(v)
if err != nil {
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
} else if value != nil {
uri := r.HTTPRequest.URL.Path
uri = strings.Replace(uri, "{"+name+"}", EscapePath(*value, true), -1)
uri = strings.Replace(uri, "{"+name+"+}", EscapePath(*value, false), -1)
r.HTTPRequest.URL.Path = uri
}
}
func buildQueryString(r *aws.Request, v reflect.Value, name string, query url.Values) {
str, err := convertType(v)
if err != nil {
r.Error = awserr.New("SerializationError", "failed to encode REST request", err)
} else if str != nil {
query.Set(name, *str)
}
}
func updatePath(url *url.URL, urlPath string) {
scheme, query := url.Scheme, url.RawQuery
hasSlash := strings.HasSuffix(urlPath, "/")
// clean up path
urlPath = path.Clean(urlPath)
if hasSlash && !strings.HasSuffix(urlPath, "/") {
urlPath += "/"
}
// get formatted URL minus scheme so we can build this into Opaque
url.Scheme, url.Path, url.RawQuery = "", "", ""
s := url.String()
url.Scheme = scheme
url.RawQuery = query
// build opaque URI
url.Opaque = s + urlPath
}
// EscapePath escapes part of a URL path in Amazon style
func EscapePath(path string, encodeSep bool) string {
var buf bytes.Buffer
for i := 0; i < len(path); i++ {
c := path[i]
if noEscape[c] || (c == '/' && !encodeSep) {
buf.WriteByte(c)
} else {
buf.WriteByte('%')
buf.WriteString(strings.ToUpper(strconv.FormatUint(uint64(c), 16)))
}
}
return buf.String()
}
func convertType(v reflect.Value) (*string, error) {
v = reflect.Indirect(v)
if !v.IsValid() {
return nil, nil
}
var str string
switch value := v.Interface().(type) {
case string:
str = value
case []byte:
str = base64.StdEncoding.EncodeToString(value)
case bool:
str = strconv.FormatBool(value)
case int64:
str = strconv.FormatInt(value, 10)
case float64:
str = strconv.FormatFloat(value, 'f', -1, 64)
case time.Time:
str = value.UTC().Format(RFC822)
default:
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
return nil, err
}
return &str, nil
}
@@ -1,174 +0,0 @@
package rest
import (
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
"reflect"
"strconv"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
)
// Unmarshal unmarshals the REST component of a response in a REST service.
func Unmarshal(r *aws.Request) {
if r.DataFilled() {
v := reflect.Indirect(reflect.ValueOf(r.Data))
unmarshalBody(r, v)
unmarshalLocationElements(r, v)
}
}
func unmarshalBody(r *aws.Request, v reflect.Value) {
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
if payloadName := field.Tag.Get("payload"); payloadName != "" {
pfield, _ := v.Type().FieldByName(payloadName)
if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" {
payload := v.FieldByName(payloadName)
if payload.IsValid() {
switch payload.Interface().(type) {
case []byte:
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
} else {
payload.Set(reflect.ValueOf(b))
}
case *string:
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
} else {
str := string(b)
payload.Set(reflect.ValueOf(&str))
}
default:
switch payload.Type().String() {
case "io.ReadSeeker":
payload.Set(reflect.ValueOf(aws.ReadSeekCloser(r.HTTPResponse.Body)))
case "aws.ReadSeekCloser", "io.ReadCloser":
payload.Set(reflect.ValueOf(r.HTTPResponse.Body))
default:
r.Error = awserr.New("SerializationError",
"failed to decode REST response",
fmt.Errorf("unknown payload type %s", payload.Type()))
}
}
}
}
}
}
}
func unmarshalLocationElements(r *aws.Request, v reflect.Value) {
for i := 0; i < v.NumField(); i++ {
m, field := v.Field(i), v.Type().Field(i)
if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) {
continue
}
if m.IsValid() {
name := field.Tag.Get("locationName")
if name == "" {
name = field.Name
}
switch field.Tag.Get("location") {
case "statusCode":
unmarshalStatusCode(m, r.HTTPResponse.StatusCode)
case "header":
err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name))
if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
break
}
case "headers":
prefix := field.Tag.Get("locationName")
err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix)
if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
break
}
}
}
if r.Error != nil {
return
}
}
}
func unmarshalStatusCode(v reflect.Value, statusCode int) {
if !v.IsValid() {
return
}
switch v.Interface().(type) {
case *int64:
s := int64(statusCode)
v.Set(reflect.ValueOf(&s))
}
}
func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error {
switch r.Interface().(type) {
case map[string]*string: // we only support string map value types
out := map[string]*string{}
for k, v := range headers {
k = http.CanonicalHeaderKey(k)
if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) {
out[k[len(prefix):]] = &v[0]
}
}
r.Set(reflect.ValueOf(out))
}
return nil
}
func unmarshalHeader(v reflect.Value, header string) error {
if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) {
return nil
}
switch v.Interface().(type) {
case *string:
v.Set(reflect.ValueOf(&header))
case []byte:
b, err := base64.StdEncoding.DecodeString(header)
if err != nil {
return err
}
v.Set(reflect.ValueOf(&b))
case *bool:
b, err := strconv.ParseBool(header)
if err != nil {
return err
}
v.Set(reflect.ValueOf(&b))
case *int64:
i, err := strconv.ParseInt(header, 10, 64)
if err != nil {
return err
}
v.Set(reflect.ValueOf(&i))
case *float64:
f, err := strconv.ParseFloat(header, 64)
if err != nil {
return err
}
v.Set(reflect.ValueOf(&f))
case *time.Time:
t, err := time.Parse(RFC822, header)
if err != nil {
return err
}
v.Set(reflect.ValueOf(&t))
default:
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
return err
}
return nil
}
@@ -1,43 +0,0 @@
package v4_test
import (
"net/url"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/internal/test/unit"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/stretchr/testify/assert"
)
var _ = unit.Imported
func TestPresignHandler(t *testing.T) {
svc := s3.New(nil)
req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String("bucket"),
Key: aws.String("key"),
ContentDisposition: aws.String("a+b c$d"),
ACL: aws.String("public-read"),
})
req.Time = time.Unix(0, 0)
urlstr, err := req.Presign(5 * time.Minute)
assert.NoError(t, err)
expectedDate := "19700101T000000Z"
expectedHeaders := "host;x-amz-acl"
expectedSig := "7edcb4e3a1bf12f4989018d75acbe3a7f03df24bd6f3112602d59fc551f0e4e2"
expectedCred := "AKID/19700101/mock-region/s3/aws4_request"
u, _ := url.Parse(urlstr)
urlQ := u.Query()
assert.Equal(t, expectedSig, urlQ.Get("X-Amz-Signature"))
assert.Equal(t, expectedCred, urlQ.Get("X-Amz-Credential"))
assert.Equal(t, expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"))
assert.Equal(t, expectedDate, urlQ.Get("X-Amz-Date"))
assert.Equal(t, "300", urlQ.Get("X-Amz-Expires"))
assert.NotContains(t, urlstr, "+") // + encoded as %20
}
@@ -1,364 +0,0 @@
// Package v4 implements signing for AWS V4 signer
package v4
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/internal/protocol/rest"
)
const (
authHeaderPrefix = "AWS4-HMAC-SHA256"
timeFormat = "20060102T150405Z"
shortTimeFormat = "20060102"
)
var ignoredHeaders = map[string]bool{
"Authorization": true,
"Content-Type": true,
"Content-Length": true,
"User-Agent": true,
}
type signer struct {
Request *http.Request
Time time.Time
ExpireTime time.Duration
ServiceName string
Region string
CredValues credentials.Value
Credentials *credentials.Credentials
Query url.Values
Body io.ReadSeeker
Debug aws.LogLevelType
Logger aws.Logger
isPresign bool
formattedTime string
formattedShortTime string
signedHeaders string
canonicalHeaders string
canonicalString string
credentialString string
stringToSign string
signature string
authorization string
}
// Sign requests with signature version 4.
//
// Will sign the requests with the service config's Credentials object
// Signing is skipped if the credentials is the credentials.AnonymousCredentials
// object.
func Sign(req *aws.Request) {
// If the request does not need to be signed ignore the signing of the
// request if the AnonymousCredentials object is used.
if req.Service.Config.Credentials == credentials.AnonymousCredentials {
return
}
region := req.Service.SigningRegion
if region == "" {
region = aws.StringValue(req.Service.Config.Region)
}
name := req.Service.SigningName
if name == "" {
name = req.Service.ServiceName
}
s := signer{
Request: req.HTTPRequest,
Time: req.Time,
ExpireTime: req.ExpireTime,
Query: req.HTTPRequest.URL.Query(),
Body: req.Body,
ServiceName: name,
Region: region,
Credentials: req.Service.Config.Credentials,
Debug: req.Service.Config.LogLevel.Value(),
Logger: req.Service.Config.Logger,
}
req.Error = s.sign()
}
func (v4 *signer) sign() error {
if v4.ExpireTime != 0 {
v4.isPresign = true
}
if v4.isRequestSigned() {
if !v4.Credentials.IsExpired() {
// If the request is already signed, and the credentials have not
// expired yet ignore the signing request.
return nil
}
// The credentials have expired for this request. The current signing
// is invalid, and needs to be request because the request will fail.
if v4.isPresign {
v4.removePresign()
// Update the request's query string to ensure the values stays in
// sync in the case retrieving the new credentials fails.
v4.Request.URL.RawQuery = v4.Query.Encode()
}
}
var err error
v4.CredValues, err = v4.Credentials.Get()
if err != nil {
return err
}
if v4.isPresign {
v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
if v4.CredValues.SessionToken != "" {
v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
} else {
v4.Query.Del("X-Amz-Security-Token")
}
} else if v4.CredValues.SessionToken != "" {
v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
}
v4.build()
if v4.Debug.Matches(aws.LogDebugWithSigning) {
v4.logSigningInfo()
}
return nil
}
const logSignInfoMsg = `DEBUG: Request Signiture:
---[ CANONICAL STRING ]-----------------------------
%s
---[ STRING TO SIGN ]--------------------------------
%s%s
-----------------------------------------------------`
const logSignedURLMsg = `
---[ SIGNED URL ]------------------------------------
%s`
func (v4 *signer) logSigningInfo() {
signedURLMsg := ""
if v4.isPresign {
signedURLMsg = fmt.Sprintf(logSignedURLMsg, v4.Request.URL.String())
}
msg := fmt.Sprintf(logSignInfoMsg, v4.canonicalString, v4.stringToSign, signedURLMsg)
v4.Logger.Log(msg)
}
func (v4 *signer) build() {
v4.buildTime() // no depends
v4.buildCredentialString() // no depends
if v4.isPresign {
v4.buildQuery() // no depends
}
v4.buildCanonicalHeaders() // depends on cred string
v4.buildCanonicalString() // depends on canon headers / signed headers
v4.buildStringToSign() // depends on canon string
v4.buildSignature() // depends on string to sign
if v4.isPresign {
v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature
} else {
parts := []string{
authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString,
"SignedHeaders=" + v4.signedHeaders,
"Signature=" + v4.signature,
}
v4.Request.Header.Set("Authorization", strings.Join(parts, ", "))
}
}
func (v4 *signer) buildTime() {
v4.formattedTime = v4.Time.UTC().Format(timeFormat)
v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
if v4.isPresign {
duration := int64(v4.ExpireTime / time.Second)
v4.Query.Set("X-Amz-Date", v4.formattedTime)
v4.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
} else {
v4.Request.Header.Set("X-Amz-Date", v4.formattedTime)
}
}
func (v4 *signer) buildCredentialString() {
v4.credentialString = strings.Join([]string{
v4.formattedShortTime,
v4.Region,
v4.ServiceName,
"aws4_request",
}, "/")
if v4.isPresign {
v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString)
}
}
func (v4 *signer) buildQuery() {
for k, h := range v4.Request.Header {
if strings.HasPrefix(http.CanonicalHeaderKey(k), "X-Amz-") {
continue // never hoist x-amz-* headers, they must be signed
}
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // never hoist ignored headers
}
v4.Request.Header.Del(k)
v4.Query.Del(k)
for _, v := range h {
v4.Query.Add(k, v)
}
}
}
func (v4 *signer) buildCanonicalHeaders() {
var headers []string
headers = append(headers, "host")
for k := range v4.Request.Header {
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // ignored header
}
headers = append(headers, strings.ToLower(k))
}
sort.Strings(headers)
v4.signedHeaders = strings.Join(headers, ";")
if v4.isPresign {
v4.Query.Set("X-Amz-SignedHeaders", v4.signedHeaders)
}
headerValues := make([]string, len(headers))
for i, k := range headers {
if k == "host" {
headerValues[i] = "host:" + v4.Request.URL.Host
} else {
headerValues[i] = k + ":" +
strings.Join(v4.Request.Header[http.CanonicalHeaderKey(k)], ",")
}
}
v4.canonicalHeaders = strings.Join(headerValues, "\n")
}
func (v4 *signer) buildCanonicalString() {
v4.Request.URL.RawQuery = strings.Replace(v4.Query.Encode(), "+", "%20", -1)
uri := v4.Request.URL.Opaque
if uri != "" {
uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/")
} else {
uri = v4.Request.URL.Path
}
if uri == "" {
uri = "/"
}
if v4.ServiceName != "s3" {
uri = rest.EscapePath(uri, false)
}
v4.canonicalString = strings.Join([]string{
v4.Request.Method,
uri,
v4.Request.URL.RawQuery,
v4.canonicalHeaders + "\n",
v4.signedHeaders,
v4.bodyDigest(),
}, "\n")
}
func (v4 *signer) buildStringToSign() {
v4.stringToSign = strings.Join([]string{
authHeaderPrefix,
v4.formattedTime,
v4.credentialString,
hex.EncodeToString(makeSha256([]byte(v4.canonicalString))),
}, "\n")
}
func (v4 *signer) buildSignature() {
secret := v4.CredValues.SecretAccessKey
date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
region := makeHmac(date, []byte(v4.Region))
service := makeHmac(region, []byte(v4.ServiceName))
credentials := makeHmac(service, []byte("aws4_request"))
signature := makeHmac(credentials, []byte(v4.stringToSign))
v4.signature = hex.EncodeToString(signature)
}
func (v4 *signer) bodyDigest() string {
hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
if hash == "" {
if v4.isPresign && v4.ServiceName == "s3" {
hash = "UNSIGNED-PAYLOAD"
} else if v4.Body == nil {
hash = hex.EncodeToString(makeSha256([]byte{}))
} else {
hash = hex.EncodeToString(makeSha256Reader(v4.Body))
}
v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
}
return hash
}
// isRequestSigned returns if the request is currently signed or presigned
func (v4 *signer) isRequestSigned() bool {
if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" {
return true
}
if v4.Request.Header.Get("Authorization") != "" {
return true
}
return false
}
// unsign removes signing flags for both signed and presigned requests.
func (v4 *signer) removePresign() {
v4.Query.Del("X-Amz-Algorithm")
v4.Query.Del("X-Amz-Signature")
v4.Query.Del("X-Amz-Security-Token")
v4.Query.Del("X-Amz-Date")
v4.Query.Del("X-Amz-Expires")
v4.Query.Del("X-Amz-Credential")
v4.Query.Del("X-Amz-SignedHeaders")
}
func makeHmac(key []byte, data []byte) []byte {
hash := hmac.New(sha256.New, key)
hash.Write(data)
return hash.Sum(nil)
}
func makeSha256(data []byte) []byte {
hash := sha256.New()
hash.Write(data)
return hash.Sum(nil)
}
func makeSha256Reader(reader io.ReadSeeker) []byte {
hash := sha256.New()
start, _ := reader.Seek(0, 1)
defer reader.Seek(start, 0)
io.Copy(hash, reader)
return hash.Sum(nil)
}
@@ -1,245 +0,0 @@
package v4
import (
"net/http"
"strings"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/stretchr/testify/assert"
)
func buildSigner(serviceName string, region string, signTime time.Time, expireTime time.Duration, body string) signer {
endpoint := "https://" + serviceName + "." + region + ".amazonaws.com"
reader := strings.NewReader(body)
req, _ := http.NewRequest("POST", endpoint, reader)
req.URL.Opaque = "//example.org/bucket/key-._~,!@#$%^&*()"
req.Header.Add("X-Amz-Target", "prefix.Operation")
req.Header.Add("Content-Type", "application/x-amz-json-1.0")
req.Header.Add("Content-Length", string(len(body)))
req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)")
return signer{
Request: req,
Time: signTime,
ExpireTime: expireTime,
Query: req.URL.Query(),
Body: reader,
ServiceName: serviceName,
Region: region,
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
}
}
func removeWS(text string) string {
text = strings.Replace(text, " ", "", -1)
text = strings.Replace(text, "\n", "", -1)
text = strings.Replace(text, "\t", "", -1)
return text
}
func assertEqual(t *testing.T, expected, given string) {
if removeWS(expected) != removeWS(given) {
t.Errorf("\nExpected: %s\nGiven: %s", expected, given)
}
}
func TestPresignRequest(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Unix(0, 0), 300*time.Second, "{}")
signer.sign()
expectedDate := "19700101T000000Z"
expectedHeaders := "host;x-amz-meta-other-header;x-amz-target"
expectedSig := "5eeedebf6f995145ce56daa02902d10485246d3defb34f97b973c1f40ab82d36"
expectedCred := "AKID/19700101/us-east-1/dynamodb/aws4_request"
q := signer.Request.URL.Query()
assert.Equal(t, expectedSig, q.Get("X-Amz-Signature"))
assert.Equal(t, expectedCred, q.Get("X-Amz-Credential"))
assert.Equal(t, expectedHeaders, q.Get("X-Amz-SignedHeaders"))
assert.Equal(t, expectedDate, q.Get("X-Amz-Date"))
}
func TestSignRequest(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Unix(0, 0), 0, "{}")
signer.sign()
expectedDate := "19700101T000000Z"
expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=host;x-amz-date;x-amz-meta-other-header;x-amz-security-token;x-amz-target, Signature=69ada33fec48180dab153576e4dd80c4e04124f80dda3eccfed8a67c2b91ed5e"
q := signer.Request.Header
assert.Equal(t, expectedSig, q.Get("Authorization"))
assert.Equal(t, expectedDate, q.Get("X-Amz-Date"))
}
func TestSignEmptyBody(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "")
signer.Body = nil
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", hash)
}
func TestSignBody(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "hello")
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash)
}
func TestSignSeekedBody(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, " hello")
signer.Body.Read(make([]byte, 3)) // consume first 3 bytes so body is now "hello"
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash)
start, _ := signer.Body.Seek(0, 1)
assert.Equal(t, int64(3), start)
}
func TestPresignEmptyBodyS3(t *testing.T) {
signer := buildSigner("s3", "us-east-1", time.Now(), 5*time.Minute, "hello")
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "UNSIGNED-PAYLOAD", hash)
}
func TestSignPrecomputedBodyChecksum(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "hello")
signer.Request.Header.Set("X-Amz-Content-Sha256", "PRECOMPUTED")
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "PRECOMPUTED", hash)
}
func TestAnonymousCredentials(t *testing.T) {
r := aws.NewRequest(
aws.NewService(&aws.Config{Credentials: credentials.AnonymousCredentials}),
&aws.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
Sign(r)
urlQ := r.HTTPRequest.URL.Query()
assert.Empty(t, urlQ.Get("X-Amz-Signature"))
assert.Empty(t, urlQ.Get("X-Amz-Credential"))
assert.Empty(t, urlQ.Get("X-Amz-SignedHeaders"))
assert.Empty(t, urlQ.Get("X-Amz-Date"))
hQ := r.HTTPRequest.Header
assert.Empty(t, hQ.Get("Authorization"))
assert.Empty(t, hQ.Get("X-Amz-Date"))
}
func TestIgnoreResignRequestWithValidCreds(t *testing.T) {
r := aws.NewRequest(
aws.NewService(&aws.Config{
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
Region: aws.String("us-west-2"),
}),
&aws.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
Sign(r)
sig := r.HTTPRequest.Header.Get("Authorization")
Sign(r)
assert.Equal(t, sig, r.HTTPRequest.Header.Get("Authorization"))
}
func TestIgnorePreResignRequestWithValidCreds(t *testing.T) {
r := aws.NewRequest(
aws.NewService(&aws.Config{
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
Region: aws.String("us-west-2"),
}),
&aws.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
r.ExpireTime = time.Minute * 10
Sign(r)
sig := r.HTTPRequest.Header.Get("X-Amz-Signature")
Sign(r)
assert.Equal(t, sig, r.HTTPRequest.Header.Get("X-Amz-Signature"))
}
func TestResignRequestExpiredCreds(t *testing.T) {
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
r := aws.NewRequest(
aws.NewService(&aws.Config{Credentials: creds}),
&aws.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
Sign(r)
querySig := r.HTTPRequest.Header.Get("Authorization")
creds.Expire()
Sign(r)
assert.NotEqual(t, querySig, r.HTTPRequest.Header.Get("Authorization"))
}
func TestPreResignRequestExpiredCreds(t *testing.T) {
provider := &credentials.StaticProvider{credentials.Value{"AKID", "SECRET", "SESSION"}}
creds := credentials.NewCredentials(provider)
r := aws.NewRequest(
aws.NewService(&aws.Config{Credentials: creds}),
&aws.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
r.ExpireTime = time.Minute * 10
Sign(r)
querySig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature")
creds.Expire()
r.Time = time.Now().Add(time.Hour * 48)
Sign(r)
assert.NotEqual(t, querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature"))
}
func BenchmarkPresignRequest(b *testing.B) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 300*time.Second, "{}")
for i := 0; i < b.N; i++ {
signer.sign()
}
}
func BenchmarkSignRequest(b *testing.B) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "{}")
for i := 0; i < b.N; i++ {
signer.sign()
}
}
@@ -1,89 +0,0 @@
{
"version": 2,
"endpoints": {
"*/*": {
"endpoint": "{service}.{region}.amazonaws.com"
},
"cn-north-1/*": {
"endpoint": "{service}.{region}.amazonaws.com.cn",
"signatureVersion": "v4"
},
"us-gov-west-1/iam": {
"endpoint": "iam.us-gov.amazonaws.com"
},
"us-gov-west-1/sts": {
"endpoint": "sts.us-gov-west-1.amazonaws.com"
},
"us-gov-west-1/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"*/cloudfront": {
"endpoint": "cloudfront.amazonaws.com",
"signingRegion": "us-east-1"
},
"*/cloudsearchdomain": {
"endpoint": "",
"signingRegion": "us-east-1"
},
"*/data.iot": {
"endpoint": "",
"signingRegion": "us-east-1"
},
"*/ec2metadata": {
"endpoint": "http://169.254.169.254/latest",
"signingRegion": "us-east-1"
},
"*/iam": {
"endpoint": "iam.amazonaws.com",
"signingRegion": "us-east-1"
},
"*/importexport": {
"endpoint": "importexport.amazonaws.com",
"signingRegion": "us-east-1"
},
"*/route53": {
"endpoint": "route53.amazonaws.com",
"signingRegion": "us-east-1"
},
"*/sts": {
"endpoint": "sts.amazonaws.com",
"signingRegion": "us-east-1"
},
"*/waf": {
"endpoint": "waf.amazonaws.com",
"signingRegion": "us-east-1"
},
"us-east-1/sdb": {
"endpoint": "sdb.amazonaws.com",
"signingRegion": "us-east-1"
},
"us-east-1/s3": {
"endpoint": "s3.amazonaws.com"
},
"us-west-1/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"us-west-2/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"eu-west-1/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"ap-southeast-1/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"ap-southeast-2/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"ap-northeast-1/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"sa-east-1/s3": {
"endpoint": "s3-{region}.amazonaws.com"
},
"eu-central-1/s3": {
"endpoint": "{service}.{region}.amazonaws.com",
"signatureVersion": "v4"
}
}
}
@@ -1,41 +0,0 @@
package endpoints_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/private/endpoints"
)
func TestGenericEndpoint(t *testing.T) {
name := "service"
region := "mock-region-1"
ep, sr := endpoints.EndpointForRegion(name, region, false)
assert.Equal(t, fmt.Sprintf("https://%s.%s.amazonaws.com", name, region), ep)
assert.Empty(t, sr)
}
func TestGlobalEndpoints(t *testing.T) {
region := "mock-region-1"
svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts", "waf"}
for _, name := range svcs {
ep, sr := endpoints.EndpointForRegion(name, region, false)
assert.Equal(t, fmt.Sprintf("https://%s.amazonaws.com", name), ep)
assert.Equal(t, "us-east-1", sr)
}
}
func TestServicesInCN(t *testing.T) {
region := "cn-north-1"
svcs := []string{"cloudfront", "iam", "importexport", "route53", "sts", "s3", "waf"}
for _, name := range svcs {
ep, sr := endpoints.EndpointForRegion(name, region, false)
assert.Equal(t, fmt.Sprintf("https://%s.%s.amazonaws.com.cn", name, region), ep)
assert.Empty(t, sr)
}
}
@@ -1,33 +0,0 @@
package query
import (
"encoding/xml"
"io"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
type xmlErrorResponse struct {
XMLName xml.Name `xml:"ErrorResponse"`
Code string `xml:"Error>Code"`
Message string `xml:"Error>Message"`
RequestID string `xml:"RequestId"`
}
// UnmarshalError unmarshals an error response for an AWS Query service.
func UnmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close()
resp := &xmlErrorResponse{}
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
if err != nil && err != io.EOF {
r.Error = awserr.New("SerializationError", "failed to decode query XML error response", err)
} else {
r.Error = awserr.NewRequestFailure(
awserr.New(resp.Code, resp.Message, nil),
r.HTTPResponse.StatusCode,
resp.RequestID,
)
}
}
@@ -1,45 +0,0 @@
package rest
import "reflect"
// PayloadMember returns the payload field member of i if there is one, or nil.
func PayloadMember(i interface{}) interface{} {
if i == nil {
return nil
}
v := reflect.ValueOf(i).Elem()
if !v.IsValid() {
return nil
}
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
if payloadName := field.Tag.Get("payload"); payloadName != "" {
field, _ := v.Type().FieldByName(payloadName)
if field.Tag.Get("type") != "structure" {
return nil
}
payload := v.FieldByName(payloadName)
if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) {
return payload.Interface()
}
}
}
return nil
}
// PayloadType returns the type of a payload field member of i if there is one, or "".
func PayloadType(i interface{}) string {
v := reflect.Indirect(reflect.ValueOf(i))
if !v.IsValid() {
return ""
}
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
if payloadName := field.Tag.Get("payload"); payloadName != "" {
if member, ok := v.Type().FieldByName(payloadName); ok {
return member.Tag.Get("type")
}
}
}
return ""
}
@@ -1,287 +0,0 @@
// Package xmlutil provides XML serialisation of AWS requests and responses.
package xmlutil
import (
"encoding/base64"
"encoding/xml"
"fmt"
"reflect"
"sort"
"strconv"
"strings"
"time"
)
// BuildXML will serialize params into an xml.Encoder.
// Error will be returned if the serialization of any of the params or nested values fails.
func BuildXML(params interface{}, e *xml.Encoder) error {
b := xmlBuilder{encoder: e, namespaces: map[string]string{}}
root := NewXMLElement(xml.Name{})
if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil {
return err
}
for _, c := range root.Children {
for _, v := range c {
return StructToXML(e, v, false)
}
}
return nil
}
// Returns the reflection element of a value, if it is a pointer.
func elemOf(value reflect.Value) reflect.Value {
for value.Kind() == reflect.Ptr {
value = value.Elem()
}
return value
}
// A xmlBuilder serializes values from Go code to XML
type xmlBuilder struct {
encoder *xml.Encoder
namespaces map[string]string
}
// buildValue generic XMLNode builder for any type. Will build value for their specific type
// struct, list, map, scalar.
//
// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If
// type is not provided reflect will be used to determine the value's type.
func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
value = elemOf(value)
if !value.IsValid() { // no need to handle zero values
return nil
} else if tag.Get("location") != "" { // don't handle non-body location values
return nil
}
t := tag.Get("type")
if t == "" {
switch value.Kind() {
case reflect.Struct:
t = "structure"
case reflect.Slice:
t = "list"
case reflect.Map:
t = "map"
}
}
switch t {
case "structure":
if field, ok := value.Type().FieldByName("SDKShapeTraits"); ok {
tag = tag + reflect.StructTag(" ") + field.Tag
}
return b.buildStruct(value, current, tag)
case "list":
return b.buildList(value, current, tag)
case "map":
return b.buildMap(value, current, tag)
default:
return b.buildScalar(value, current, tag)
}
}
// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested
// types are converted to XMLNodes also.
func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
if !value.IsValid() {
return nil
}
fieldAdded := false
// unwrap payloads
if payload := tag.Get("payload"); payload != "" {
field, _ := value.Type().FieldByName(payload)
tag = field.Tag
value = elemOf(value.FieldByName(payload))
if !value.IsValid() {
return nil
}
}
child := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
// there is an xmlNamespace associated with this struct
if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" {
ns := xml.Attr{
Name: xml.Name{Local: "xmlns"},
Value: uri,
}
if prefix != "" {
b.namespaces[prefix] = uri // register the namespace
ns.Name.Local = "xmlns:" + prefix
}
child.Attr = append(child.Attr, ns)
}
t := value.Type()
for i := 0; i < value.NumField(); i++ {
if c := t.Field(i).Name[0:1]; strings.ToLower(c) == c {
continue // ignore unexported fields
}
member := elemOf(value.Field(i))
field := t.Field(i)
mTag := field.Tag
if mTag.Get("location") != "" { // skip non-body members
continue
}
memberName := mTag.Get("locationName")
if memberName == "" {
memberName = field.Name
mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`)
}
if err := b.buildValue(member, child, mTag); err != nil {
return err
}
fieldAdded = true
}
if fieldAdded { // only append this child if we have one ore more valid members
current.AddChild(child)
}
return nil
}
// buildList adds the value's list items to the current XMLNode as children nodes. All
// nested values in the list are converted to XMLNodes also.
func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
if value.IsNil() { // don't build omitted lists
return nil
}
// check for unflattened list member
flattened := tag.Get("flattened") != ""
xname := xml.Name{Local: tag.Get("locationName")}
if flattened {
for i := 0; i < value.Len(); i++ {
child := NewXMLElement(xname)
current.AddChild(child)
if err := b.buildValue(value.Index(i), child, ""); err != nil {
return err
}
}
} else {
list := NewXMLElement(xname)
current.AddChild(list)
for i := 0; i < value.Len(); i++ {
iname := tag.Get("locationNameList")
if iname == "" {
iname = "member"
}
child := NewXMLElement(xml.Name{Local: iname})
list.AddChild(child)
if err := b.buildValue(value.Index(i), child, ""); err != nil {
return err
}
}
}
return nil
}
// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All
// nested values in the map are converted to XMLNodes also.
//
// Error will be returned if it is unable to build the map's values into XMLNodes
func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
if value.IsNil() { // don't build omitted maps
return nil
}
maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
current.AddChild(maproot)
current = maproot
kname, vname := "key", "value"
if n := tag.Get("locationNameKey"); n != "" {
kname = n
}
if n := tag.Get("locationNameValue"); n != "" {
vname = n
}
// sorting is not required for compliance, but it makes testing easier
keys := make([]string, value.Len())
for i, k := range value.MapKeys() {
keys[i] = k.String()
}
sort.Strings(keys)
for _, k := range keys {
v := value.MapIndex(reflect.ValueOf(k))
mapcur := current
if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps
child := NewXMLElement(xml.Name{Local: "entry"})
mapcur.AddChild(child)
mapcur = child
}
kchild := NewXMLElement(xml.Name{Local: kname})
kchild.Text = k
vchild := NewXMLElement(xml.Name{Local: vname})
mapcur.AddChild(kchild)
mapcur.AddChild(vchild)
if err := b.buildValue(v, vchild, ""); err != nil {
return err
}
}
return nil
}
// buildScalar will convert the value into a string and append it as a attribute or child
// of the current XMLNode.
//
// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value.
//
// Error will be returned if the value type is unsupported.
func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
var str string
switch converted := value.Interface().(type) {
case string:
str = converted
case []byte:
if !value.IsNil() {
str = base64.StdEncoding.EncodeToString(converted)
}
case bool:
str = strconv.FormatBool(converted)
case int64:
str = strconv.FormatInt(converted, 10)
case int:
str = strconv.Itoa(converted)
case float64:
str = strconv.FormatFloat(converted, 'f', -1, 64)
case float32:
str = strconv.FormatFloat(float64(converted), 'f', -1, 32)
case time.Time:
const ISO8601UTC = "2006-01-02T15:04:05Z"
str = converted.UTC().Format(ISO8601UTC)
default:
return fmt.Errorf("unsupported value for param %s: %v (%s)",
tag.Get("locationName"), value.Interface(), value.Type().Name())
}
xname := xml.Name{Local: tag.Get("locationName")}
if tag.Get("xmlAttribute") != "" { // put into current node's attribute list
attr := xml.Attr{Name: xname, Value: str}
current.Attr = append(current.Attr, attr)
} else { // regular text node
current.AddChild(&XMLNode{Name: xname, Text: str})
}
return nil
}
@@ -1,260 +0,0 @@
package xmlutil
import (
"encoding/base64"
"encoding/xml"
"fmt"
"io"
"reflect"
"strconv"
"strings"
"time"
)
// UnmarshalXML deserializes an xml.Decoder into the container v. V
// 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)
if n.Children != nil {
for _, root := range n.Children {
for _, c := range root {
if wrappedChild, ok := c.Children[wrapper]; ok {
c = wrappedChild[0] // pull out wrapped element
}
err := parse(reflect.ValueOf(v), c, "")
if err != nil {
if err == io.EOF {
return nil
}
return err
}
}
}
return nil
}
return nil
}
// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect
// will be used to determine the type from r.
func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
rtype := r.Type()
if rtype.Kind() == reflect.Ptr {
rtype = rtype.Elem() // check kind of actual element type
}
t := tag.Get("type")
if t == "" {
switch rtype.Kind() {
case reflect.Struct:
t = "structure"
case reflect.Slice:
t = "list"
case reflect.Map:
t = "map"
}
}
switch t {
case "structure":
if field, ok := rtype.FieldByName("SDKShapeTraits"); ok {
tag = field.Tag
}
return parseStruct(r, node, tag)
case "list":
return parseList(r, node, tag)
case "map":
return parseMap(r, node, tag)
default:
return parseScalar(r, node, tag)
}
}
// parseStruct deserializes a structure and its fields from an XMLNode. Any nested
// types in the structure will also be deserialized.
func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
t := r.Type()
if r.Kind() == reflect.Ptr {
if r.IsNil() { // create the structure if it's nil
s := reflect.New(r.Type().Elem())
r.Set(s)
r = s
}
r = r.Elem()
t = t.Elem()
}
// unwrap any payloads
if payload := tag.Get("payload"); payload != "" {
field, _ := t.FieldByName(payload)
return parseStruct(r.FieldByName(payload), node, field.Tag)
}
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if c := field.Name[0:1]; strings.ToLower(c) == c {
continue // ignore unexported fields
}
// figure out what this field is called
name := field.Name
if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
name = field.Tag.Get("locationNameList")
} else if locName := field.Tag.Get("locationName"); locName != "" {
name = locName
}
// try to find the field by name in elements
elems := node.Children[name]
if elems == nil { // try to find the field in attributes
for _, a := range node.Attr {
if name == a.Name.Local {
// turn this into a text node for de-serializing
elems = []*XMLNode{{Text: a.Value}}
}
}
}
member := r.FieldByName(field.Name)
for _, elem := range elems {
err := parse(member, elem, field.Tag)
if err != nil {
return err
}
}
}
return nil
}
// parseList deserializes a list of values from an XML node. Each list entry
// will also be deserialized.
func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
t := r.Type()
if tag.Get("flattened") == "" { // look at all item entries
mname := "member"
if name := tag.Get("locationNameList"); name != "" {
mname = name
}
if Children, ok := node.Children[mname]; ok {
if r.IsNil() {
r.Set(reflect.MakeSlice(t, len(Children), len(Children)))
}
for i, c := range Children {
err := parse(r.Index(i), c, "")
if err != nil {
return err
}
}
}
} else { // flattened list means this is a single element
if r.IsNil() {
r.Set(reflect.MakeSlice(t, 0, 0))
}
childR := reflect.Zero(t.Elem())
r.Set(reflect.Append(r, childR))
err := parse(r.Index(r.Len()-1), node, "")
if err != nil {
return err
}
}
return nil
}
// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode
// will also be deserialized as map entries.
func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
if r.IsNil() {
r.Set(reflect.MakeMap(r.Type()))
}
if tag.Get("flattened") == "" { // look at all child entries
for _, entry := range node.Children["entry"] {
parseMapEntry(r, entry, tag)
}
} else { // this element is itself an entry
parseMapEntry(r, node, tag)
}
return nil
}
// parseMapEntry deserializes a map entry from a XML node.
func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
kname, vname := "key", "value"
if n := tag.Get("locationNameKey"); n != "" {
kname = n
}
if n := tag.Get("locationNameValue"); n != "" {
vname = n
}
keys, ok := node.Children[kname]
values := node.Children[vname]
if ok {
for i, key := range keys {
keyR := reflect.ValueOf(key.Text)
value := values[i]
valueR := reflect.New(r.Type().Elem()).Elem()
parse(valueR, value, "")
r.SetMapIndex(keyR, valueR)
}
}
return nil
}
// parseScaller deserializes an XMLNode value into a concrete type based on the
// interface type of r.
//
// Error is returned if the deserialization fails due to invalid type conversion,
// or unsupported interface type.
func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
switch r.Interface().(type) {
case *string:
r.Set(reflect.ValueOf(&node.Text))
return nil
case []byte:
b, err := base64.StdEncoding.DecodeString(node.Text)
if err != nil {
return err
}
r.Set(reflect.ValueOf(b))
case *bool:
v, err := strconv.ParseBool(node.Text)
if err != nil {
return err
}
r.Set(reflect.ValueOf(&v))
case *int64:
v, err := strconv.ParseInt(node.Text, 10, 64)
if err != nil {
return err
}
r.Set(reflect.ValueOf(&v))
case *float64:
v, err := strconv.ParseFloat(node.Text, 64)
if err != nil {
return err
}
r.Set(reflect.ValueOf(&v))
case *time.Time:
const ISO8601UTC = "2006-01-02T15:04:05Z"
t, err := time.Parse(ISO8601UTC, node.Text)
if err != nil {
return err
}
r.Set(reflect.ValueOf(&t))
default:
return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type())
}
return nil
}
@@ -1,105 +0,0 @@
package xmlutil
import (
"encoding/xml"
"io"
"sort"
)
// A XMLNode contains the values to be encoded or decoded.
type XMLNode struct {
Name xml.Name `json:",omitempty"`
Children map[string][]*XMLNode `json:",omitempty"`
Text string `json:",omitempty"`
Attr []xml.Attr `json:",omitempty"`
}
// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
func NewXMLElement(name xml.Name) *XMLNode {
return &XMLNode{
Name: name,
Children: map[string][]*XMLNode{},
Attr: []xml.Attr{},
}
}
// AddChild adds child to the XMLNode.
func (n *XMLNode) AddChild(child *XMLNode) {
if _, ok := n.Children[child.Name.Local]; !ok {
n.Children[child.Name.Local] = []*XMLNode{}
}
n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child)
}
// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values.
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
}
switch typed := tok.(type) {
case xml.CharData:
out.Text = string(typed.Copy())
case xml.StartElement:
el := typed.Copy()
out.Attr = el.Attr
if out.Children == nil {
out.Children = map[string][]*XMLNode{}
}
name := typed.Name.Local
slice := out.Children[name]
if slice == nil {
slice = []*XMLNode{}
}
node, e := XMLToStruct(d, &el)
if e != nil {
return out, e
}
node.Name = typed.Name
slice = append(slice, node)
out.Children[name] = slice
case xml.EndElement:
if s != nil && s.Name.Local == typed.Name.Local { // matching end token
return out, nil
}
}
}
return out, nil
}
// StructToXML writes an XMLNode to a xml.Encoder as tokens.
func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr})
if node.Text != "" {
e.EncodeToken(xml.CharData([]byte(node.Text)))
} else if sorted {
sortedNames := []string{}
for k := range node.Children {
sortedNames = append(sortedNames, k)
}
sort.Strings(sortedNames)
for _, k := range sortedNames {
for _, v := range node.Children[k] {
StructToXML(e, v, sorted)
}
}
} else {
for _, c := range node.Children {
for _, v := range c {
StructToXML(e, v, sorted)
}
}
}
e.EncodeToken(xml.EndElement{Name: node.Name})
return e.Flush()
}
@@ -1,42 +0,0 @@
package v4_test
import (
"net/url"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/awstesting/unit"
"github.com/aws/aws-sdk-go/service/s3"
)
func TestPresignHandler(t *testing.T) {
svc := s3.New(unit.Session)
req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String("bucket"),
Key: aws.String("key"),
ContentDisposition: aws.String("a+b c$d"),
ACL: aws.String("public-read"),
})
req.Time = time.Unix(0, 0)
urlstr, err := req.Presign(5 * time.Minute)
assert.NoError(t, err)
expectedDate := "19700101T000000Z"
expectedHeaders := "host;x-amz-acl"
expectedSig := "7edcb4e3a1bf12f4989018d75acbe3a7f03df24bd6f3112602d59fc551f0e4e2"
expectedCred := "AKID/19700101/mock-region/s3/aws4_request"
u, _ := url.Parse(urlstr)
urlQ := u.Query()
assert.Equal(t, expectedSig, urlQ.Get("X-Amz-Signature"))
assert.Equal(t, expectedCred, urlQ.Get("X-Amz-Credential"))
assert.Equal(t, expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"))
assert.Equal(t, expectedDate, urlQ.Get("X-Amz-Date"))
assert.Equal(t, "300", urlQ.Get("X-Amz-Expires"))
assert.NotContains(t, urlstr, "+") // + encoded as %20
}
-365
View File
@@ -1,365 +0,0 @@
// Package v4 implements signing for AWS V4 signer
package v4
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/rest"
)
const (
authHeaderPrefix = "AWS4-HMAC-SHA256"
timeFormat = "20060102T150405Z"
shortTimeFormat = "20060102"
)
var ignoredHeaders = map[string]bool{
"Authorization": true,
"Content-Type": true,
"Content-Length": true,
"User-Agent": true,
}
type signer struct {
Request *http.Request
Time time.Time
ExpireTime time.Duration
ServiceName string
Region string
CredValues credentials.Value
Credentials *credentials.Credentials
Query url.Values
Body io.ReadSeeker
Debug aws.LogLevelType
Logger aws.Logger
isPresign bool
formattedTime string
formattedShortTime string
signedHeaders string
canonicalHeaders string
canonicalString string
credentialString string
stringToSign string
signature string
authorization string
}
// Sign requests with signature version 4.
//
// Will sign the requests with the service config's Credentials object
// Signing is skipped if the credentials is the credentials.AnonymousCredentials
// object.
func Sign(req *request.Request) {
// If the request does not need to be signed ignore the signing of the
// request if the AnonymousCredentials object is used.
if req.Config.Credentials == credentials.AnonymousCredentials {
return
}
region := req.ClientInfo.SigningRegion
if region == "" {
region = aws.StringValue(req.Config.Region)
}
name := req.ClientInfo.SigningName
if name == "" {
name = req.ClientInfo.ServiceName
}
s := signer{
Request: req.HTTPRequest,
Time: req.Time,
ExpireTime: req.ExpireTime,
Query: req.HTTPRequest.URL.Query(),
Body: req.Body,
ServiceName: name,
Region: region,
Credentials: req.Config.Credentials,
Debug: req.Config.LogLevel.Value(),
Logger: req.Config.Logger,
}
req.Error = s.sign()
}
func (v4 *signer) sign() error {
if v4.ExpireTime != 0 {
v4.isPresign = true
}
if v4.isRequestSigned() {
if !v4.Credentials.IsExpired() {
// If the request is already signed, and the credentials have not
// expired yet ignore the signing request.
return nil
}
// The credentials have expired for this request. The current signing
// is invalid, and needs to be request because the request will fail.
if v4.isPresign {
v4.removePresign()
// Update the request's query string to ensure the values stays in
// sync in the case retrieving the new credentials fails.
v4.Request.URL.RawQuery = v4.Query.Encode()
}
}
var err error
v4.CredValues, err = v4.Credentials.Get()
if err != nil {
return err
}
if v4.isPresign {
v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
if v4.CredValues.SessionToken != "" {
v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
} else {
v4.Query.Del("X-Amz-Security-Token")
}
} else if v4.CredValues.SessionToken != "" {
v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
}
v4.build()
if v4.Debug.Matches(aws.LogDebugWithSigning) {
v4.logSigningInfo()
}
return nil
}
const logSignInfoMsg = `DEBUG: Request Signiture:
---[ CANONICAL STRING ]-----------------------------
%s
---[ STRING TO SIGN ]--------------------------------
%s%s
-----------------------------------------------------`
const logSignedURLMsg = `
---[ SIGNED URL ]------------------------------------
%s`
func (v4 *signer) logSigningInfo() {
signedURLMsg := ""
if v4.isPresign {
signedURLMsg = fmt.Sprintf(logSignedURLMsg, v4.Request.URL.String())
}
msg := fmt.Sprintf(logSignInfoMsg, v4.canonicalString, v4.stringToSign, signedURLMsg)
v4.Logger.Log(msg)
}
func (v4 *signer) build() {
v4.buildTime() // no depends
v4.buildCredentialString() // no depends
if v4.isPresign {
v4.buildQuery() // no depends
}
v4.buildCanonicalHeaders() // depends on cred string
v4.buildCanonicalString() // depends on canon headers / signed headers
v4.buildStringToSign() // depends on canon string
v4.buildSignature() // depends on string to sign
if v4.isPresign {
v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature
} else {
parts := []string{
authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString,
"SignedHeaders=" + v4.signedHeaders,
"Signature=" + v4.signature,
}
v4.Request.Header.Set("Authorization", strings.Join(parts, ", "))
}
}
func (v4 *signer) buildTime() {
v4.formattedTime = v4.Time.UTC().Format(timeFormat)
v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
if v4.isPresign {
duration := int64(v4.ExpireTime / time.Second)
v4.Query.Set("X-Amz-Date", v4.formattedTime)
v4.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
} else {
v4.Request.Header.Set("X-Amz-Date", v4.formattedTime)
}
}
func (v4 *signer) buildCredentialString() {
v4.credentialString = strings.Join([]string{
v4.formattedShortTime,
v4.Region,
v4.ServiceName,
"aws4_request",
}, "/")
if v4.isPresign {
v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString)
}
}
func (v4 *signer) buildQuery() {
for k, h := range v4.Request.Header {
if strings.HasPrefix(http.CanonicalHeaderKey(k), "X-Amz-") {
continue // never hoist x-amz-* headers, they must be signed
}
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // never hoist ignored headers
}
v4.Request.Header.Del(k)
v4.Query.Del(k)
for _, v := range h {
v4.Query.Add(k, v)
}
}
}
func (v4 *signer) buildCanonicalHeaders() {
var headers []string
headers = append(headers, "host")
for k := range v4.Request.Header {
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // ignored header
}
headers = append(headers, strings.ToLower(k))
}
sort.Strings(headers)
v4.signedHeaders = strings.Join(headers, ";")
if v4.isPresign {
v4.Query.Set("X-Amz-SignedHeaders", v4.signedHeaders)
}
headerValues := make([]string, len(headers))
for i, k := range headers {
if k == "host" {
headerValues[i] = "host:" + v4.Request.URL.Host
} else {
headerValues[i] = k + ":" +
strings.Join(v4.Request.Header[http.CanonicalHeaderKey(k)], ",")
}
}
v4.canonicalHeaders = strings.Join(headerValues, "\n")
}
func (v4 *signer) buildCanonicalString() {
v4.Request.URL.RawQuery = strings.Replace(v4.Query.Encode(), "+", "%20", -1)
uri := v4.Request.URL.Opaque
if uri != "" {
uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/")
} else {
uri = v4.Request.URL.Path
}
if uri == "" {
uri = "/"
}
if v4.ServiceName != "s3" {
uri = rest.EscapePath(uri, false)
}
v4.canonicalString = strings.Join([]string{
v4.Request.Method,
uri,
v4.Request.URL.RawQuery,
v4.canonicalHeaders + "\n",
v4.signedHeaders,
v4.bodyDigest(),
}, "\n")
}
func (v4 *signer) buildStringToSign() {
v4.stringToSign = strings.Join([]string{
authHeaderPrefix,
v4.formattedTime,
v4.credentialString,
hex.EncodeToString(makeSha256([]byte(v4.canonicalString))),
}, "\n")
}
func (v4 *signer) buildSignature() {
secret := v4.CredValues.SecretAccessKey
date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
region := makeHmac(date, []byte(v4.Region))
service := makeHmac(region, []byte(v4.ServiceName))
credentials := makeHmac(service, []byte("aws4_request"))
signature := makeHmac(credentials, []byte(v4.stringToSign))
v4.signature = hex.EncodeToString(signature)
}
func (v4 *signer) bodyDigest() string {
hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
if hash == "" {
if v4.isPresign && v4.ServiceName == "s3" {
hash = "UNSIGNED-PAYLOAD"
} else if v4.Body == nil {
hash = hex.EncodeToString(makeSha256([]byte{}))
} else {
hash = hex.EncodeToString(makeSha256Reader(v4.Body))
}
v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
}
return hash
}
// isRequestSigned returns if the request is currently signed or presigned
func (v4 *signer) isRequestSigned() bool {
if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" {
return true
}
if v4.Request.Header.Get("Authorization") != "" {
return true
}
return false
}
// unsign removes signing flags for both signed and presigned requests.
func (v4 *signer) removePresign() {
v4.Query.Del("X-Amz-Algorithm")
v4.Query.Del("X-Amz-Signature")
v4.Query.Del("X-Amz-Security-Token")
v4.Query.Del("X-Amz-Date")
v4.Query.Del("X-Amz-Expires")
v4.Query.Del("X-Amz-Credential")
v4.Query.Del("X-Amz-SignedHeaders")
}
func makeHmac(key []byte, data []byte) []byte {
hash := hmac.New(sha256.New, key)
hash.Write(data)
return hash.Sum(nil)
}
func makeSha256(data []byte) []byte {
hash := sha256.New()
hash.Write(data)
return hash.Sum(nil)
}
func makeSha256Reader(reader io.ReadSeeker) []byte {
hash := sha256.New()
start, _ := reader.Seek(0, 1)
defer reader.Seek(start, 0)
io.Copy(hash, reader)
return hash.Sum(nil)
}
@@ -1,252 +0,0 @@
package v4
import (
"net/http"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/awstesting"
)
func buildSigner(serviceName string, region string, signTime time.Time, expireTime time.Duration, body string) signer {
endpoint := "https://" + serviceName + "." + region + ".amazonaws.com"
reader := strings.NewReader(body)
req, _ := http.NewRequest("POST", endpoint, reader)
req.URL.Opaque = "//example.org/bucket/key-._~,!@#$%^&*()"
req.Header.Add("X-Amz-Target", "prefix.Operation")
req.Header.Add("Content-Type", "application/x-amz-json-1.0")
req.Header.Add("Content-Length", string(len(body)))
req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)")
return signer{
Request: req,
Time: signTime,
ExpireTime: expireTime,
Query: req.URL.Query(),
Body: reader,
ServiceName: serviceName,
Region: region,
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
}
}
func removeWS(text string) string {
text = strings.Replace(text, " ", "", -1)
text = strings.Replace(text, "\n", "", -1)
text = strings.Replace(text, "\t", "", -1)
return text
}
func assertEqual(t *testing.T, expected, given string) {
if removeWS(expected) != removeWS(given) {
t.Errorf("\nExpected: %s\nGiven: %s", expected, given)
}
}
func TestPresignRequest(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Unix(0, 0), 300*time.Second, "{}")
signer.sign()
expectedDate := "19700101T000000Z"
expectedHeaders := "host;x-amz-meta-other-header;x-amz-target"
expectedSig := "5eeedebf6f995145ce56daa02902d10485246d3defb34f97b973c1f40ab82d36"
expectedCred := "AKID/19700101/us-east-1/dynamodb/aws4_request"
q := signer.Request.URL.Query()
assert.Equal(t, expectedSig, q.Get("X-Amz-Signature"))
assert.Equal(t, expectedCred, q.Get("X-Amz-Credential"))
assert.Equal(t, expectedHeaders, q.Get("X-Amz-SignedHeaders"))
assert.Equal(t, expectedDate, q.Get("X-Amz-Date"))
}
func TestSignRequest(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Unix(0, 0), 0, "{}")
signer.sign()
expectedDate := "19700101T000000Z"
expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=host;x-amz-date;x-amz-meta-other-header;x-amz-security-token;x-amz-target, Signature=69ada33fec48180dab153576e4dd80c4e04124f80dda3eccfed8a67c2b91ed5e"
q := signer.Request.Header
assert.Equal(t, expectedSig, q.Get("Authorization"))
assert.Equal(t, expectedDate, q.Get("X-Amz-Date"))
}
func TestSignEmptyBody(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "")
signer.Body = nil
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", hash)
}
func TestSignBody(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "hello")
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash)
}
func TestSignSeekedBody(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, " hello")
signer.Body.Read(make([]byte, 3)) // consume first 3 bytes so body is now "hello"
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash)
start, _ := signer.Body.Seek(0, 1)
assert.Equal(t, int64(3), start)
}
func TestPresignEmptyBodyS3(t *testing.T) {
signer := buildSigner("s3", "us-east-1", time.Now(), 5*time.Minute, "hello")
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "UNSIGNED-PAYLOAD", hash)
}
func TestSignPrecomputedBodyChecksum(t *testing.T) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "hello")
signer.Request.Header.Set("X-Amz-Content-Sha256", "PRECOMPUTED")
signer.sign()
hash := signer.Request.Header.Get("X-Amz-Content-Sha256")
assert.Equal(t, "PRECOMPUTED", hash)
}
func TestAnonymousCredentials(t *testing.T) {
svc := awstesting.NewClient(&aws.Config{Credentials: credentials.AnonymousCredentials})
r := svc.NewRequest(
&request.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
Sign(r)
urlQ := r.HTTPRequest.URL.Query()
assert.Empty(t, urlQ.Get("X-Amz-Signature"))
assert.Empty(t, urlQ.Get("X-Amz-Credential"))
assert.Empty(t, urlQ.Get("X-Amz-SignedHeaders"))
assert.Empty(t, urlQ.Get("X-Amz-Date"))
hQ := r.HTTPRequest.Header
assert.Empty(t, hQ.Get("Authorization"))
assert.Empty(t, hQ.Get("X-Amz-Date"))
}
func TestIgnoreResignRequestWithValidCreds(t *testing.T) {
svc := awstesting.NewClient(&aws.Config{
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
Region: aws.String("us-west-2"),
})
r := svc.NewRequest(
&request.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
Sign(r)
sig := r.HTTPRequest.Header.Get("Authorization")
Sign(r)
assert.Equal(t, sig, r.HTTPRequest.Header.Get("Authorization"))
}
func TestIgnorePreResignRequestWithValidCreds(t *testing.T) {
svc := awstesting.NewClient(&aws.Config{
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
Region: aws.String("us-west-2"),
})
r := svc.NewRequest(
&request.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
r.ExpireTime = time.Minute * 10
Sign(r)
sig := r.HTTPRequest.Header.Get("X-Amz-Signature")
Sign(r)
assert.Equal(t, sig, r.HTTPRequest.Header.Get("X-Amz-Signature"))
}
func TestResignRequestExpiredCreds(t *testing.T) {
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
svc := awstesting.NewClient(&aws.Config{Credentials: creds})
r := svc.NewRequest(
&request.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
Sign(r)
querySig := r.HTTPRequest.Header.Get("Authorization")
creds.Expire()
Sign(r)
assert.NotEqual(t, querySig, r.HTTPRequest.Header.Get("Authorization"))
}
func TestPreResignRequestExpiredCreds(t *testing.T) {
provider := &credentials.StaticProvider{Value: credentials.Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "SESSION",
}}
creds := credentials.NewCredentials(provider)
svc := awstesting.NewClient(&aws.Config{Credentials: creds})
r := svc.NewRequest(
&request.Operation{
Name: "BatchGetItem",
HTTPMethod: "POST",
HTTPPath: "/",
},
nil,
nil,
)
r.ExpireTime = time.Minute * 10
Sign(r)
querySig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature")
creds.Expire()
r.Time = time.Now().Add(time.Hour * 48)
Sign(r)
assert.NotEqual(t, querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature"))
}
func BenchmarkPresignRequest(b *testing.B) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 300*time.Second, "{}")
for i := 0; i < b.N; i++ {
signer.sign()
}
}
func BenchmarkSignRequest(b *testing.B) {
signer := buildSigner("dynamodb", "us-east-1", time.Now(), 0, "{}")
for i := 0; i < b.N; i++ {
signer.sign()
}
}
File diff suppressed because it is too large Load Diff
@@ -1,125 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
package cloudwatch
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/query"
"github.com/aws/aws-sdk-go/private/signer/v4"
)
// This is the Amazon CloudWatch API Reference. This guide provides detailed
// information about Amazon CloudWatch actions, data types, parameters, and
// errors. For detailed information about Amazon CloudWatch features and their
// associated API calls, go to the Amazon CloudWatch Developer Guide (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide).
//
// Amazon CloudWatch is a web service that enables you to publish, monitor,
// and manage various metrics, as well as configure alarm actions based on data
// from metrics. For more information about this product go to http://aws.amazon.com/cloudwatch
// (http://aws.amazon.com/cloudwatch).
//
// For information about the namespace, metric names, and dimensions that
// other Amazon Web Services products use to send metrics to Cloudwatch, go
// to Amazon CloudWatch Metrics, Namespaces, and Dimensions Reference (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html)
// in the Amazon CloudWatch Developer Guide.
//
// Use the following links to get started using the Amazon CloudWatch API Reference:
//
// Actions (http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_Operations.html):
// An alphabetical list of all Amazon CloudWatch actions. Data Types (http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_Types.html):
// An alphabetical list of all Amazon CloudWatch data types. Common Parameters
// (http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CommonParameters.html):
// Parameters that all Query actions can use. Common Errors (http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CommonErrors.html):
// Client and server errors that all actions can return. Regions and Endpoints
// (http://docs.aws.amazon.com/general/latest/gr/index.html?rande.html): Itemized
// regions and endpoints for all AWS products. WSDL Location (http://monitoring.amazonaws.com/doc/2010-08-01/CloudWatch.wsdl):
// http://monitoring.amazonaws.com/doc/2010-08-01/CloudWatch.wsdl In addition
// to using the Amazon CloudWatch API, you can also use the following SDKs and
// third-party libraries to access Amazon CloudWatch programmatically.
//
// AWS SDK for Java Documentation (http://aws.amazon.com/documentation/sdkforjava/)
// AWS SDK for .NET Documentation (http://aws.amazon.com/documentation/sdkfornet/)
// AWS SDK for PHP Documentation (http://aws.amazon.com/documentation/sdkforphp/)
// AWS SDK for Ruby Documentation (http://aws.amazon.com/documentation/sdkforruby/)
// Developers in the AWS developer community also provide their own libraries,
// which you can find at the following AWS developer centers:
//
// AWS Java Developer Center (http://aws.amazon.com/java/) AWS PHP Developer
// Center (http://aws.amazon.com/php/) AWS Python Developer Center (http://aws.amazon.com/python/)
// AWS Ruby Developer Center (http://aws.amazon.com/ruby/) AWS Windows and .NET
// Developer Center (http://aws.amazon.com/net/)
//The service client's operations are safe to be used concurrently.
// It is not safe to mutate any of the client's properties though.
type CloudWatch struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// A ServiceName is the name of the service the client will make API calls to.
const ServiceName = "monitoring"
// New creates a new instance of the CloudWatch client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
// // Create a CloudWatch client from just a session.
// svc := cloudwatch.New(mySession)
//
// // Create a CloudWatch client with additional configuration
// svc := cloudwatch.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *CloudWatch {
c := p.ClientConfig(ServiceName, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *CloudWatch {
svc := &CloudWatch{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
SigningRegion: signingRegion,
Endpoint: endpoint,
APIVersion: "2010-08-01",
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBack(v4.Sign)
svc.Handlers.Build.PushBack(query.Build)
svc.Handlers.Unmarshal.PushBack(query.Unmarshal)
svc.Handlers.UnmarshalMeta.PushBack(query.UnmarshalMeta)
svc.Handlers.UnmarshalError.PushBack(query.UnmarshalError)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a CloudWatch operation and runs any
// custom request initialization.
func (c *CloudWatch) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}
@@ -1,24 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
src
-8
View File
@@ -1,8 +0,0 @@
language: go
go:
- 1.5.3
- tip
notifications:
email:
- ionathan@gmail.com
- marcosnils@gmail.com
-3
View File
@@ -1,3 +0,0 @@
test:
go get -v -d -t ./...
go test -v
-444
View File
@@ -1,444 +0,0 @@
[![Build Status](https://img.shields.io/travis/franela/goreq/master.svg)](https://travis-ci.org/franela/goreq)
[![GoDoc](https://godoc.org/github.com/franela/goreq?status.svg)](https://godoc.org/github.com/franela/goreq)
GoReq
=======
Simple and sane HTTP request library for Go language.
**Table of Contents**
- [Why GoReq?](#user-content-why-goreq)
- [How do I install it?](#user-content-how-do-i-install-it)
- [What can I do with it?](#user-content-what-can-i-do-with-it)
- [Making requests with different methods](#user-content-making-requests-with-different-methods)
- [GET](#user-content-get)
- [Tags](#user-content-tags)
- [POST](#user-content-post)
- [Sending payloads in the Body](#user-content-sending-payloads-in-the-body)
- [Specifiying request headers](#user-content-specifiying-request-headers)
- [Sending Cookies](#cookie-support)
- [Setting timeouts](#user-content-setting-timeouts)
- [Using the Response and Error](#user-content-using-the-response-and-error)
- [Receiving JSON](#user-content-receiving-json)
- [Sending/Receiving Compressed Payloads](#user-content-sendingreceiving-compressed-payloads)
- [Using gzip compression:](#user-content-using-gzip-compression)
- [Using deflate compression:](#user-content-using-deflate-compression)
- [Using compressed responses:](#user-content-using-compressed-responses)
- [Proxy](#proxy)
- [Debugging requests](#debug)
- [Getting raw Request & Response](#getting-raw-request--response)
- [TODO:](#user-content-todo)
Why GoReq?
==========
Go has very nice native libraries that allows you to do lots of cool things. But sometimes those libraries are too low level, which means that to do a simple thing, like an HTTP Request, it takes some time. And if you want to do something as simple as adding a timeout to a request, you will end up writing several lines of code.
This is why we think GoReq is useful. Because you can do all your HTTP requests in a very simple and comprehensive way, while enabling you to do more advanced stuff by giving you access to the native API.
How do I install it?
====================
```bash
go get github.com/franela/goreq
```
What can I do with it?
======================
## Making requests with different methods
#### GET
```go
res, err := goreq.Request{ Uri: "http://www.google.com" }.Do()
```
GoReq default method is GET.
You can also set value to GET method easily
```go
type Item struct {
Limit int
Skip int
Fields string
}
item := Item {
Limit: 3,
Skip: 5,
Fields: "Value",
}
res, err := goreq.Request{
Uri: "http://localhost:3000/",
QueryString: item,
}.Do()
```
The sample above will send `http://localhost:3000/?limit=3&skip=5&fields=Value`
Alternatively the `url` tag can be used in struct fields to customize encoding properties
```go
type Item struct {
TheLimit int `url:"the_limit"`
TheSkip string `url:"the_skip,omitempty"`
TheFields string `url:"-"`
}
item := Item {
TheLimit: 3,
TheSkip: "",
TheFields: "Value",
}
res, err := goreq.Request{
Uri: "http://localhost:3000/",
QueryString: item,
}.Do()
```
The sample above will send `http://localhost:3000/?the_limit=3`
QueryString also support url.Values
```go
item := url.Values{}
item.Set("Limit", 3)
item.Add("Field", "somefield")
item.Add("Field", "someotherfield")
res, err := goreq.Request{
Uri: "http://localhost:3000/",
QueryString: item,
}.Do()
```
The sample above will send `http://localhost:3000/?limit=3&field=somefield&field=someotherfield`
### Tags
Struct field `url` tag is mainly used as the request parameter name.
Tags can be comma separated multiple values, 1st value is for naming and rest has special meanings.
- special tag for 1st value
- `-`: value is ignored if set this
- special tag for rest 2nd value
- `omitempty`: zero-value is ignored if set this
- `squash`: the fields of embedded struct is used for parameter
#### Tag Examples
```go
type Place struct {
Country string `url:"country"`
City string `url:"city"`
ZipCode string `url:"zipcode,omitempty"`
}
type Person struct {
Place `url:",squash"`
FirstName string `url:"first_name"`
LastName string `url:"last_name"`
Age string `url:"age,omitempty"`
Password string `url:"-"`
}
johnbull := Person{
Place: Place{ // squash the embedded struct value
Country: "UK",
City: "London",
ZipCode: "SW1",
},
FirstName: "John",
LastName: "Doe",
Age: "35",
Password: "my-secret", // ignored for parameter
}
goreq.Request{
Uri: "http://localhost/",
QueryString: johnbull,
}.Do()
// => `http://localhost/?first_name=John&last_name=Doe&age=35&country=UK&city=London&zip_code=SW1`
// age and zipcode will be ignored because of `omitempty`
// but firstname isn't.
samurai := Person{
Place: Place{ // squash the embedded struct value
Country: "Japan",
City: "Tokyo",
},
LastName: "Yagyu",
}
goreq.Request{
Uri: "http://localhost/",
QueryString: samurai,
}.Do()
// => `http://localhost/?first_name=&last_name=yagyu&country=Japan&city=Tokyo`
```
#### POST
```go
res, err := goreq.Request{ Method: "POST", Uri: "http://www.google.com" }.Do()
```
## Sending payloads in the Body
You can send ```string```, ```Reader``` or ```interface{}``` in the body. The first two will be sent as text. The last one will be marshalled to JSON, if possible.
```go
type Item struct {
Id int
Name string
}
item := Item{ Id: 1111, Name: "foobar" }
res, err := goreq.Request{
Method: "POST",
Uri: "http://www.google.com",
Body: item,
}.Do()
```
## Specifiying request headers
We think that most of the times the request headers that you use are: ```Host```, ```Content-Type```, ```Accept``` and ```User-Agent```. This is why we decided to make it very easy to set these headers.
```go
res, err := goreq.Request{
Uri: "http://www.google.com",
Host: "foobar.com",
Accept: "application/json",
ContentType: "application/json",
UserAgent: "goreq",
}.Do()
```
But sometimes you need to set other headers. You can still do it.
```go
req := goreq.Request{ Uri: "http://www.google.com" }
req.AddHeader("X-Custom", "somevalue")
req.Do()
```
Alternatively you can use the `WithHeader` function to keep the syntax short
```go
res, err = goreq.Request{ Uri: "http://www.google.com" }.WithHeader("X-Custom", "somevalue").Do()
```
## Cookie support
Cookies can be either set at the request level by sending a [CookieJar](http://golang.org/pkg/net/http/cookiejar/) in the `CookieJar` request field
or you can use goreq's one-liner WithCookie method as shown below
```go
res, err := goreq.Request{
Uri: "http://www.google.com",
}.
WithCookie(&http.Cookie{Name: "c1", Value: "v1"}).
Do()
```
## Setting timeouts
GoReq supports 2 kind of timeouts. A general connection timeout and a request specific one. By default the connection timeout is of 1 second. There is no default for request timeout, which means it will wait forever.
You can change the connection timeout doing:
```go
goreq.SetConnectTimeout(100 * time.Millisecond)
```
And specify the request timeout doing:
```go
res, err := goreq.Request{
Uri: "http://www.google.com",
Timeout: 500 * time.Millisecond,
}.Do()
```
## Using the Response and Error
GoReq will always return 2 values: a ```Response``` and an ```Error```.
If ```Error``` is not ```nil``` it means that an error happened while doing the request and you shouldn't use the ```Response``` in any way.
You can check what happened by getting the error message:
```go
fmt.Println(err.Error())
```
And to make it easy to know if it was a timeout error, you can ask the error or return it:
```go
if serr, ok := err.(*goreq.Error); ok {
if serr.Timeout() {
...
}
}
return err
```
If you don't get an error, you can safely use the ```Response```.
```go
res.Uri // return final URL location of the response (fulfilled after redirect was made)
res.StatusCode // return the status code of the response
res.Body // gives you access to the body
res.Body.ToString() // will return the body as a string
res.Header.Get("Content-Type") // gives you access to all the response headers
```
Remember that you should **always** close `res.Body` if it's not `nil`
## Receiving JSON
GoReq will help you to receive and unmarshal JSON.
```go
type Item struct {
Id int
Name string
}
var item Item
res.Body.FromJsonTo(&item)
```
## Sending/Receiving Compressed Payloads
GoReq supports gzip, deflate and zlib compression of requests' body and transparent decompression of responses provided they have a correct `Content-Encoding` header.
#####Using gzip compression:
```go
res, err := goreq.Request{
Method: "POST",
Uri: "http://www.google.com",
Body: item,
Compression: goreq.Gzip(),
}.Do()
```
#####Using deflate/zlib compression:
```go
res, err := goreq.Request{
Method: "POST",
Uri: "http://www.google.com",
Body: item,
Compression: goreq.Deflate(),
}.Do()
```
#####Using compressed responses:
If servers replies a correct and matching `Content-Encoding` header (gzip requires `Content-Encoding: gzip` and deflate `Content-Encoding: deflate`) goreq transparently decompresses the response so the previous example should always work:
```go
type Item struct {
Id int
Name string
}
res, err := goreq.Request{
Method: "POST",
Uri: "http://www.google.com",
Body: item,
Compression: goreq.Gzip(),
}.Do()
var item Item
res.Body.FromJsonTo(&item)
```
If no `Content-Encoding` header is replied by the server GoReq will return the crude response.
## Proxy
If you need to use a proxy for your requests GoReq supports the standard `http_proxy` env variable as well as manually setting the proxy for each request
```go
res, err := goreq.Request{
Method: "GET",
Proxy: "http://myproxy:myproxyport",
Uri: "http://www.google.com",
}.Do()
```
### Proxy basic auth is also supported
```go
res, err := goreq.Request{
Method: "GET",
Proxy: "http://user:pass@myproxy:myproxyport",
Uri: "http://www.google.com",
}.Do()
```
## Debug
If you need to debug your http requests, it can print the http request detail.
```go
res, err := goreq.Request{
Method: "GET",
Uri: "http://www.google.com",
Compression: goreq.Gzip(),
ShowDebug: true,
}.Do()
fmt.Println(res, err)
```
and it will print the log:
```
GET / HTTP/1.1
Host: www.google.com
Accept:
Accept-Encoding: gzip
Content-Encoding: gzip
Content-Type:
```
### Getting raw Request & Response
To get the Request:
```go
req := goreq.Request{
Host: "foobar.com",
}
//req.Request will return a new instance of an http.Request so you can safely use it for something else
request, _ := req.NewRequest()
```
To get the Response:
```go
res, err := goreq.Request{
Method: "GET",
Uri: "http://www.google.com",
Compression: goreq.Gzip(),
ShowDebug: true,
}.Do()
// res.Response will contain the original http.Response structure
fmt.Println(res.Response, err)
```
TODO:
-----
We do have a couple of [issues](https://github.com/franela/goreq/issues) pending we'll be addressing soon. But feel free to
contribute and send us PRs (with tests please :smile:).
-491
View File
@@ -1,491 +0,0 @@
package goreq
import (
"bufio"
"bytes"
"compress/gzip"
"compress/zlib"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"net/http"
"net/http/httputil"
"net/url"
"reflect"
"strings"
"time"
)
type itimeout interface {
Timeout() bool
}
type Request struct {
headers []headerTuple
cookies []*http.Cookie
Method string
Uri string
Body interface{}
QueryString interface{}
Timeout time.Duration
ContentType string
Accept string
Host string
UserAgent string
Insecure bool
MaxRedirects int
RedirectHeaders bool
Proxy string
Compression *compression
BasicAuthUsername string
BasicAuthPassword string
CookieJar http.CookieJar
ShowDebug bool
OnBeforeRequest func(goreq *Request, httpreq *http.Request)
}
type compression struct {
writer func(buffer io.Writer) (io.WriteCloser, error)
reader func(buffer io.Reader) (io.ReadCloser, error)
ContentEncoding string
}
type Response struct {
*http.Response
Uri string
Body *Body
req *http.Request
}
func (r Response) CancelRequest() {
cancelRequest(DefaultTransport, r.req)
}
func cancelRequest(transport interface{}, r *http.Request) {
if tp, ok := transport.(transportRequestCanceler); ok {
tp.CancelRequest(r)
}
}
type headerTuple struct {
name string
value string
}
type Body struct {
reader io.ReadCloser
compressedReader io.ReadCloser
}
type Error struct {
timeout bool
Err error
}
type transportRequestCanceler interface {
CancelRequest(*http.Request)
}
func (e *Error) Timeout() bool {
return e.timeout
}
func (e *Error) Error() string {
return e.Err.Error()
}
func (b *Body) Read(p []byte) (int, error) {
if b.compressedReader != nil {
return b.compressedReader.Read(p)
}
return b.reader.Read(p)
}
func (b *Body) Close() error {
err := b.reader.Close()
if b.compressedReader != nil {
return b.compressedReader.Close()
}
return err
}
func (b *Body) FromJsonTo(o interface{}) error {
return json.NewDecoder(b).Decode(o)
}
func (b *Body) ToString() (string, error) {
body, err := ioutil.ReadAll(b)
if err != nil {
return "", err
}
return string(body), nil
}
func Gzip() *compression {
reader := func(buffer io.Reader) (io.ReadCloser, error) {
return gzip.NewReader(buffer)
}
writer := func(buffer io.Writer) (io.WriteCloser, error) {
return gzip.NewWriter(buffer), nil
}
return &compression{writer: writer, reader: reader, ContentEncoding: "gzip"}
}
func Deflate() *compression {
reader := func(buffer io.Reader) (io.ReadCloser, error) {
return zlib.NewReader(buffer)
}
writer := func(buffer io.Writer) (io.WriteCloser, error) {
return zlib.NewWriter(buffer), nil
}
return &compression{writer: writer, reader: reader, ContentEncoding: "deflate"}
}
func Zlib() *compression {
return Deflate()
}
func paramParse(query interface{}) (string, error) {
switch query.(type) {
case url.Values:
return query.(url.Values).Encode(), nil
case *url.Values:
return query.(*url.Values).Encode(), nil
default:
var v = &url.Values{}
err := paramParseStruct(v, query)
return v.Encode(), err
}
}
func paramParseStruct(v *url.Values, query interface{}) error {
var (
s = reflect.ValueOf(query)
t = reflect.TypeOf(query)
)
for t.Kind() == reflect.Ptr || t.Kind() == reflect.Interface {
s = s.Elem()
t = s.Type()
}
if t.Kind() != reflect.Struct {
return errors.New("Can not parse QueryString.")
}
for i := 0; i < t.NumField(); i++ {
var name string
field := s.Field(i)
typeField := t.Field(i)
if !field.CanInterface() {
continue
}
urlTag := typeField.Tag.Get("url")
if urlTag == "-" {
continue
}
name, opts := parseTag(urlTag)
var omitEmpty, squash bool
omitEmpty = opts.Contains("omitempty")
squash = opts.Contains("squash")
if squash {
err := paramParseStruct(v, field.Interface())
if err != nil {
return err
}
continue
}
if urlTag == "" {
name = strings.ToLower(typeField.Name)
}
if val := fmt.Sprintf("%v", field.Interface()); !(omitEmpty && len(val) == 0) {
v.Add(name, val)
}
}
return nil
}
func prepareRequestBody(b interface{}) (io.Reader, error) {
switch b.(type) {
case string:
// treat is as text
return strings.NewReader(b.(string)), nil
case io.Reader:
// treat is as text
return b.(io.Reader), nil
case []byte:
//treat as byte array
return bytes.NewReader(b.([]byte)), nil
case nil:
return nil, nil
default:
// try to jsonify it
j, err := json.Marshal(b)
if err == nil {
return bytes.NewReader(j), nil
}
return nil, err
}
}
var DefaultDialer = &net.Dialer{Timeout: 1000 * time.Millisecond}
var DefaultTransport http.RoundTripper = &http.Transport{Dial: DefaultDialer.Dial, Proxy: http.ProxyFromEnvironment}
var DefaultClient = &http.Client{Transport: DefaultTransport}
var proxyTransport http.RoundTripper
var proxyClient *http.Client
func SetConnectTimeout(duration time.Duration) {
DefaultDialer.Timeout = duration
}
func (r *Request) AddHeader(name string, value string) {
if r.headers == nil {
r.headers = []headerTuple{}
}
r.headers = append(r.headers, headerTuple{name: name, value: value})
}
func (r Request) WithHeader(name string, value string) Request {
r.AddHeader(name, value)
return r
}
func (r *Request) AddCookie(c *http.Cookie) {
r.cookies = append(r.cookies, c)
}
func (r Request) WithCookie(c *http.Cookie) Request {
r.AddCookie(c)
return r
}
func (r Request) Do() (*Response, error) {
var client = DefaultClient
var transport = DefaultTransport
var resUri string
var redirectFailed bool
r.Method = valueOrDefault(r.Method, "GET")
// use a client with a cookie jar if necessary. We create a new client not
// to modify the default one.
if r.CookieJar != nil {
client = &http.Client{
Transport: transport,
Jar: r.CookieJar,
}
}
if r.Proxy != "" {
proxyUrl, err := url.Parse(r.Proxy)
if err != nil {
// proxy address is in a wrong format
return nil, &Error{Err: err}
}
//If jar is specified new client needs to be built
if proxyTransport == nil || client.Jar != nil {
proxyTransport = &http.Transport{Dial: DefaultDialer.Dial, Proxy: http.ProxyURL(proxyUrl)}
proxyClient = &http.Client{Transport: proxyTransport, Jar: client.Jar}
} else if proxyTransport, ok := proxyTransport.(*http.Transport); ok {
proxyTransport.Proxy = http.ProxyURL(proxyUrl)
}
transport = proxyTransport
client = proxyClient
}
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if len(via) > r.MaxRedirects {
redirectFailed = true
return errors.New("Error redirecting. MaxRedirects reached")
}
resUri = req.URL.String()
//By default Golang will not redirect request headers
// https://code.google.com/p/go/issues/detail?id=4800&q=request%20header
if r.RedirectHeaders {
for key, val := range via[0].Header {
req.Header[key] = val
}
}
return nil
}
if transport, ok := transport.(*http.Transport); ok {
if r.Insecure {
if transport.TLSClientConfig != nil {
transport.TLSClientConfig.InsecureSkipVerify = true
} else {
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
}
} else if transport.TLSClientConfig != nil {
// the default TLS client (when transport.TLSClientConfig==nil) is
// already set to verify, so do nothing in that case
transport.TLSClientConfig.InsecureSkipVerify = false
}
}
req, err := r.NewRequest()
if err != nil {
// we couldn't parse the URL.
return nil, &Error{Err: err}
}
timeout := false
if r.Timeout > 0 {
client.Timeout = r.Timeout
}
if r.ShowDebug {
dump, err := httputil.DumpRequest(req, true)
if err != nil {
log.Println(err)
}
log.Println(string(dump))
}
if r.OnBeforeRequest != nil {
r.OnBeforeRequest(&r, req)
}
res, err := client.Do(req)
if err != nil {
if !timeout {
if t, ok := err.(itimeout); ok {
timeout = t.Timeout()
}
if ue, ok := err.(*url.Error); ok {
if t, ok := ue.Err.(itimeout); ok {
timeout = t.Timeout()
}
}
}
var response *Response
//If redirect fails we still want to return response data
if redirectFailed {
if res != nil {
response = &Response{res, resUri, &Body{reader: res.Body}, req}
} else {
response = &Response{res, resUri, nil, req}
}
}
//If redirect fails and we haven't set a redirect count we shouldn't return an error
if redirectFailed && r.MaxRedirects == 0 {
return response, nil
}
return response, &Error{timeout: timeout, Err: err}
}
if r.Compression != nil && strings.Contains(res.Header.Get("Content-Encoding"), r.Compression.ContentEncoding) {
compressedReader, err := r.Compression.reader(res.Body)
if err != nil {
return nil, &Error{Err: err}
}
return &Response{res, resUri, &Body{reader: res.Body, compressedReader: compressedReader}, req}, nil
}
return &Response{res, resUri, &Body{reader: res.Body}, req}, nil
}
func (r Request) addHeaders(headersMap http.Header) {
if len(r.UserAgent) > 0 {
headersMap.Add("User-Agent", r.UserAgent)
}
if r.Accept != "" {
headersMap.Add("Accept", r.Accept)
}
if r.ContentType != "" {
headersMap.Add("Content-Type", r.ContentType)
}
}
func (r Request) NewRequest() (*http.Request, error) {
b, e := prepareRequestBody(r.Body)
if e != nil {
// there was a problem marshaling the body
return nil, &Error{Err: e}
}
if r.QueryString != nil {
param, e := paramParse(r.QueryString)
if e != nil {
return nil, &Error{Err: e}
}
r.Uri = r.Uri + "?" + param
}
var bodyReader io.Reader
if b != nil && r.Compression != nil {
buffer := bytes.NewBuffer([]byte{})
readBuffer := bufio.NewReader(b)
writer, err := r.Compression.writer(buffer)
if err != nil {
return nil, &Error{Err: err}
}
_, e = readBuffer.WriteTo(writer)
writer.Close()
if e != nil {
return nil, &Error{Err: e}
}
bodyReader = buffer
} else {
bodyReader = b
}
req, err := http.NewRequest(r.Method, r.Uri, bodyReader)
if err != nil {
return nil, err
}
// add headers to the request
req.Host = r.Host
r.addHeaders(req.Header)
if r.Compression != nil {
req.Header.Add("Content-Encoding", r.Compression.ContentEncoding)
req.Header.Add("Accept-Encoding", r.Compression.ContentEncoding)
}
if r.headers != nil {
for _, header := range r.headers {
req.Header.Add(header.name, header.value)
}
}
//use basic auth if required
if r.BasicAuthUsername != "" {
req.SetBasicAuth(r.BasicAuthUsername, r.BasicAuthPassword)
}
for _, c := range r.cookies {
req.AddCookie(c)
}
return req, nil
}
// Return value if nonempty, def otherwise.
func valueOrDefault(value, def string) string {
if value != "" {
return value
}
return def
}
-64
View File
@@ -1,64 +0,0 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goreq
import (
"strings"
"unicode"
)
// tagOptions is the string following a comma in a struct field's "json"
// tag, or the empty string. It does not include the leading comma.
type tagOptions string
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
}
// Contains reports whether a comma-separated list of options
// contains a particular substr flag. substr must be surrounded by a
// string boundary or commas.
func (o tagOptions) Contains(optionName string) bool {
if len(o) == 0 {
return false
}
s := string(o)
for s != "" {
var next string
i := strings.Index(s, ",")
if i >= 0 {
s, next = s[:i], s[i+1:]
}
if s == optionName {
return true
}
s = next
}
return false
}
func isValidTag(s string) bool {
if s == "" {
return false
}
for _, c := range s {
switch {
case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
// Backslash and quote chars are reserved, but
// otherwise any punctuation chars are allowed
// in a tag name.
default:
if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
return false
}
}
}
return true
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

-201
View File
@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -1,35 +0,0 @@
package commands
import (
"github.com/codegangsta/cli"
)
type CommandLine interface {
ShowHelp()
ShowVersion()
Application() *cli.App
Args() cli.Args
Bool(name string) bool
Int(name string) int
String(name string) string
StringSlice(name string) []string
GlobalString(name string) string
FlagNames() (names []string)
Generic(name string) interface{}
}
type contextCommandLine struct {
*cli.Context
}
func (c *contextCommandLine) ShowHelp() {
cli.ShowCommandHelp(c.Context, c.Command.Name)
}
func (c *contextCommandLine) ShowVersion() {
cli.ShowVersion(c.Context)
}
func (c *contextCommandLine) Application() *cli.App {
return c.App
}
@@ -1,48 +0,0 @@
package commands
import (
"github.com/codegangsta/cli"
"github.com/grafana/grafana-cli/pkg/log"
)
func runCommand(command func(commandLine CommandLine) error) func(context *cli.Context) {
return func(context *cli.Context) {
cmd := &contextCommandLine{context}
if err := command(cmd); err != nil {
log.Errorf("%v\n\n", err)
cmd.ShowHelp()
} else {
log.Info("Restart grafana after installing plugins . <service grafana-server restart>\n")
}
}
}
var Commands = []cli.Command{
{
Name: "install",
Usage: "installs stuff",
Action: runCommand(installCommand),
}, {
Name: "list-remote",
Usage: "list remote available plugins",
Action: runCommand(listremoteCommand),
}, {
Name: "upgrade",
Usage: "upgrades one plugin",
Action: runCommand(upgradeCommand),
}, {
Name: "upgrade-all",
Usage: "upgrades all your installed plugins",
Action: runCommand(upgradeAllCommand),
}, {
Name: "ls",
Usage: "list all installed plugins",
Action: runCommand(lsCommand),
}, {
Name: "remove",
Usage: "removes stuff",
Action: runCommand(removeCommand),
},
}
@@ -1,95 +0,0 @@
package commandstest
import (
"github.com/codegangsta/cli"
)
type FakeFlagger struct {
Data map[string]interface{}
}
type FakeCommandLine struct {
LocalFlags, GlobalFlags *FakeFlagger
HelpShown, VersionShown bool
CliArgs []string
}
func (ff FakeFlagger) String(key string) string {
if value, ok := ff.Data[key]; ok {
return value.(string)
}
return ""
}
func (ff FakeFlagger) StringSlice(key string) []string {
if value, ok := ff.Data[key]; ok {
return value.([]string)
}
return []string{}
}
func (ff FakeFlagger) Int(key string) int {
if value, ok := ff.Data[key]; ok {
return value.(int)
}
return 0
}
func (ff FakeFlagger) Bool(key string) bool {
if value, ok := ff.Data[key]; ok {
return value.(bool)
}
return false
}
func (fcli *FakeCommandLine) String(key string) string {
return fcli.LocalFlags.String(key)
}
func (fcli *FakeCommandLine) StringSlice(key string) []string {
return fcli.LocalFlags.StringSlice(key)
}
func (fcli *FakeCommandLine) Int(key string) int {
return fcli.LocalFlags.Int(key)
}
func (fcli *FakeCommandLine) Bool(key string) bool {
if fcli.LocalFlags == nil {
return false
}
return fcli.LocalFlags.Bool(key)
}
func (fcli *FakeCommandLine) GlobalString(key string) string {
return fcli.GlobalFlags.String(key)
}
func (fcli *FakeCommandLine) Generic(name string) interface{} {
return fcli.LocalFlags.Data[name]
}
func (fcli *FakeCommandLine) FlagNames() []string {
flagNames := []string{}
for key := range fcli.LocalFlags.Data {
flagNames = append(flagNames, key)
}
return flagNames
}
func (fcli *FakeCommandLine) ShowHelp() {
fcli.HelpShown = true
}
func (fcli *FakeCommandLine) Application() *cli.App {
return cli.NewApp()
}
func (fcli *FakeCommandLine) Args() cli.Args {
return fcli.CliArgs
}
func (fcli *FakeCommandLine) ShowVersion() {
fcli.VersionShown = true
}
@@ -1,55 +0,0 @@
package commandstest
import (
"os"
"time"
)
type FakeIoUtil struct {
FakeReadDir []os.FileInfo
FakeIsDirectory bool
}
func (util *FakeIoUtil) Stat(path string) (os.FileInfo, error) {
return FakeFileInfo{IsDirectory: util.FakeIsDirectory}, nil
}
func (util *FakeIoUtil) RemoveAll(path string) error {
return nil
}
func (util *FakeIoUtil) ReadDir(path string) ([]os.FileInfo, error) {
return util.FakeReadDir, nil
}
func (i *FakeIoUtil) ReadFile(filename string) ([]byte, error) {
return make([]byte, 0), nil
}
type FakeFileInfo struct {
IsDirectory bool
}
func (ffi FakeFileInfo) IsDir() bool {
return ffi.IsDirectory
}
func (ffi FakeFileInfo) Size() int64 {
return 1
}
func (ffi FakeFileInfo) Mode() os.FileMode {
return 0777
}
func (ffi FakeFileInfo) Name() string {
return ""
}
func (ffi FakeFileInfo) ModTime() time.Time {
return time.Time{}
}
func (ffi FakeFileInfo) Sys() interface{} {
return nil
}
@@ -1,146 +0,0 @@
package commands
import (
"archive/zip"
"bytes"
"errors"
"github.com/grafana/grafana-cli/pkg/log"
m "github.com/grafana/grafana-cli/pkg/models"
services "github.com/grafana/grafana-cli/pkg/services"
"io"
"io/ioutil"
"net/http"
"os"
"path"
"regexp"
)
func validateInput(c CommandLine, pluginFolder string) error {
arg := c.Args().First()
if arg == "" {
return errors.New("please specify plugin to install")
}
pluginDir := c.GlobalString("path")
if pluginDir == "" {
return errors.New("missing path flag")
}
fileinfo, err := os.Stat(pluginDir)
if err != nil && !fileinfo.IsDir() {
return errors.New("path is not a directory")
}
return nil
}
func installCommand(c CommandLine) error {
pluginFolder := c.GlobalString("path")
if err := validateInput(c, pluginFolder); err != nil {
return err
}
pluginToInstall := c.Args().First()
version := c.Args().Get(1)
log.Infof("version: %v\n", version)
return InstallPlugin(pluginToInstall, pluginFolder, version)
}
func InstallPlugin(pluginName, pluginFolder, version string) error {
plugin, err := services.GetPlugin(pluginName)
if err != nil {
return err
}
v, err := SelectVersion(plugin, version)
if err != nil {
return err
}
url := v.Url
commit := v.Commit
downloadURL := url + "/archive/" + commit + ".zip"
log.Infof("installing %v @ %v\n", plugin.Id, version)
log.Infof("from url: %v\n", downloadURL)
log.Infof("on commit: %v\n", commit)
log.Infof("into: %v\n", pluginFolder)
err = downloadFile(plugin.Id, pluginFolder, downloadURL)
if err == nil {
log.Info("Installed %s successfully ✔\n", plugin.Id)
}
res := services.ReadPlugin(pluginFolder, pluginName)
for _, v := range res.Dependency.Plugins {
log.Infof("Depends on %s install!\n", v.Id)
//Todo: uncomment this code once the repo is more correct.
//InstallPlugin(v.Id, pluginFolder, "")
}
return err
}
func SelectVersion(plugin m.Plugin, version string) (m.Version, error) {
if version == "" {
return plugin.Versions[0], nil
}
for _, v := range plugin.Versions {
if v.Version == version {
return v, nil
}
}
return m.Version{}, errors.New("Could not find the version your looking for")
}
func RemoveGitBuildFromname(pluginname, filename string) string {
r := regexp.MustCompile("^[a-zA-Z0-9_.-]*/")
return r.ReplaceAllString(filename, pluginname+"/")
}
func downloadFile(pluginName, filepath, url string) (err error) {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
r, err := zip.NewReader(bytes.NewReader(body), resp.ContentLength)
if err != nil {
return err
}
for _, zf := range r.File {
newfile := path.Join(filepath, RemoveGitBuildFromname(pluginName, zf.Name))
if zf.FileInfo().IsDir() {
os.Mkdir(newfile, 0777)
} else {
dst, err := os.Create(newfile)
if err != nil {
log.Errorf("%v", err)
}
defer dst.Close()
src, err := zf.Open()
if err != nil {
log.Errorf("%v", err)
}
defer src.Close()
io.Copy(dst, src)
}
}
return nil
}
@@ -1,20 +0,0 @@
package commands
import (
"github.com/grafana/grafana-cli/pkg/log"
"github.com/grafana/grafana-cli/pkg/services"
)
func listremoteCommand(c CommandLine) error {
plugin, err := services.ListAllPlugins()
if err != nil {
return err
}
for _, i := range plugin.Plugins {
log.Infof("id: %v version:\n", i.Id)
}
return nil
}
@@ -1,49 +0,0 @@
package commands
import (
"errors"
"github.com/grafana/grafana-cli/pkg/log"
m "github.com/grafana/grafana-cli/pkg/models"
s "github.com/grafana/grafana-cli/pkg/services"
)
var getPlugins func(path string) []m.InstalledPlugin
var GetStat m.IoUtil
func init() {
getPlugins = s.GetLocalPlugins
GetStat = s.IoUtil
}
func validateCommand(pluginDir string) error {
if pluginDir == "" {
return errors.New("missing path flag")
}
log.Info("plugindir: " + pluginDir + "\n")
pluginDirInfo, err := GetStat.Stat(pluginDir)
if err != nil {
return errors.New("missing path flag")
}
if pluginDirInfo.IsDir() == false {
return errors.New("plugin path is not a directory")
}
return nil
}
func lsCommand(c CommandLine) error {
pluginDir := c.GlobalString("path")
if err := validateCommand(pluginDir); err != nil {
return err
}
for _, plugin := range getPlugins(pluginDir) {
log.Infof("plugin: %s @ %s \n", plugin.Name, plugin.Info.Version)
}
return nil
}
@@ -1,35 +0,0 @@
package commands
import (
"errors"
"github.com/grafana/grafana-cli/pkg/log"
m "github.com/grafana/grafana-cli/pkg/models"
services "github.com/grafana/grafana-cli/pkg/services"
)
var getPluginss func(path string) []m.InstalledPlugin = services.GetLocalPlugins
var removePlugin func(pluginPath, id string) error = services.RemoveInstalledPlugin
func removeCommand(c CommandLine) error {
pluginPath := c.GlobalString("path")
localPlugins := getPluginss(pluginPath)
log.Info("remove!\n")
plugin := c.Args().First()
log.Info("plugin: " + plugin + "\n")
if plugin == "" {
return errors.New("Missing which plugin parameter")
}
log.Infof("plugins : \n%v\n", localPlugins)
for _, p := range localPlugins {
log.Infof("is %s == %s ? %v", p.Id, c.Args().First(), p.Id == c.Args().First())
if p.Id == c.Args().First() {
removePlugin(pluginPath, p.Id)
}
}
return nil
}
@@ -1,61 +0,0 @@
package commands
import (
"github.com/grafana/grafana-cli/pkg/log"
m "github.com/grafana/grafana-cli/pkg/models"
services "github.com/grafana/grafana-cli/pkg/services"
"github.com/hashicorp/go-version"
)
func ShouldUpgrade(installed string, remote m.Plugin) bool {
installedVersion, err1 := version.NewVersion(installed)
if err1 != nil {
return false
}
for _, v := range remote.Versions {
remoteVersion, err2 := version.NewVersion(v.Version)
if err2 == nil {
if installedVersion.LessThan(remoteVersion) {
return true
}
}
}
return false
}
func upgradeAllCommand(c CommandLine) error {
pluginDir := c.GlobalString("path")
localPlugins := services.GetLocalPlugins(pluginDir)
remotePlugins, err := services.ListAllPlugins()
if err != nil {
return err
}
pluginsToUpgrade := make([]m.InstalledPlugin, 0)
for _, localPlugin := range localPlugins {
for _, remotePlugin := range remotePlugins.Plugins {
if localPlugin.Id == remotePlugin.Id {
if ShouldUpgrade(localPlugin.Info.Version, remotePlugin) {
pluginsToUpgrade = append(pluginsToUpgrade, localPlugin)
}
}
}
}
for _, p := range pluginsToUpgrade {
log.Infof("lets upgrade %v \n", p)
services.RemoveInstalledPlugin(pluginDir, p.Id)
InstallPlugin(p.Id, pluginDir, "")
}
return nil
}
@@ -1,9 +0,0 @@
package commands
import (
"errors"
)
func upgradeCommand(c CommandLine) error {
return errors.New("Not yet Implemented")
}
@@ -1,48 +0,0 @@
package models
import (
"os"
)
type InstalledPlugin struct {
Id string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Info PluginInfo `json:"info"`
Dependency Dependency `json:"dependencies"`
}
type Dependency struct {
GrafanaVersion string `json:"grafanaVersion"`
Plugins []Plugin `json:"plugins"`
}
type PluginInfo struct {
Version string `json:"version"`
Updated string `json:"updated"`
}
type Plugin struct {
Id string `json:"id"`
Category string `json:"category"`
Versions []Version `json:"versions"`
}
type Version struct {
Commit string `json:"commit"`
Url string `json:"url"`
Version string `json:"version"`
}
type PluginRepo struct {
Plugins []Plugin `json:"plugins"`
Version string `json:"version"`
}
type IoUtil interface {
Stat(path string) (os.FileInfo, error)
RemoveAll(path string) error
ReadDir(path string) ([]os.FileInfo, error)
ReadFile(filename string) ([]byte, error)
}
@@ -1,28 +0,0 @@
package services
import (
m "github.com/grafana/grafana-cli/pkg/models"
"io/ioutil"
"os"
)
var IoUtil m.IoUtil = IoUtilImp{}
type IoUtilImp struct {
}
func (i IoUtilImp) Stat(path string) (os.FileInfo, error) {
return os.Stat(path)
}
func (i IoUtilImp) RemoveAll(path string) error {
return os.RemoveAll(path)
}
func (i IoUtilImp) ReadDir(path string) ([]os.FileInfo, error) {
return ioutil.ReadDir(path)
}
func (i IoUtilImp) ReadFile(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)
}
@@ -1,70 +0,0 @@
package services
import (
"encoding/json"
"errors"
"github.com/franela/goreq"
m "github.com/grafana/grafana-cli/pkg/models"
"path"
)
var IoHelper m.IoUtil = IoUtilImp{}
func ListAllPlugins() (m.PluginRepo, error) {
res, _ := goreq.Request{Uri: "https://raw.githubusercontent.com/grafana/grafana-plugin-repository/master/repo.json"}.Do()
var resp m.PluginRepo
err := res.Body.FromJsonTo(&resp)
if err != nil {
return m.PluginRepo{}, errors.New("Could not load plugin data")
}
return resp, nil
}
func ReadPlugin(pluginDir, pluginName string) m.InstalledPlugin {
pluginDataPath := path.Join(pluginDir, pluginName, "plugin.json")
pluginData, _ := IoHelper.ReadFile(pluginDataPath)
res := m.InstalledPlugin{}
json.Unmarshal(pluginData, &res)
if res.Info.Version == "" {
res.Info.Version = "0.0.0"
}
if res.Id == "" {
res.Id = res.Name
}
return res
}
func GetLocalPlugins(pluginDir string) []m.InstalledPlugin {
result := make([]m.InstalledPlugin, 0)
files, _ := IoHelper.ReadDir(pluginDir)
for _, f := range files {
res := ReadPlugin(pluginDir, f.Name())
result = append(result, res)
}
return result
}
func RemoveInstalledPlugin(pluginPath, id string) error {
return IoHelper.RemoveAll(path.Join(pluginPath, id))
}
func GetPlugin(id string) (m.Plugin, error) {
resp, err := ListAllPlugins()
if err != nil {
}
for _, i := range resp.Plugins {
if i.Id == id {
return i, nil
}
}
return m.Plugin{}, errors.New("could not find plugin named \"" + id + "\"")
}
@@ -1,5 +0,0 @@
package version
var (
Version = "0.0.2"
)
@@ -1,3 +0,0 @@
#ignore
-timeout=1s
-coverpkg=github.com/smartystreets/goconvey/convey/assertions,github.com/smartystreets/goconvey/convey/assertions/oglematchers
@@ -1,103 +0,0 @@
package assertions
import (
"fmt"
"testing"
"time"
)
func TestShouldContain(t *testing.T) {
fail(t, so([]int{}, ShouldContain), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so([]int{}, ShouldContain, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
fail(t, so(Thing1{}, ShouldContain, 1), "You must provide a valid container (was assertions.Thing1)!")
fail(t, so(nil, ShouldContain, 1), "You must provide a valid container (was <nil>)!")
fail(t, so([]int{1}, ShouldContain, 2), "Expected the container ([]int) to contain: '2' (but it didn't)!")
pass(t, so([]int{1}, ShouldContain, 1))
pass(t, so([]int{1, 2, 3}, ShouldContain, 2))
}
func TestShouldNotContain(t *testing.T) {
fail(t, so([]int{}, ShouldNotContain), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so([]int{}, ShouldNotContain, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
fail(t, so(Thing1{}, ShouldNotContain, 1), "You must provide a valid container (was assertions.Thing1)!")
fail(t, so(nil, ShouldNotContain, 1), "You must provide a valid container (was <nil>)!")
fail(t, so([]int{1}, ShouldNotContain, 1), "Expected the container ([]int) NOT to contain: '1' (but it did)!")
fail(t, so([]int{1, 2, 3}, ShouldNotContain, 2), "Expected the container ([]int) NOT to contain: '2' (but it did)!")
pass(t, so([]int{1}, ShouldNotContain, 2))
}
func TestShouldBeIn(t *testing.T) {
fail(t, so(4, ShouldBeIn), shouldHaveProvidedCollectionMembers)
container := []int{1, 2, 3, 4}
pass(t, so(4, ShouldBeIn, container))
pass(t, so(4, ShouldBeIn, 1, 2, 3, 4))
fail(t, so(4, ShouldBeIn, 1, 2, 3), "Expected '4' to be in the container ([]interface {}, but it wasn't)!")
fail(t, so(4, ShouldBeIn, []int{1, 2, 3}), "Expected '4' to be in the container ([]int, but it wasn't)!")
}
func TestShouldNotBeIn(t *testing.T) {
fail(t, so(4, ShouldNotBeIn), shouldHaveProvidedCollectionMembers)
container := []int{1, 2, 3, 4}
pass(t, so(42, ShouldNotBeIn, container))
pass(t, so(42, ShouldNotBeIn, 1, 2, 3, 4))
fail(t, so(2, ShouldNotBeIn, 1, 2, 3), "Expected '2' NOT to be in the container ([]interface {}, but it was)!")
fail(t, so(2, ShouldNotBeIn, []int{1, 2, 3}), "Expected '2' NOT to be in the container ([]int, but it was)!")
}
func TestShouldBeEmpty(t *testing.T) {
fail(t, so(1, ShouldBeEmpty, 2, 3), "This assertion requires exactly 0 comparison values (you provided 2).")
pass(t, so([]int{}, ShouldBeEmpty)) // empty slice
pass(t, so([]interface{}{}, ShouldBeEmpty)) // empty slice
pass(t, so(map[string]int{}, ShouldBeEmpty)) // empty map
pass(t, so("", ShouldBeEmpty)) // empty string
pass(t, so(&[]int{}, ShouldBeEmpty)) // pointer to empty slice
pass(t, so(&[0]int{}, ShouldBeEmpty)) // pointer to empty array
pass(t, so(nil, ShouldBeEmpty)) // nil
pass(t, so(make(chan string), ShouldBeEmpty)) // empty channel
fail(t, so([]int{1}, ShouldBeEmpty), "Expected [1] to be empty (but it wasn't)!") // non-empty slice
fail(t, so([]interface{}{1}, ShouldBeEmpty), "Expected [1] to be empty (but it wasn't)!") // non-empty slice
fail(t, so(map[string]int{"hi": 0}, ShouldBeEmpty), "Expected map[hi:0] to be empty (but it wasn't)!") // non-empty map
fail(t, so("hi", ShouldBeEmpty), "Expected hi to be empty (but it wasn't)!") // non-empty string
fail(t, so(&[]int{1}, ShouldBeEmpty), "Expected &[1] to be empty (but it wasn't)!") // pointer to non-empty slice
fail(t, so(&[1]int{1}, ShouldBeEmpty), "Expected &[1] to be empty (but it wasn't)!") // pointer to non-empty array
c := make(chan int, 1) // non-empty channel
go func() { c <- 1 }()
time.Sleep(time.Millisecond)
fail(t, so(c, ShouldBeEmpty), fmt.Sprintf("Expected %+v to be empty (but it wasn't)!", c))
}
func TestShouldNotBeEmpty(t *testing.T) {
fail(t, so(1, ShouldNotBeEmpty, 2, 3), "This assertion requires exactly 0 comparison values (you provided 2).")
fail(t, so([]int{}, ShouldNotBeEmpty), "Expected [] to NOT be empty (but it was)!") // empty slice
fail(t, so([]interface{}{}, ShouldNotBeEmpty), "Expected [] to NOT be empty (but it was)!") // empty slice
fail(t, so(map[string]int{}, ShouldNotBeEmpty), "Expected map[] to NOT be empty (but it was)!") // empty map
fail(t, so("", ShouldNotBeEmpty), "Expected to NOT be empty (but it was)!") // empty string
fail(t, so(&[]int{}, ShouldNotBeEmpty), "Expected &[] to NOT be empty (but it was)!") // pointer to empty slice
fail(t, so(&[0]int{}, ShouldNotBeEmpty), "Expected &[] to NOT be empty (but it was)!") // pointer to empty array
fail(t, so(nil, ShouldNotBeEmpty), "Expected <nil> to NOT be empty (but it was)!") // nil
c := make(chan int, 0) // non-empty channel
fail(t, so(c, ShouldNotBeEmpty), fmt.Sprintf("Expected %+v to NOT be empty (but it was)!", c)) // empty channel
pass(t, so([]int{1}, ShouldNotBeEmpty)) // non-empty slice
pass(t, so([]interface{}{1}, ShouldNotBeEmpty)) // non-empty slice
pass(t, so(map[string]int{"hi": 0}, ShouldNotBeEmpty)) // non-empty map
pass(t, so("hi", ShouldNotBeEmpty)) // non-empty string
pass(t, so(&[]int{1}, ShouldNotBeEmpty)) // pointer to non-empty slice
pass(t, so(&[1]int{1}, ShouldNotBeEmpty)) // pointer to non-empty array
c = make(chan int, 1)
go func() { c <- 1 }()
time.Sleep(time.Millisecond)
pass(t, so(c, ShouldNotBeEmpty))
}
@@ -1,43 +0,0 @@
// Package assertions contains the implementations for all assertions which
// are referenced in the convey package for use with the So(...) method.
package assertions
// This function is not used by the goconvey library. It's actually a convenience method
// for running assertions on arbitrary arguments outside of any testing context, like for
// application logging. It allows you to perform assertion-like behavior (and get nicely
// formatted messages detailing discrepancies) but without the probram blowing up or panicking.
// All that is required is to import this package and call `So` with one of the assertions
// exported by this package as the second parameter.
// The first return parameter is a boolean indicating if the assertion was true. The second
// return parameter is the well-formatted message showing why an assertion was incorrect, or
// blank if the assertion was correct.
//
// Example:
//
// if ok, message := So(x, ShouldBeGreaterThan, y); !ok {
// log.Println(message)
// }
//
func So(actual interface{}, assert assertion, expected ...interface{}) (bool, string) {
serializer = noop
if result := so(actual, assert, expected...); len(result) == 0 {
return true, result
} else {
return false, result
}
}
// so is like So, except that it only returns the string message, which is blank if the
// assertion passed. Used to facilitate testing.
func so(actual interface{}, assert func(interface{}, ...interface{}) string, expected ...interface{}) string {
return assert(actual, expected...)
}
// assertion is an alias for a function with a signature that the So()
// function can handle. Any future or custom assertions should conform to this
// method signature. The return value should be an empty string if the assertion
// passes and a well-formed failure message if not.
type assertion func(actual interface{}, expected ...interface{}) string
////////////////////////////////////////////////////////////////////////////
@@ -1,267 +0,0 @@
package assertions
import (
"fmt"
"reflect"
"testing"
)
func TestShouldEqual(t *testing.T) {
serializer = newFakeSerializer()
fail(t, so(1, ShouldEqual), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so(1, ShouldEqual, 1, 2), "This assertion requires exactly 1 comparison values (you provided 2).")
fail(t, so(1, ShouldEqual, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
pass(t, so(1, ShouldEqual, 1))
fail(t, so(1, ShouldEqual, 2), "2|1|Expected: '2' Actual: '1' (Should be equal)")
pass(t, so(true, ShouldEqual, true))
fail(t, so(true, ShouldEqual, false), "false|true|Expected: 'false' Actual: 'true' (Should be equal)")
pass(t, so("hi", ShouldEqual, "hi"))
fail(t, so("hi", ShouldEqual, "bye"), "bye|hi|Expected: 'bye' Actual: 'hi' (Should be equal)")
pass(t, so(42, ShouldEqual, uint(42)))
fail(t, so(Thing1{"hi"}, ShouldEqual, Thing1{}), "{}|{hi}|Expected: '{}' Actual: '{hi}' (Should be equal)")
fail(t, so(Thing1{"hi"}, ShouldEqual, Thing1{"hi"}), "{hi}|{hi}|Expected: '{hi}' Actual: '{hi}' (Should be equal)")
fail(t, so(&Thing1{"hi"}, ShouldEqual, &Thing1{"hi"}), "&{hi}|&{hi}|Expected: '&{hi}' Actual: '&{hi}' (Should be equal)")
fail(t, so(Thing1{}, ShouldEqual, Thing2{}), "{}|{}|Expected: '{}' Actual: '{}' (Should be equal)")
}
func TestShouldNotEqual(t *testing.T) {
fail(t, so(1, ShouldNotEqual), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so(1, ShouldNotEqual, 1, 2), "This assertion requires exactly 1 comparison values (you provided 2).")
fail(t, so(1, ShouldNotEqual, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
pass(t, so(1, ShouldNotEqual, 2))
fail(t, so(1, ShouldNotEqual, 1), "Expected '1' to NOT equal '1' (but it did)!")
pass(t, so(true, ShouldNotEqual, false))
fail(t, so(true, ShouldNotEqual, true), "Expected 'true' to NOT equal 'true' (but it did)!")
pass(t, so("hi", ShouldNotEqual, "bye"))
fail(t, so("hi", ShouldNotEqual, "hi"), "Expected 'hi' to NOT equal 'hi' (but it did)!")
pass(t, so(&Thing1{"hi"}, ShouldNotEqual, &Thing1{"hi"}))
pass(t, so(Thing1{"hi"}, ShouldNotEqual, Thing1{"hi"}))
pass(t, so(Thing1{}, ShouldNotEqual, Thing1{}))
pass(t, so(Thing1{}, ShouldNotEqual, Thing2{}))
}
func TestShouldAlmostEqual(t *testing.T) {
fail(t, so(1, ShouldAlmostEqual), "This assertion requires exactly one comparison value and an optional delta (you provided neither)")
fail(t, so(1, ShouldAlmostEqual, 1, 2, 3), "This assertion requires exactly one comparison value and an optional delta (you provided more values)")
// with the default delta
pass(t, so(1, ShouldAlmostEqual, .99999999999999))
pass(t, so(1.3612499999999996, ShouldAlmostEqual, 1.36125))
pass(t, so(0.7285312499999999, ShouldAlmostEqual, 0.72853125))
fail(t, so(1, ShouldAlmostEqual, .99), "Expected '1' to almost equal '0.99' (but it didn't)!")
// with a different delta
pass(t, so(100.0, ShouldAlmostEqual, 110.0, 10.0))
fail(t, so(100.0, ShouldAlmostEqual, 111.0, 10.5), "Expected '100' to almost equal '111' (but it didn't)!")
// ints should work
pass(t, so(100, ShouldAlmostEqual, 100.0))
fail(t, so(100, ShouldAlmostEqual, 99.0), "Expected '100' to almost equal '99' (but it didn't)!")
// float32 should work
pass(t, so(float64(100.0), ShouldAlmostEqual, float32(100.0)))
fail(t, so(float32(100.0), ShouldAlmostEqual, 99.0, float32(0.1)), "Expected '100' to almost equal '99' (but it didn't)!")
}
func TestShouldNotAlmostEqual(t *testing.T) {
fail(t, so(1, ShouldNotAlmostEqual), "This assertion requires exactly one comparison value and an optional delta (you provided neither)")
fail(t, so(1, ShouldNotAlmostEqual, 1, 2, 3), "This assertion requires exactly one comparison value and an optional delta (you provided more values)")
// with the default delta
fail(t, so(1, ShouldNotAlmostEqual, .99999999999999), "Expected '1' to NOT almost equal '0.99999999999999' (but it did)!")
fail(t, so(1.3612499999999996, ShouldNotAlmostEqual, 1.36125), "Expected '1.3612499999999996' to NOT almost equal '1.36125' (but it did)!")
pass(t, so(1, ShouldNotAlmostEqual, .99))
// with a different delta
fail(t, so(100.0, ShouldNotAlmostEqual, 110.0, 10.0), "Expected '100' to NOT almost equal '110' (but it did)!")
pass(t, so(100.0, ShouldNotAlmostEqual, 111.0, 10.5))
// ints should work
fail(t, so(100, ShouldNotAlmostEqual, 100.0), "Expected '100' to NOT almost equal '100' (but it did)!")
pass(t, so(100, ShouldNotAlmostEqual, 99.0))
// float32 should work
fail(t, so(float64(100.0), ShouldNotAlmostEqual, float32(100.0)), "Expected '100' to NOT almost equal '100' (but it did)!")
pass(t, so(float32(100.0), ShouldNotAlmostEqual, 99.0, float32(0.1)))
}
func TestShouldResemble(t *testing.T) {
serializer = newFakeSerializer()
fail(t, so(Thing1{"hi"}, ShouldResemble), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"hi"}, Thing1{"hi"}), "This assertion requires exactly 1 comparison values (you provided 2).")
pass(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"hi"}))
fail(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"bye"}), "{bye}|{hi}|Expected: 'assertions.Thing1{a:\"bye\"}' Actual: 'assertions.Thing1{a:\"hi\"}' (Should resemble)!")
var (
a []int
b []int = []int{}
)
fail(t, so(a, ShouldResemble, b), "[]|[]|Expected: '[]int{}' Actual: '[]int(nil)' (Should resemble)!")
fail(t, so(2, ShouldResemble, 1), "1|2|Expected: '1' Actual: '2' (Should resemble)!")
fail(t, so(StringStringMapAlias{"hi": "bye"}, ShouldResemble, map[string]string{"hi": "bye"}),
"map[hi:bye]|map[hi:bye]|Expected: 'map[string]string{\"hi\":\"bye\"}' Actual: 'assertions.StringStringMapAlias{\"hi\":\"bye\"}' (Should resemble)!")
fail(t, so(StringSliceAlias{"hi", "bye"}, ShouldResemble, []string{"hi", "bye"}),
"[hi bye]|[hi bye]|Expected: '[]string{\"hi\", \"bye\"}' Actual: 'assertions.StringSliceAlias{\"hi\", \"bye\"}' (Should resemble)!")
// some types come out looking the same when represented with "%#v" so we show type mismatch info:
fail(t, so(StringAlias("hi"), ShouldResemble, "hi"), "hi|hi|Expected: '\"hi\"' Actual: '\"hi\"' (Type mismatch: 'string' vs 'assertions.StringAlias')!")
fail(t, so(IntAlias(42), ShouldResemble, 42), "42|42|Expected: '42' Actual: '42' (Type mismatch: 'int' vs 'assertions.IntAlias')!")
}
func TestShouldNotResemble(t *testing.T) {
fail(t, so(Thing1{"hi"}, ShouldNotResemble), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"hi"}, Thing1{"hi"}), "This assertion requires exactly 1 comparison values (you provided 2).")
pass(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"bye"}))
fail(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"hi"}),
"Expected 'assertions.Thing1{a:\"hi\"}' to NOT resemble 'assertions.Thing1{a:\"hi\"}' (but it did)!")
pass(t, so(map[string]string{"hi": "bye"}, ShouldResemble, map[string]string{"hi": "bye"}))
pass(t, so(IntAlias(42), ShouldNotResemble, 42))
pass(t, so(StringSliceAlias{"hi", "bye"}, ShouldNotResemble, []string{"hi", "bye"}))
}
func TestShouldPointTo(t *testing.T) {
serializer = newFakeSerializer()
t1 := &Thing1{}
t2 := t1
t3 := &Thing1{}
pointer1 := reflect.ValueOf(t1).Pointer()
pointer3 := reflect.ValueOf(t3).Pointer()
fail(t, so(t1, ShouldPointTo), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so(t1, ShouldPointTo, t2, t3), "This assertion requires exactly 1 comparison values (you provided 2).")
pass(t, so(t1, ShouldPointTo, t2))
fail(t, so(t1, ShouldPointTo, t3), fmt.Sprintf(
"%v|%v|Expected '&{a:}' (address: '%v') and '&{a:}' (address: '%v') to be the same address (but their weren't)!",
pointer3, pointer1, pointer1, pointer3))
t4 := Thing1{}
t5 := t4
fail(t, so(t4, ShouldPointTo, t5), "Both arguments should be pointers (the first was not)!")
fail(t, so(&t4, ShouldPointTo, t5), "Both arguments should be pointers (the second was not)!")
fail(t, so(nil, ShouldPointTo, nil), "Both arguments should be pointers (the first was nil)!")
fail(t, so(&t4, ShouldPointTo, nil), "Both arguments should be pointers (the second was nil)!")
}
func TestShouldNotPointTo(t *testing.T) {
t1 := &Thing1{}
t2 := t1
t3 := &Thing1{}
pointer1 := reflect.ValueOf(t1).Pointer()
fail(t, so(t1, ShouldNotPointTo), "This assertion requires exactly 1 comparison values (you provided 0).")
fail(t, so(t1, ShouldNotPointTo, t2, t3), "This assertion requires exactly 1 comparison values (you provided 2).")
pass(t, so(t1, ShouldNotPointTo, t3))
fail(t, so(t1, ShouldNotPointTo, t2), fmt.Sprintf("Expected '&{a:}' and '&{a:}' to be different references (but they matched: '%v')!", pointer1))
t4 := Thing1{}
t5 := t4
fail(t, so(t4, ShouldNotPointTo, t5), "Both arguments should be pointers (the first was not)!")
fail(t, so(&t4, ShouldNotPointTo, t5), "Both arguments should be pointers (the second was not)!")
fail(t, so(nil, ShouldNotPointTo, nil), "Both arguments should be pointers (the first was nil)!")
fail(t, so(&t4, ShouldNotPointTo, nil), "Both arguments should be pointers (the second was nil)!")
}
func TestShouldBeNil(t *testing.T) {
fail(t, so(nil, ShouldBeNil, nil, nil, nil), "This assertion requires exactly 0 comparison values (you provided 3).")
fail(t, so(nil, ShouldBeNil, nil), "This assertion requires exactly 0 comparison values (you provided 1).")
pass(t, so(nil, ShouldBeNil))
fail(t, so(1, ShouldBeNil), "Expected: nil Actual: '1'")
var thing Thinger
pass(t, so(thing, ShouldBeNil))
thing = &Thing{}
fail(t, so(thing, ShouldBeNil), "Expected: nil Actual: '&{}'")
var thingOne *Thing1
pass(t, so(thingOne, ShouldBeNil))
var nilSlice []int = nil
pass(t, so(nilSlice, ShouldBeNil))
var nilMap map[string]string = nil
pass(t, so(nilMap, ShouldBeNil))
var nilChannel chan int = nil
pass(t, so(nilChannel, ShouldBeNil))
var nilFunc func() = nil
pass(t, so(nilFunc, ShouldBeNil))
var nilInterface interface{} = nil
pass(t, so(nilInterface, ShouldBeNil))
}
func TestShouldNotBeNil(t *testing.T) {
fail(t, so(nil, ShouldNotBeNil, nil, nil, nil), "This assertion requires exactly 0 comparison values (you provided 3).")
fail(t, so(nil, ShouldNotBeNil, nil), "This assertion requires exactly 0 comparison values (you provided 1).")
fail(t, so(nil, ShouldNotBeNil), "Expected '<nil>' to NOT be nil (but it was)!")
pass(t, so(1, ShouldNotBeNil))
var thing Thinger
fail(t, so(thing, ShouldNotBeNil), "Expected '<nil>' to NOT be nil (but it was)!")
thing = &Thing{}
pass(t, so(thing, ShouldNotBeNil))
}
func TestShouldBeTrue(t *testing.T) {
fail(t, so(true, ShouldBeTrue, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
fail(t, so(true, ShouldBeTrue, 1), "This assertion requires exactly 0 comparison values (you provided 1).")
fail(t, so(false, ShouldBeTrue), "Expected: true Actual: false")
fail(t, so(1, ShouldBeTrue), "Expected: true Actual: 1")
pass(t, so(true, ShouldBeTrue))
}
func TestShouldBeFalse(t *testing.T) {
fail(t, so(false, ShouldBeFalse, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
fail(t, so(false, ShouldBeFalse, 1), "This assertion requires exactly 0 comparison values (you provided 1).")
fail(t, so(true, ShouldBeFalse), "Expected: false Actual: true")
fail(t, so(1, ShouldBeFalse), "Expected: false Actual: 1")
pass(t, so(false, ShouldBeFalse))
}
func TestShouldBeZeroValue(t *testing.T) {
serializer = newFakeSerializer()
fail(t, so(0, ShouldBeZeroValue, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
fail(t, so(false, ShouldBeZeroValue, true), "This assertion requires exactly 0 comparison values (you provided 1).")
fail(t, so(1, ShouldBeZeroValue), "0|1|'1' should have been the zero value") //"Expected: (zero value) Actual: 1")
fail(t, so(true, ShouldBeZeroValue), "false|true|'true' should have been the zero value") //"Expected: (zero value) Actual: true")
fail(t, so("123", ShouldBeZeroValue), "|123|'123' should have been the zero value") //"Expected: (zero value) Actual: 123")
fail(t, so(" ", ShouldBeZeroValue), "| |' ' should have been the zero value") //"Expected: (zero value) Actual: ")
fail(t, so([]string{"Nonempty"}, ShouldBeZeroValue), "[]|[Nonempty]|'[Nonempty]' should have been the zero value") //"Expected: (zero value) Actual: [Nonempty]")
fail(t, so(struct{ a string }{a: "asdf"}, ShouldBeZeroValue), "{}|{asdf}|'{a:asdf}' should have been the zero value")
pass(t, so(0, ShouldBeZeroValue))
pass(t, so(false, ShouldBeZeroValue))
pass(t, so("", ShouldBeZeroValue))
pass(t, so(struct{}{}, ShouldBeZeroValue))
}
@@ -1,6 +0,0 @@
package assertions
var (
serializer Serializer = newSerializer()
noop Serializer = new(noopSerializer)
)
@@ -1,5 +0,0 @@
*.6
6.out
_obj/
_test/
_testmain.go
@@ -1,110 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"errors"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type allOfFakeMatcher struct {
desc string
err error
}
func (m *allOfFakeMatcher) Matches(c interface{}) error {
return m.err
}
func (m *allOfFakeMatcher) Description() string {
return m.desc
}
type AllOfTest struct {
}
func init() { RegisterTestSuite(&AllOfTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *AllOfTest) DescriptionWithEmptySet() {
m := AllOf()
ExpectEq("is anything", m.Description())
}
func (t *AllOfTest) DescriptionWithOneMatcher() {
m := AllOf(&allOfFakeMatcher{"taco", errors.New("")})
ExpectEq("taco", m.Description())
}
func (t *AllOfTest) DescriptionWithMultipleMatchers() {
m := AllOf(
&allOfFakeMatcher{"taco", errors.New("")},
&allOfFakeMatcher{"burrito", errors.New("")},
&allOfFakeMatcher{"enchilada", errors.New("")})
ExpectEq("taco, and burrito, and enchilada", m.Description())
}
func (t *AllOfTest) EmptySet() {
m := AllOf()
err := m.Matches(17)
ExpectEq(nil, err)
}
func (t *AllOfTest) OneMatcherReturnsFatalErrorAndSomeOthersFail() {
m := AllOf(
&allOfFakeMatcher{"", errors.New("")},
&allOfFakeMatcher{"", NewFatalError("taco")},
&allOfFakeMatcher{"", errors.New("")},
&allOfFakeMatcher{"", nil})
err := m.Matches(17)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("taco")))
}
func (t *AllOfTest) OneMatcherReturnsNonFatalAndOthersSayTrue() {
m := AllOf(
&allOfFakeMatcher{"", nil},
&allOfFakeMatcher{"", errors.New("taco")},
&allOfFakeMatcher{"", nil})
err := m.Matches(17)
ExpectFalse(isFatal(err))
ExpectThat(err, Error(Equals("taco")))
}
func (t *AllOfTest) AllMatchersSayTrue() {
m := AllOf(
&allOfFakeMatcher{"", nil},
&allOfFakeMatcher{"", nil},
&allOfFakeMatcher{"", nil})
err := m.Matches(17)
ExpectEq(nil, err)
}
@@ -1,121 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"errors"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type fakeAnyOfMatcher struct {
desc string
err error
}
func (m *fakeAnyOfMatcher) Matches(c interface{}) error {
return m.err
}
func (m *fakeAnyOfMatcher) Description() string {
return m.desc
}
type AnyOfTest struct {
}
func init() { RegisterTestSuite(&AnyOfTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *AnyOfTest) EmptySet() {
matcher := AnyOf()
err := matcher.Matches(0)
ExpectThat(err, Error(Equals("")))
}
func (t *AnyOfTest) OneTrue() {
matcher := AnyOf(
&fakeAnyOfMatcher{"", NewFatalError("foo")},
17,
&fakeAnyOfMatcher{"", errors.New("foo")},
&fakeAnyOfMatcher{"", nil},
&fakeAnyOfMatcher{"", errors.New("foo")},
)
err := matcher.Matches(0)
ExpectEq(nil, err)
}
func (t *AnyOfTest) OneEqual() {
matcher := AnyOf(
&fakeAnyOfMatcher{"", NewFatalError("foo")},
&fakeAnyOfMatcher{"", errors.New("foo")},
13,
"taco",
19,
&fakeAnyOfMatcher{"", errors.New("foo")},
)
err := matcher.Matches("taco")
ExpectEq(nil, err)
}
func (t *AnyOfTest) OneFatal() {
matcher := AnyOf(
&fakeAnyOfMatcher{"", errors.New("foo")},
17,
&fakeAnyOfMatcher{"", NewFatalError("taco")},
&fakeAnyOfMatcher{"", errors.New("foo")},
)
err := matcher.Matches(0)
ExpectThat(err, Error(Equals("taco")))
}
func (t *AnyOfTest) AllFalseAndNotEqual() {
matcher := AnyOf(
&fakeAnyOfMatcher{"", errors.New("foo")},
17,
&fakeAnyOfMatcher{"", errors.New("foo")},
19,
)
err := matcher.Matches(0)
ExpectThat(err, Error(Equals("")))
}
func (t *AnyOfTest) DescriptionForEmptySet() {
matcher := AnyOf()
ExpectEq("or()", matcher.Description())
}
func (t *AnyOfTest) DescriptionForNonEmptySet() {
matcher := AnyOf(
&fakeAnyOfMatcher{"taco", nil},
"burrito",
&fakeAnyOfMatcher{"enchilada", nil},
)
ExpectEq("or(taco, burrito, enchilada)", matcher.Description())
}
@@ -1,53 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type AnyTest struct {
}
func init() { RegisterTestSuite(&AnyTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *AnyTest) Description() {
m := Any()
ExpectEq("is anything", m.Description())
}
func (t *AnyTest) Matches() {
var err error
m := Any()
err = m.Matches(nil)
ExpectEq(nil, err)
err = m.Matches(17)
ExpectEq(nil, err)
err = m.Matches("taco")
ExpectEq(nil, err)
}
@@ -1,234 +0,0 @@
// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type ContainsTest struct{}
func init() { RegisterTestSuite(&ContainsTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *ContainsTest) WrongTypeCandidates() {
m := Contains("")
ExpectEq("contains: ", m.Description())
var err error
// Nil candidate
err = m.Matches(nil)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("array")))
ExpectThat(err, Error(HasSubstr("slice")))
// String candidate
err = m.Matches("")
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("array")))
ExpectThat(err, Error(HasSubstr("slice")))
// Map candidate
err = m.Matches(make(map[string]string))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("array")))
ExpectThat(err, Error(HasSubstr("slice")))
}
func (t *ContainsTest) NilArgument() {
m := Contains(nil)
ExpectEq("contains: is nil", m.Description())
var c interface{}
var err error
// Empty array of pointers
c = [...]*int{}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Empty slice of pointers
c = []*int{}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-empty array of integers
c = [...]int{17, 0, 19}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-empty slice of integers
c = []int{17, 0, 19}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-matching array of pointers
c = [...]*int{new(int), new(int)}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-matching slice of pointers
c = []*int{new(int), new(int)}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Matching array of pointers
c = [...]*int{new(int), nil, new(int)}
err = m.Matches(c)
ExpectEq(nil, err)
// Matching slice of pointers
c = []*int{new(int), nil, new(int)}
err = m.Matches(c)
ExpectEq(nil, err)
// Non-matching slice of pointers from matching array
someArray := [...]*int{new(int), nil, new(int)}
c = someArray[0:1]
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
func (t *ContainsTest) StringArgument() {
m := Contains("taco")
ExpectEq("contains: taco", m.Description())
var c interface{}
var err error
// Non-matching array of strings
c = [...]string{"burrito", "enchilada"}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-matching slice of strings
c = []string{"burrito", "enchilada"}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Matching array of strings
c = [...]string{"burrito", "taco", "enchilada"}
err = m.Matches(c)
ExpectEq(nil, err)
// Matching slice of strings
c = []string{"burrito", "taco", "enchilada"}
err = m.Matches(c)
ExpectEq(nil, err)
// Non-matching slice of strings from matching array
someArray := [...]string{"burrito", "taco", "enchilada"}
c = someArray[0:1]
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
func (t *ContainsTest) IntegerArgument() {
m := Contains(int(17))
ExpectEq("contains: 17", m.Description())
var c interface{}
var err error
// Non-matching array of integers
c = [...]int{13, 19}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-matching slice of integers
c = []int{13, 19}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Matching array of integers
c = [...]int{13, 17, 19}
err = m.Matches(c)
ExpectEq(nil, err)
// Matching slice of integers
c = []int{13, 17, 19}
err = m.Matches(c)
ExpectEq(nil, err)
// Non-matching slice of integers from matching array
someArray := [...]int{13, 17, 19}
c = someArray[0:1]
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-matching array of floats
c = [...]float32{13, 17.5, 19}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-matching slice of floats
c = []float32{13, 17.5, 19}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Matching array of floats
c = [...]float32{13, 17, 19}
err = m.Matches(c)
ExpectEq(nil, err)
// Matching slice of floats
c = []float32{13, 17, 19}
err = m.Matches(c)
ExpectEq(nil, err)
}
func (t *ContainsTest) MatcherArgument() {
m := Contains(HasSubstr("ac"))
ExpectEq("contains: has substring \"ac\"", m.Description())
var c interface{}
var err error
// Non-matching array of strings
c = [...]string{"burrito", "enchilada"}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Non-matching slice of strings
c = []string{"burrito", "enchilada"}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Matching array of strings
c = [...]string{"burrito", "taco", "enchilada"}
err = m.Matches(c)
ExpectEq(nil, err)
// Matching slice of strings
c = []string{"burrito", "taco", "enchilada"}
err = m.Matches(c)
ExpectEq(nil, err)
// Non-matching slice of strings from matching array
someArray := [...]string{"burrito", "taco", "enchilada"}
c = someArray[0:1]
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
@@ -1,344 +0,0 @@
// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"bytes"
"testing"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type DeepEqualsTest struct{}
func init() { RegisterTestSuite(&DeepEqualsTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *DeepEqualsTest) WrongTypeCandidateWithScalarValue() {
var x int = 17
m := DeepEquals(x)
var err error
// Nil candidate.
err = m.Matches(nil)
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("<nil>")))
// Int alias candidate.
type intAlias int
err = m.Matches(intAlias(x))
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("intAlias")))
// String candidate.
err = m.Matches("taco")
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("string")))
// Byte slice candidate.
err = m.Matches([]byte{})
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("[]uint8")))
// Other slice candidate.
err = m.Matches([]uint16{})
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("[]uint16")))
// Unsigned int candidate.
err = m.Matches(uint(17))
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("uint")))
}
func (t *DeepEqualsTest) WrongTypeCandidateWithByteSliceValue() {
x := []byte{}
m := DeepEquals(x)
var err error
// Nil candidate.
err = m.Matches(nil)
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("<nil>")))
// String candidate.
err = m.Matches("taco")
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("string")))
// Slice candidate with wrong value type.
err = m.Matches([]uint16{})
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("[]uint16")))
}
func (t *DeepEqualsTest) WrongTypeCandidateWithOtherSliceValue() {
x := []uint16{}
m := DeepEquals(x)
var err error
// Nil candidate.
err = m.Matches(nil)
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("<nil>")))
// String candidate.
err = m.Matches("taco")
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("string")))
// Byte slice candidate with wrong value type.
err = m.Matches([]byte{})
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("[]uint8")))
// Other slice candidate with wrong value type.
err = m.Matches([]uint32{})
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("[]uint32")))
}
func (t *DeepEqualsTest) WrongTypeCandidateWithNilLiteralValue() {
m := DeepEquals(nil)
var err error
// String candidate.
err = m.Matches("taco")
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("string")))
// Nil byte slice candidate.
err = m.Matches([]byte(nil))
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("[]uint8")))
// Nil other slice candidate.
err = m.Matches([]uint16(nil))
AssertNe(nil, err)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("type")))
ExpectThat(err, Error(HasSubstr("[]uint16")))
}
func (t *DeepEqualsTest) NilLiteralValue() {
m := DeepEquals(nil)
ExpectEq("deep equals: <nil>", m.Description())
var c interface{}
var err error
// Nil literal candidate.
c = nil
err = m.Matches(c)
ExpectEq(nil, err)
}
func (t *DeepEqualsTest) IntValue() {
m := DeepEquals(int(17))
ExpectEq("deep equals: 17", m.Description())
var c interface{}
var err error
// Matching int.
c = int(17)
err = m.Matches(c)
ExpectEq(nil, err)
// Non-matching int.
c = int(18)
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
func (t *DeepEqualsTest) ByteSliceValue() {
x := []byte{17, 19}
m := DeepEquals(x)
ExpectEq("deep equals: [17 19]", m.Description())
var c []byte
var err error
// Matching.
c = make([]byte, len(x))
AssertEq(len(x), copy(c, x))
err = m.Matches(c)
ExpectEq(nil, err)
// Nil slice.
c = []byte(nil)
err = m.Matches(c)
ExpectThat(err, Error(Equals("which is nil")))
// Prefix.
AssertGt(len(x), 1)
c = make([]byte, len(x)-1)
AssertEq(len(x)-1, copy(c, x))
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Suffix.
c = make([]byte, len(x)+1)
AssertEq(len(x), copy(c, x))
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
func (t *DeepEqualsTest) OtherSliceValue() {
x := []uint16{17, 19}
m := DeepEquals(x)
ExpectEq("deep equals: [17 19]", m.Description())
var c []uint16
var err error
// Matching.
c = make([]uint16, len(x))
AssertEq(len(x), copy(c, x))
err = m.Matches(c)
ExpectEq(nil, err)
// Nil slice.
c = []uint16(nil)
err = m.Matches(c)
ExpectThat(err, Error(Equals("which is nil")))
// Prefix.
AssertGt(len(x), 1)
c = make([]uint16, len(x)-1)
AssertEq(len(x)-1, copy(c, x))
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
// Suffix.
c = make([]uint16, len(x)+1)
AssertEq(len(x), copy(c, x))
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
func (t *DeepEqualsTest) NilByteSliceValue() {
x := []byte(nil)
m := DeepEquals(x)
ExpectEq("deep equals: <nil slice>", m.Description())
var c []byte
var err error
// Nil slice.
c = []byte(nil)
err = m.Matches(c)
ExpectEq(nil, err)
// Non-nil slice.
c = []byte{}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
func (t *DeepEqualsTest) NilOtherSliceValue() {
x := []uint16(nil)
m := DeepEquals(x)
ExpectEq("deep equals: <nil slice>", m.Description())
var c []uint16
var err error
// Nil slice.
c = []uint16(nil)
err = m.Matches(c)
ExpectEq(nil, err)
// Non-nil slice.
c = []uint16{}
err = m.Matches(c)
ExpectThat(err, Error(Equals("")))
}
////////////////////////////////////////////////////////////////////////
// Benchmarks
////////////////////////////////////////////////////////////////////////
func benchmarkWithSize(b *testing.B, size int) {
b.StopTimer()
buf := bytes.Repeat([]byte{0x01}, size)
bufCopy := make([]byte, size)
copy(bufCopy, buf)
matcher := DeepEquals(buf)
b.StartTimer()
for i := 0; i < b.N; i++ {
matcher.Matches(bufCopy)
}
b.SetBytes(int64(size))
}
func BenchmarkShortByteSlice(b *testing.B) {
benchmarkWithSize(b, 256)
}
func BenchmarkLongByteSlice(b *testing.B) {
benchmarkWithSize(b, 1<<24)
}
@@ -1,208 +0,0 @@
// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type ElementsAreTest struct {
}
func init() { RegisterTestSuite(&ElementsAreTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *ElementsAreTest) EmptySet() {
m := ElementsAre()
ExpectEq("elements are: []", m.Description())
var c []interface{}
var err error
// No candidates.
c = []interface{}{}
err = m.Matches(c)
ExpectEq(nil, err)
// One candidate.
c = []interface{}{17}
err = m.Matches(c)
ExpectThat(err, Error(HasSubstr("length 1")))
}
func (t *ElementsAreTest) OneMatcher() {
m := ElementsAre(LessThan(17))
ExpectEq("elements are: [less than 17]", m.Description())
var c []interface{}
var err error
// No candidates.
c = []interface{}{}
err = m.Matches(c)
ExpectThat(err, Error(HasSubstr("length 0")))
// Matching candidate.
c = []interface{}{16}
err = m.Matches(c)
ExpectEq(nil, err)
// Non-matching candidate.
c = []interface{}{19}
err = m.Matches(c)
ExpectNe(nil, err)
// Two candidates.
c = []interface{}{17, 19}
err = m.Matches(c)
ExpectThat(err, Error(HasSubstr("length 2")))
}
func (t *ElementsAreTest) OneValue() {
m := ElementsAre(17)
ExpectEq("elements are: [17]", m.Description())
var c []interface{}
var err error
// No candidates.
c = []interface{}{}
err = m.Matches(c)
ExpectThat(err, Error(HasSubstr("length 0")))
// Matching int.
c = []interface{}{int(17)}
err = m.Matches(c)
ExpectEq(nil, err)
// Matching float.
c = []interface{}{float32(17)}
err = m.Matches(c)
ExpectEq(nil, err)
// Non-matching candidate.
c = []interface{}{19}
err = m.Matches(c)
ExpectNe(nil, err)
// Two candidates.
c = []interface{}{17, 19}
err = m.Matches(c)
ExpectThat(err, Error(HasSubstr("length 2")))
}
func (t *ElementsAreTest) MultipleElements() {
m := ElementsAre("taco", LessThan(17))
ExpectEq("elements are: [taco, less than 17]", m.Description())
var c []interface{}
var err error
// One candidate.
c = []interface{}{17}
err = m.Matches(c)
ExpectThat(err, Error(HasSubstr("length 1")))
// Both matching.
c = []interface{}{"taco", 16}
err = m.Matches(c)
ExpectEq(nil, err)
// First non-matching.
c = []interface{}{"burrito", 16}
err = m.Matches(c)
ExpectThat(err, Error(Equals("whose element 0 doesn't match")))
// Second non-matching.
c = []interface{}{"taco", 17}
err = m.Matches(c)
ExpectThat(err, Error(Equals("whose element 1 doesn't match")))
// Three candidates.
c = []interface{}{"taco", 17, 19}
err = m.Matches(c)
ExpectThat(err, Error(HasSubstr("length 3")))
}
func (t *ElementsAreTest) ArrayCandidates() {
m := ElementsAre("taco", LessThan(17))
var err error
// One candidate.
err = m.Matches([1]interface{}{"taco"})
ExpectThat(err, Error(HasSubstr("length 1")))
// Both matching.
err = m.Matches([2]interface{}{"taco", 16})
ExpectEq(nil, err)
// First non-matching.
err = m.Matches([2]interface{}{"burrito", 16})
ExpectThat(err, Error(Equals("whose element 0 doesn't match")))
}
func (t *ElementsAreTest) WrongTypeCandidate() {
m := ElementsAre("taco")
var err error
// String candidate.
err = m.Matches("taco")
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("array")))
ExpectThat(err, Error(HasSubstr("slice")))
// Map candidate.
err = m.Matches(map[string]string{})
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("array")))
ExpectThat(err, Error(HasSubstr("slice")))
// Nil candidate.
err = m.Matches(nil)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("array")))
ExpectThat(err, Error(HasSubstr("slice")))
}
func (t *ElementsAreTest) PropagatesFatality() {
m := ElementsAre(LessThan(17))
ExpectEq("elements are: [less than 17]", m.Description())
var c []interface{}
var err error
// Non-fatal error.
c = []interface{}{19}
err = m.Matches(c)
AssertNe(nil, err)
ExpectFalse(isFatal(err))
// Fatal error.
c = []interface{}{"taco"}
err = m.Matches(c)
AssertNe(nil, err)
ExpectTrue(isFatal(err))
}
File diff suppressed because it is too large Load Diff
@@ -1,92 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"errors"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type ErrorTest struct {
matcherCalled bool
suppliedCandidate interface{}
wrappedError error
matcher Matcher
}
func init() { RegisterTestSuite(&ErrorTest{}) }
func (t *ErrorTest) SetUp(i *TestInfo) {
wrapped := &fakeMatcher{
func(c interface{}) error {
t.matcherCalled = true
t.suppliedCandidate = c
return t.wrappedError
},
"is foo",
}
t.matcher = Error(wrapped)
}
func isFatal(err error) bool {
_, isFatal := err.(*FatalError)
return isFatal
}
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *ErrorTest) Description() {
ExpectThat(t.matcher.Description(), Equals("error is foo"))
}
func (t *ErrorTest) CandidateIsNil() {
err := t.matcher.Matches(nil)
ExpectThat(t.matcherCalled, Equals(false))
ExpectThat(err.Error(), Equals("which is not an error"))
ExpectTrue(isFatal(err))
}
func (t *ErrorTest) CandidateIsString() {
err := t.matcher.Matches("taco")
ExpectThat(t.matcherCalled, Equals(false))
ExpectThat(err.Error(), Equals("which is not an error"))
ExpectTrue(isFatal(err))
}
func (t *ErrorTest) CallsWrappedMatcher() {
candidate := errors.New("taco")
t.matcher.Matches(candidate)
ExpectThat(t.matcherCalled, Equals(true))
ExpectThat(t.suppliedCandidate, Equals("taco"))
}
func (t *ErrorTest) ReturnsWrappedMatcherResult() {
t.wrappedError = errors.New("burrito")
err := t.matcher.Matches(errors.New(""))
ExpectThat(err, Equals(t.wrappedError))
}
File diff suppressed because it is too large Load Diff
@@ -1,92 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type HasSubstrTest struct {
}
func init() { RegisterTestSuite(&HasSubstrTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *HasSubstrTest) Description() {
matcher := HasSubstr("taco")
ExpectThat(matcher.Description(), Equals("has substring \"taco\""))
}
func (t *HasSubstrTest) CandidateIsNil() {
matcher := HasSubstr("")
err := matcher.Matches(nil)
ExpectThat(err, Error(Equals("which is not a string")))
ExpectTrue(isFatal(err))
}
func (t *HasSubstrTest) CandidateIsInteger() {
matcher := HasSubstr("")
err := matcher.Matches(17)
ExpectThat(err, Error(Equals("which is not a string")))
ExpectTrue(isFatal(err))
}
func (t *HasSubstrTest) CandidateIsByteSlice() {
matcher := HasSubstr("")
err := matcher.Matches([]byte{17})
ExpectThat(err, Error(Equals("which is not a string")))
ExpectTrue(isFatal(err))
}
func (t *HasSubstrTest) CandidateDoesntHaveSubstring() {
matcher := HasSubstr("taco")
err := matcher.Matches("tac")
ExpectThat(err, Error(Equals("")))
ExpectFalse(isFatal(err))
}
func (t *HasSubstrTest) CandidateEqualsArg() {
matcher := HasSubstr("taco")
err := matcher.Matches("taco")
ExpectThat(err, Equals(nil))
}
func (t *HasSubstrTest) CandidateHasProperSubstring() {
matcher := HasSubstr("taco")
err := matcher.Matches("burritos and tacos")
ExpectThat(err, Equals(nil))
}
func (t *HasSubstrTest) EmptyStringIsAlwaysSubString() {
matcher := HasSubstr("")
err := matcher.Matches("asdf")
ExpectThat(err, Equals(nil))
}
@@ -1,849 +0,0 @@
// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"fmt"
"io"
"unsafe"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type IdenticalToTest struct {
}
func init() { RegisterTestSuite(&IdenticalToTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *IdenticalToTest) TypesNotIdentical() {
var m Matcher
var err error
type intAlias int
// Type alias expected value
m = IdenticalTo(intAlias(17))
err = m.Matches(int(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int")))
// Type alias candidate
m = IdenticalTo(int(17))
err = m.Matches(intAlias(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.intAlias")))
// int and uint
m = IdenticalTo(int(17))
err = m.Matches(uint(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type uint")))
}
func (t *IdenticalToTest) PredeclaredNilIdentifier() {
var m Matcher
var err error
// Nil literal
m = IdenticalTo(nil)
err = m.Matches(nil)
ExpectEq(nil, err)
// Zero interface var (which is the same as above since IdenticalTo takes an
// interface{} as an arg)
var nilReader io.Reader
var nilWriter io.Writer
m = IdenticalTo(nilReader)
err = m.Matches(nilWriter)
ExpectEq(nil, err)
// Typed nil value.
m = IdenticalTo(nil)
err = m.Matches((chan int)(nil))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type chan int")))
// Non-nil value.
m = IdenticalTo(nil)
err = m.Matches("taco")
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type string")))
}
func (t *IdenticalToTest) Slices() {
var m Matcher
var err error
// Nil expected value
m = IdenticalTo(([]int)(nil))
ExpectEq("identical to <[]int> []", m.Description())
err = m.Matches(([]int)(nil))
ExpectEq(nil, err)
err = m.Matches([]int{})
ExpectThat(err, Error(Equals("which is not an identical reference")))
// Non-nil expected value
o1 := make([]int, 1)
o2 := make([]int, 1)
m = IdenticalTo(o1)
ExpectEq(fmt.Sprintf("identical to <[]int> %v", o1), m.Description())
err = m.Matches(o1)
ExpectEq(nil, err)
err = m.Matches(o2)
ExpectThat(err, Error(Equals("which is not an identical reference")))
}
func (t *IdenticalToTest) Maps() {
var m Matcher
var err error
// Nil expected value
m = IdenticalTo((map[int]int)(nil))
ExpectEq("identical to <map[int]int> map[]", m.Description())
err = m.Matches((map[int]int)(nil))
ExpectEq(nil, err)
err = m.Matches(map[int]int{})
ExpectThat(err, Error(Equals("which is not an identical reference")))
// Non-nil expected value
o1 := map[int]int{}
o2 := map[int]int{}
m = IdenticalTo(o1)
ExpectEq(fmt.Sprintf("identical to <map[int]int> %v", o1), m.Description())
err = m.Matches(o1)
ExpectEq(nil, err)
err = m.Matches(o2)
ExpectThat(err, Error(Equals("which is not an identical reference")))
}
func (t *IdenticalToTest) Functions() {
var m Matcher
var err error
// Nil expected value
m = IdenticalTo((func())(nil))
ExpectEq("identical to <func()> <nil>", m.Description())
err = m.Matches((func())(nil))
ExpectEq(nil, err)
err = m.Matches(func() {})
ExpectThat(err, Error(Equals("which is not an identical reference")))
// Non-nil expected value
o1 := func() {}
o2 := func() {}
m = IdenticalTo(o1)
ExpectEq(fmt.Sprintf("identical to <func()> %v", o1), m.Description())
err = m.Matches(o1)
ExpectEq(nil, err)
err = m.Matches(o2)
ExpectThat(err, Error(Equals("which is not an identical reference")))
}
func (t *IdenticalToTest) Channels() {
var m Matcher
var err error
// Nil expected value
m = IdenticalTo((chan int)(nil))
ExpectEq("identical to <chan int> <nil>", m.Description())
err = m.Matches((chan int)(nil))
ExpectEq(nil, err)
err = m.Matches(make(chan int))
ExpectThat(err, Error(Equals("which is not an identical reference")))
// Non-nil expected value
o1 := make(chan int)
o2 := make(chan int)
m = IdenticalTo(o1)
ExpectEq(fmt.Sprintf("identical to <chan int> %v", o1), m.Description())
err = m.Matches(o1)
ExpectEq(nil, err)
err = m.Matches(o2)
ExpectThat(err, Error(Equals("which is not an identical reference")))
}
func (t *IdenticalToTest) Bools() {
var m Matcher
var err error
// false
m = IdenticalTo(false)
ExpectEq("identical to <bool> false", m.Description())
err = m.Matches(false)
ExpectEq(nil, err)
err = m.Matches(true)
ExpectThat(err, Error(Equals("")))
// true
m = IdenticalTo(true)
ExpectEq("identical to <bool> true", m.Description())
err = m.Matches(false)
ExpectThat(err, Error(Equals("")))
err = m.Matches(true)
ExpectEq(nil, err)
}
func (t *IdenticalToTest) Ints() {
var m Matcher
var err error
m = IdenticalTo(int(17))
ExpectEq("identical to <int> 17", m.Description())
// Identical value
err = m.Matches(int(17))
ExpectEq(nil, err)
// Type alias
type myType int
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Int8s() {
var m Matcher
var err error
m = IdenticalTo(int8(17))
ExpectEq("identical to <int8> 17", m.Description())
// Identical value
err = m.Matches(int8(17))
ExpectEq(nil, err)
// Type alias
type myType int8
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Int16s() {
var m Matcher
var err error
m = IdenticalTo(int16(17))
ExpectEq("identical to <int16> 17", m.Description())
// Identical value
err = m.Matches(int16(17))
ExpectEq(nil, err)
// Type alias
type myType int16
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Int32s() {
var m Matcher
var err error
m = IdenticalTo(int32(17))
ExpectEq("identical to <int32> 17", m.Description())
// Identical value
err = m.Matches(int32(17))
ExpectEq(nil, err)
// Type alias
type myType int32
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int16(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int16")))
}
func (t *IdenticalToTest) Int64s() {
var m Matcher
var err error
m = IdenticalTo(int64(17))
ExpectEq("identical to <int64> 17", m.Description())
// Identical value
err = m.Matches(int64(17))
ExpectEq(nil, err)
// Type alias
type myType int64
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Uints() {
var m Matcher
var err error
m = IdenticalTo(uint(17))
ExpectEq("identical to <uint> 17", m.Description())
// Identical value
err = m.Matches(uint(17))
ExpectEq(nil, err)
// Type alias
type myType uint
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Uint8s() {
var m Matcher
var err error
m = IdenticalTo(uint8(17))
ExpectEq("identical to <uint8> 17", m.Description())
// Identical value
err = m.Matches(uint8(17))
ExpectEq(nil, err)
// Type alias
type myType uint8
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Uint16s() {
var m Matcher
var err error
m = IdenticalTo(uint16(17))
ExpectEq("identical to <uint16> 17", m.Description())
// Identical value
err = m.Matches(uint16(17))
ExpectEq(nil, err)
// Type alias
type myType uint16
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Uint32s() {
var m Matcher
var err error
m = IdenticalTo(uint32(17))
ExpectEq("identical to <uint32> 17", m.Description())
// Identical value
err = m.Matches(uint32(17))
ExpectEq(nil, err)
// Type alias
type myType uint32
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Uint64s() {
var m Matcher
var err error
m = IdenticalTo(uint64(17))
ExpectEq("identical to <uint64> 17", m.Description())
// Identical value
err = m.Matches(uint64(17))
ExpectEq(nil, err)
// Type alias
type myType uint64
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Uintptrs() {
var m Matcher
var err error
m = IdenticalTo(uintptr(17))
ExpectEq("identical to <uintptr> 17", m.Description())
// Identical value
err = m.Matches(uintptr(17))
ExpectEq(nil, err)
// Type alias
type myType uintptr
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Float32s() {
var m Matcher
var err error
m = IdenticalTo(float32(17))
ExpectEq("identical to <float32> 17", m.Description())
// Identical value
err = m.Matches(float32(17))
ExpectEq(nil, err)
// Type alias
type myType float32
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Float64s() {
var m Matcher
var err error
m = IdenticalTo(float64(17))
ExpectEq("identical to <float64> 17", m.Description())
// Identical value
err = m.Matches(float64(17))
ExpectEq(nil, err)
// Type alias
type myType float64
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Complex64s() {
var m Matcher
var err error
m = IdenticalTo(complex64(17))
ExpectEq("identical to <complex64> (17+0i)", m.Description())
// Identical value
err = m.Matches(complex64(17))
ExpectEq(nil, err)
// Type alias
type myType complex64
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) Complex128s() {
var m Matcher
var err error
m = IdenticalTo(complex128(17))
ExpectEq("identical to <complex128> (17+0i)", m.Description())
// Identical value
err = m.Matches(complex128(17))
ExpectEq(nil, err)
// Type alias
type myType complex128
err = m.Matches(myType(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) EmptyComparableArrays() {
var m Matcher
var err error
m = IdenticalTo([0]int{})
ExpectEq("identical to <[0]int> []", m.Description())
// Identical value
err = m.Matches([0]int{})
ExpectEq(nil, err)
// Length too long
err = m.Matches([1]int{17})
ExpectThat(err, Error(Equals("which is of type [1]int")))
// Element type alias
type myType int
err = m.Matches([0]myType{})
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type [0]oglematchers_test.myType")))
// Completely wrong element type
err = m.Matches([0]int32{})
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type [0]int32")))
}
func (t *IdenticalToTest) NonEmptyComparableArrays() {
var m Matcher
var err error
m = IdenticalTo([2]int{17, 19})
ExpectEq("identical to <[2]int> [17 19]", m.Description())
// Identical value
err = m.Matches([2]int{17, 19})
ExpectEq(nil, err)
// Length too short
err = m.Matches([1]int{17})
ExpectThat(err, Error(Equals("which is of type [1]int")))
// Length too long
err = m.Matches([3]int{17, 19, 23})
ExpectThat(err, Error(Equals("which is of type [3]int")))
// First element different
err = m.Matches([2]int{13, 19})
ExpectThat(err, Error(Equals("")))
// Second element different
err = m.Matches([2]int{17, 23})
ExpectThat(err, Error(Equals("")))
// Element type alias
type myType int
err = m.Matches([2]myType{17, 19})
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type [2]oglematchers_test.myType")))
// Completely wrong element type
err = m.Matches([2]int32{17, 19})
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type [2]int32")))
}
func (t *IdenticalToTest) NonEmptyArraysOfComparableArrays() {
var m Matcher
var err error
x := [2][2]int{
[2]int{17, 19},
[2]int{23, 29},
}
m = IdenticalTo(x)
ExpectEq("identical to <[2][2]int> [[17 19] [23 29]]", m.Description())
// Identical value
err = m.Matches([2][2]int{[2]int{17, 19}, [2]int{23, 29}})
ExpectEq(nil, err)
// Outer length too short
err = m.Matches([1][2]int{[2]int{17, 19}})
ExpectThat(err, Error(Equals("which is of type [1][2]int")))
// Inner length too short
err = m.Matches([2][1]int{[1]int{17}, [1]int{23}})
ExpectThat(err, Error(Equals("which is of type [2][1]int")))
// First element different
err = m.Matches([2][2]int{[2]int{13, 19}, [2]int{23, 29}})
ExpectThat(err, Error(Equals("")))
// Element type alias
type myType int
err = m.Matches([2][2]myType{[2]myType{17, 19}, [2]myType{23, 29}})
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type [2][2]oglematchers_test.myType")))
}
func (t *IdenticalToTest) NonComparableArrays() {
x := [0]func(){}
f := func() { IdenticalTo(x) }
ExpectThat(f, Panics(HasSubstr("is not comparable")))
}
func (t *IdenticalToTest) ArraysOfNonComparableArrays() {
x := [0][0]func(){}
f := func() { IdenticalTo(x) }
ExpectThat(f, Panics(HasSubstr("is not comparable")))
}
func (t *IdenticalToTest) Strings() {
var m Matcher
var err error
m = IdenticalTo("taco")
ExpectEq("identical to <string> taco", m.Description())
// Identical value
err = m.Matches("ta" + "co")
ExpectEq(nil, err)
// Type alias
type myType string
err = m.Matches(myType("taco"))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) ComparableStructs() {
var m Matcher
var err error
type subStruct struct {
i int
}
type myStruct struct {
u uint
s subStruct
}
x := myStruct{17, subStruct{19}}
m = IdenticalTo(x)
ExpectEq("identical to <oglematchers_test.myStruct> {17 {19}}", m.Description())
// Identical value
err = m.Matches(myStruct{17, subStruct{19}})
ExpectEq(nil, err)
// Wrong outer field
err = m.Matches(myStruct{13, subStruct{19}})
ExpectThat(err, Error(Equals("")))
// Wrong inner field
err = m.Matches(myStruct{17, subStruct{23}})
ExpectThat(err, Error(Equals("")))
// Type alias
type myType myStruct
err = m.Matches(myType{17, subStruct{19}})
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) NonComparableStructs() {
type subStruct struct {
s []int
}
type myStruct struct {
u uint
s subStruct
}
x := myStruct{17, subStruct{[]int{19}}}
f := func() { IdenticalTo(x) }
ExpectThat(f, Panics(AllOf(HasSubstr("IdenticalTo"), HasSubstr("comparable"))))
}
func (t *IdenticalToTest) NilUnsafePointer() {
var m Matcher
var err error
x := unsafe.Pointer(nil)
m = IdenticalTo(x)
ExpectEq(fmt.Sprintf("identical to <unsafe.Pointer> %v", x), m.Description())
// Identical value
err = m.Matches(unsafe.Pointer(nil))
ExpectEq(nil, err)
// Wrong value
j := 17
err = m.Matches(unsafe.Pointer(&j))
ExpectThat(err, Error(Equals("")))
// Type alias
type myType unsafe.Pointer
err = m.Matches(myType(unsafe.Pointer(nil)))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) NonNilUnsafePointer() {
var m Matcher
var err error
i := 17
x := unsafe.Pointer(&i)
m = IdenticalTo(x)
ExpectEq(fmt.Sprintf("identical to <unsafe.Pointer> %v", x), m.Description())
// Identical value
err = m.Matches(unsafe.Pointer(&i))
ExpectEq(nil, err)
// Nil value
err = m.Matches(unsafe.Pointer(nil))
ExpectThat(err, Error(Equals("")))
// Wrong value
j := 17
err = m.Matches(unsafe.Pointer(&j))
ExpectThat(err, Error(Equals("")))
// Type alias
type myType unsafe.Pointer
err = m.Matches(myType(unsafe.Pointer(&i)))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
func (t *IdenticalToTest) IntAlias() {
var m Matcher
var err error
type intAlias int
m = IdenticalTo(intAlias(17))
ExpectEq("identical to <oglematchers_test.intAlias> 17", m.Description())
// Identical value
err = m.Matches(intAlias(17))
ExpectEq(nil, err)
// Int
err = m.Matches(int(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int")))
// Completely wrong type
err = m.Matches(int32(17))
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("which is of type int32")))
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,92 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type MatchesRegexpTest struct {
}
func init() { RegisterTestSuite(&MatchesRegexpTest{}) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *MatchesRegexpTest) Description() {
m := MatchesRegexp("foo.*bar")
ExpectEq("matches regexp \"foo.*bar\"", m.Description())
}
func (t *MatchesRegexpTest) InvalidRegexp() {
ExpectThat(
func() { MatchesRegexp("(foo") },
Panics(HasSubstr("missing closing )")))
}
func (t *MatchesRegexpTest) CandidateIsNil() {
m := MatchesRegexp("")
err := m.Matches(nil)
ExpectThat(err, Error(Equals("which is not a string or []byte")))
ExpectTrue(isFatal(err))
}
func (t *MatchesRegexpTest) CandidateIsInteger() {
m := MatchesRegexp("")
err := m.Matches(17)
ExpectThat(err, Error(Equals("which is not a string or []byte")))
ExpectTrue(isFatal(err))
}
func (t *MatchesRegexpTest) NonMatchingCandidates() {
m := MatchesRegexp("fo[op]\\s+x")
var err error
err = m.Matches("fon x")
ExpectThat(err, Error(Equals("")))
ExpectFalse(isFatal(err))
err = m.Matches("fopx")
ExpectThat(err, Error(Equals("")))
ExpectFalse(isFatal(err))
err = m.Matches("fop ")
ExpectThat(err, Error(Equals("")))
ExpectFalse(isFatal(err))
}
func (t *MatchesRegexpTest) MatchingCandidates() {
m := MatchesRegexp("fo[op]\\s+x")
var err error
err = m.Matches("foo x")
ExpectEq(nil, err)
err = m.Matches("fop x")
ExpectEq(nil, err)
err = m.Matches("blah blah foo x blah blah")
ExpectEq(nil, err)
}
@@ -1,107 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"errors"
"testing"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type fakeMatcher struct {
matchFunc func(interface{}) error
description string
}
func (m *fakeMatcher) Matches(c interface{}) error {
return m.matchFunc(c)
}
func (m *fakeMatcher) Description() string {
return m.description
}
type NotTest struct {
}
func init() { RegisterTestSuite(&NotTest{}) }
func TestOgletest(t *testing.T) { RunTests(t) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *NotTest) CallsWrapped() {
var suppliedCandidate interface{}
matchFunc := func(c interface{}) error {
suppliedCandidate = c
return nil
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Not(wrapped)
matcher.Matches(17)
ExpectThat(suppliedCandidate, Equals(17))
}
func (t *NotTest) WrappedReturnsTrue() {
matchFunc := func(c interface{}) error {
return nil
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Not(wrapped)
err := matcher.Matches(0)
ExpectThat(err, Error(Equals("")))
}
func (t *NotTest) WrappedReturnsNonFatalError() {
matchFunc := func(c interface{}) error {
return errors.New("taco")
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Not(wrapped)
err := matcher.Matches(0)
ExpectEq(nil, err)
}
func (t *NotTest) WrappedReturnsFatalError() {
matchFunc := func(c interface{}) error {
return NewFatalError("taco")
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Not(wrapped)
err := matcher.Matches(0)
ExpectThat(err, Error(Equals("taco")))
}
func (t *NotTest) Description() {
wrapped := &fakeMatcher{nil, "taco"}
matcher := Not(wrapped)
ExpectEq("not(taco)", matcher.Description())
}
@@ -1,2 +0,0 @@
#ignore
-timeout=1s
@@ -1,141 +0,0 @@
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"errors"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type PanicsTest struct {
matcherCalled bool
suppliedCandidate interface{}
wrappedError error
matcher Matcher
}
func init() { RegisterTestSuite(&PanicsTest{}) }
func (t *PanicsTest) SetUp(i *TestInfo) {
wrapped := &fakeMatcher{
func(c interface{}) error {
t.matcherCalled = true
t.suppliedCandidate = c
return t.wrappedError
},
"foo",
}
t.matcher = Panics(wrapped)
}
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *PanicsTest) Description() {
ExpectThat(t.matcher.Description(), Equals("panics with: foo"))
}
func (t *PanicsTest) CandidateIsNil() {
err := t.matcher.Matches(nil)
ExpectThat(err, Error(Equals("which is not a zero-arg function")))
ExpectTrue(isFatal(err))
}
func (t *PanicsTest) CandidateIsString() {
err := t.matcher.Matches("taco")
ExpectThat(err, Error(Equals("which is not a zero-arg function")))
ExpectTrue(isFatal(err))
}
func (t *PanicsTest) CandidateTakesArgs() {
err := t.matcher.Matches(func(i int) string { return "" })
ExpectThat(err, Error(Equals("which is not a zero-arg function")))
ExpectTrue(isFatal(err))
}
func (t *PanicsTest) CallsFunction() {
callCount := 0
t.matcher.Matches(func() string {
callCount++
return ""
})
ExpectThat(callCount, Equals(1))
}
func (t *PanicsTest) FunctionDoesntPanic() {
err := t.matcher.Matches(func() {})
ExpectThat(err, Error(Equals("which didn't panic")))
ExpectFalse(isFatal(err))
}
func (t *PanicsTest) CallsWrappedMatcher() {
expectedErr := 17
t.wrappedError = errors.New("")
t.matcher.Matches(func() { panic(expectedErr) })
ExpectThat(t.suppliedCandidate, Equals(expectedErr))
}
func (t *PanicsTest) WrappedReturnsTrue() {
err := t.matcher.Matches(func() { panic("") })
ExpectEq(nil, err)
}
func (t *PanicsTest) WrappedReturnsFatalErrorWithoutText() {
t.wrappedError = NewFatalError("")
err := t.matcher.Matches(func() { panic(17) })
ExpectThat(err, Error(Equals("which panicked with: 17")))
ExpectFalse(isFatal(err))
}
func (t *PanicsTest) WrappedReturnsFatalErrorWithText() {
t.wrappedError = NewFatalError("which blah")
err := t.matcher.Matches(func() { panic(17) })
ExpectThat(err, Error(Equals("which panicked with: 17, which blah")))
ExpectFalse(isFatal(err))
}
func (t *PanicsTest) WrappedReturnsNonFatalErrorWithoutText() {
t.wrappedError = errors.New("")
err := t.matcher.Matches(func() { panic(17) })
ExpectThat(err, Error(Equals("which panicked with: 17")))
ExpectFalse(isFatal(err))
}
func (t *PanicsTest) WrappedReturnsNonFatalErrorWithText() {
t.wrappedError = errors.New("which blah")
err := t.matcher.Matches(func() { panic(17) })
ExpectThat(err, Error(Equals("which panicked with: 17, which blah")))
ExpectFalse(isFatal(err))
}
@@ -1,153 +0,0 @@
// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package oglematchers_test
import (
"errors"
"testing"
. "github.com/smartystreets/goconvey/convey/assertions/oglematchers"
. "github.com/smartystreets/goconvey/convey/assertions/ogletest"
)
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
type PointeeTest struct{}
func init() { RegisterTestSuite(&PointeeTest{}) }
func TestPointee(t *testing.T) { RunTests(t) }
////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////
func (t *PointeeTest) Description() {
wrapped := &fakeMatcher{nil, "taco"}
matcher := Pointee(wrapped)
ExpectEq("pointee(taco)", matcher.Description())
}
func (t *PointeeTest) CandidateIsNotAPointer() {
matcher := Pointee(HasSubstr(""))
err := matcher.Matches([]byte{})
ExpectThat(err, Error(Equals("which is not a pointer")))
ExpectTrue(isFatal(err))
}
func (t *PointeeTest) CandidateIsANilLiteral() {
matcher := Pointee(HasSubstr(""))
err := matcher.Matches(nil)
ExpectThat(err, Error(Equals("which is not a pointer")))
ExpectTrue(isFatal(err))
}
func (t *PointeeTest) CandidateIsANilPointer() {
matcher := Pointee(HasSubstr(""))
err := matcher.Matches((*int)(nil))
ExpectThat(err, Error(Equals("")))
ExpectTrue(isFatal(err))
}
func (t *PointeeTest) CallsWrapped() {
var suppliedCandidate interface{}
matchFunc := func(c interface{}) error {
suppliedCandidate = c
return nil
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Pointee(wrapped)
someSlice := []byte{}
matcher.Matches(&someSlice)
ExpectThat(suppliedCandidate, IdenticalTo(someSlice))
}
func (t *PointeeTest) WrappedReturnsOkay() {
matchFunc := func(c interface{}) error {
return nil
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Pointee(wrapped)
err := matcher.Matches(new(int))
ExpectEq(nil, err)
}
func (t *PointeeTest) WrappedReturnsNonFatalNonEmptyError() {
matchFunc := func(c interface{}) error {
return errors.New("taco")
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Pointee(wrapped)
i := 17
err := matcher.Matches(&i)
ExpectFalse(isFatal(err))
ExpectThat(err, Error(Equals("taco")))
}
func (t *PointeeTest) WrappedReturnsNonFatalEmptyError() {
matchFunc := func(c interface{}) error {
return errors.New("")
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Pointee(wrapped)
i := 17
err := matcher.Matches(&i)
ExpectFalse(isFatal(err))
ExpectThat(err, Error(HasSubstr("whose pointee")))
ExpectThat(err, Error(HasSubstr("17")))
}
func (t *PointeeTest) WrappedReturnsFatalNonEmptyError() {
matchFunc := func(c interface{}) error {
return NewFatalError("taco")
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Pointee(wrapped)
i := 17
err := matcher.Matches(&i)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(Equals("taco")))
}
func (t *PointeeTest) WrappedReturnsFatalEmptyError() {
matchFunc := func(c interface{}) error {
return NewFatalError("")
}
wrapped := &fakeMatcher{matchFunc, ""}
matcher := Pointee(wrapped)
i := 17
err := matcher.Matches(&i)
ExpectTrue(isFatal(err))
ExpectThat(err, Error(HasSubstr("whose pointee")))
ExpectThat(err, Error(HasSubstr("17")))
}
@@ -1,5 +0,0 @@
*.6
6.out
_obj/
_test/
_testmain.go
@@ -1,101 +0,0 @@
`oglemock` is a mocking framework for the Go programming language with the
following features:
* An extensive and extensible set of matchers for expressing call
expectations (provided by the [oglematchers][] package).
* Clean, readable output that tells you exactly what you need to know.
* Style and semantics similar to [Google Mock][googlemock] and
[Google JS Test][google-js-test].
* Seamless integration with the [ogletest][] unit testing framework.
It can be integrated into any testing framework (including Go's `testing`
package), but out of the box support is built in to [ogletest][] and that is the
easiest place to use it.
Installation
------------
First, make sure you have installed Go 1.0.2 or newer. See
[here][golang-install] for instructions.
Use the following command to install `oglemock` and its dependencies, and to
keep them up to date:
go get -u github.com/smartystreets/goconvey/convey/assertions/oglemock
go get -u github.com/smartystreets/goconvey/convey/assertions/oglemock/createmock
Those commands will install the `oglemock` package itself, along with the
`createmock` tool that is used to auto-generate mock types.
Generating and using mock types
-------------------------------
Automatically generating a mock implementation of an interface is easy. If you
want to mock interfaces `Bar` and `Baz` from package `foo`, simply run the
following:
createmock foo Bar Baz
That will print source code that can be saved to a file and used in your tests.
For example, to create a `mock_io` package containing mock implementations of
`io.Reader` and `io.Writer`:
mkdir mock_io
createmock io Reader Writer > mock_io/mock_io.go
The new package will be named `mock_io`, and contain types called `MockReader`
and `MockWriter`, which implement `io.Reader` and `io.Writer` respectively.
For each generated mock type, there is a corresponding function for creating an
instance of that type given a `Controller` object (see below). For example, to
create a mock reader:
```go
someController := [...] // See next section.
someReader := mock_io.NewMockReader(someController, "Mock file reader")
```
The snippet above creates a mock `io.Reader` that reports failures to
`someController`. The reader can subsequently have expectations set up and be
passed to your code under test that uses an `io.Reader`.
Getting ahold of a controller
-----------------------------
[oglemock.Controller][controller-ref] is used to create mock objects, and to set
up and verify expectations for them. You can create one by calling
`NewController` with an `ErrorReporter`, which is the basic type used to
interface between `oglemock` and the testing framework within which it is being
used.
If you are using [ogletest][] you don't need to worry about any of this, since
the `TestInfo` struct provided to your test's `SetUp` function already contains
a working `Controller` that you can use to create mock object, and you can use
the built-in `ExpectCall` function for setting expectations. (See the
[ogletest documentation][ogletest-docs] for more info.) Otherwise, you will need
to implement the simple [ErrorReporter interface][reporter-ref] for your test
environment.
Documentation
-------------
For thorough documentation, including information on how to set up expectations,
see [here][oglemock-docs].
[controller-ref]: http://gopkgdoc.appspot.com/pkg/github.com/smartystreets/goconvey/convey/assertions/oglemock#Controller
[reporter-ref]: http://gopkgdoc.appspot.com/pkg/github.com/smartystreets/goconvey/convey/assertions/oglemock#ErrorReporter
[golang-install]: http://golang.org/doc/install.html
[google-js-test]: http://code.google.com/p/google-js-test/
[googlemock]: http://code.google.com/p/googlemock/
[oglematchers]: https://github.com/smartystreets/goconvey/convey/assertions/oglematchers
[oglemock-docs]: http://gopkgdoc.appspot.com/pkg/github.com/smartystreets/goconvey/convey/assertions/oglemock
[ogletest]: https://github.com/smartystreets/goconvey/convey/assertions/oglematchers
[ogletest-docs]: http://gopkgdoc.appspot.com/pkg/github.com/smartystreets/goconvey/convey/assertions/ogletest

Some files were not shown because too many files have changed in this diff Show More