├── .build.yml
├── .gitignore
├── CHANGELOG.md
├── Configuration.md
├── Dockerfile
├── Dockerfile_Build
├── Gruntfile.js
├── Installation.md
├── LICENSE
├── README.md
├── amc.dev.conf
├── common
├── alert.go
├── backup_restore.go
├── config.go
├── parser.go
├── remote_job.go
├── set.go
├── stats.go
├── sync_value.go
├── types.go
└── utils.go
├── controllers
├── backup_restore.go
├── cluster.go
├── common.go
├── enterprise.go
├── main.go
├── main_enterprise.go
├── middleware
│ └── sessions
│ │ ├── cookie.go
│ │ └── sessions.go
├── session.go
├── users.go
└── xdr.go
├── deployment
├── common
│ ├── amc.conf
│ ├── amc.deb
│ ├── amc.docker.sh
│ ├── amc.other.sh
│ ├── amc.rpm
│ ├── amc.service
│ └── systemd_after_install.sh
└── release
│ ├── darwin
│ ├── LaunchAgents
│ │ └── com.aerospike.amc.plist
│ ├── Logs
│ │ └── amc
│ │ │ └── .placeholder
│ └── amc
│ │ ├── amc.conf
│ │ └── uninstall.sh
│ └── linux
│ ├── etc
│ └── amc
│ │ └── amc.conf
│ └── var
│ └── log
│ └── amc
│ └── .placeholder
├── go-time-series
├── LICENSE
├── README.md
├── glide.lock
├── glide.yaml
├── level.go
└── timeseries.go
├── go.mod
├── go.sum
├── mailer
├── mailer.go
└── templates
│ ├── alerts
│ └── generic.html
│ └── base.html
├── main_darwin.go
├── main_linux.go
├── make.sh
├── models
├── attr_aliases.go
├── backup.go
├── cluster.go
├── namespace.go
├── namespace_notifications.go
├── node.go
├── node_notifications.go
├── observer.go
└── restore.go
├── package-lock.json
├── package.json
├── rrd
├── rrd.go
├── rrd_test.go
└── simple_bucket.go
├── run.sh
├── server-dev.sh
├── static
├── css
│ ├── alerts.css
│ ├── common.css
│ ├── fonts
│ │ ├── MavenPro-Regular.ttf
│ │ └── icomoon.ttf
│ ├── grid
│ │ └── 960.css
│ ├── icons.css
│ ├── jqgrid
│ │ ├── images
│ │ │ ├── ui-icons_2e83ff_256x240.png
│ │ │ └── ui-icons_888888_256x240.png
│ │ ├── nav.buttons.jquerui.css
│ │ └── ui.jqgrid.css
│ ├── jqueryui
│ │ ├── images
│ │ │ ├── animated-overlay.gif
│ │ │ ├── ui-bg_flat_30_cccccc_40x100.png
│ │ │ ├── ui-bg_flat_50_5c5c5c_40x100.png
│ │ │ ├── ui-bg_glass_20_555555_1x400.png
│ │ │ ├── ui-bg_glass_40_0078a3_1x400.png
│ │ │ ├── ui-bg_glass_40_ffc73d_1x400.png
│ │ │ ├── ui-bg_glass_75_d0e5f5_1x400.png
│ │ │ ├── ui-bg_gloss-wave_25_333333_500x100.png
│ │ │ ├── ui-bg_highlight-soft_80_eeeeee_1x100.png
│ │ │ ├── ui-bg_inset-hard_100_fcfdfd_1x100.png
│ │ │ ├── ui-bg_inset-soft_25_000000_1x100.png
│ │ │ ├── ui-bg_inset-soft_30_f58400_1x100.png
│ │ │ ├── ui-icons_222222_256x240.png
│ │ │ ├── ui-icons_4b8e0b_256x240.png
│ │ │ ├── ui-icons_a83300_256x240.png
│ │ │ ├── ui-icons_cccccc_256x240.png
│ │ │ └── ui-icons_ffffff_256x240.png
│ │ └── jquery-ui-1.10.4.custom.min.css
│ ├── sprite.css
│ ├── sprite.png
│ ├── timeseries.css
│ └── vertical-tabs.css
├── images
│ ├── arrow_down.svg
│ ├── arrow_up.svg
│ ├── bg-btn-blue.png
│ ├── bg-btn-grey.png
│ ├── cog.png
│ ├── favicon.png
│ ├── link.png
│ ├── loading.gif
│ └── sidepanelpattern.png
├── index.html
└── js
│ ├── collections
│ ├── common
│ │ └── MultiClusters.js
│ ├── configs
│ │ ├── namespaces.js
│ │ ├── nodes.js
│ │ ├── sindex.js
│ │ └── xdr.js
│ ├── dashboard
│ │ ├── clusterwidenamespaces.js
│ │ ├── namespaces.js
│ │ ├── nodes.js
│ │ └── xdrs.js
│ ├── definitions
│ │ ├── sets.js
│ │ ├── sindexes.js
│ │ ├── udf.js
│ │ └── xdrs.js
│ ├── jobs
│ │ └── nodes.js
│ ├── latency
│ │ └── nodes.js
│ └── statistics
│ │ ├── namespaces.js
│ │ ├── nodes.js
│ │ ├── sindex.js
│ │ └── xdr.js
│ ├── config
│ ├── app-config.js
│ ├── var-details.js
│ └── view-config.js
│ ├── dev.app.build.js
│ ├── helper
│ ├── AjaxManager.js
│ ├── authmanager.js
│ ├── bulletchart.js
│ ├── command-line.js
│ ├── def-table.js
│ ├── definitions
│ │ ├── set-table.js
│ │ ├── sindex-table.js
│ │ ├── udf-table.js
│ │ └── xdr-table.js
│ ├── drilldown-charts.js
│ ├── edit-config.js
│ ├── job-table.js
│ ├── jqgrid-helper.js
│ ├── login.js
│ ├── modal.js
│ ├── namespace-clusterwide-table.js
│ ├── namespace-table.js
│ ├── node-table.js
│ ├── notification.js
│ ├── overlay.js
│ ├── piechart.js
│ ├── servicemanager.js
│ ├── sessionmanager.js
│ ├── stat-table.js
│ ├── timechart-helper.js
│ ├── toggle.js
│ ├── usermanager.js
│ ├── util.js
│ └── xdr-table.js
│ ├── libs
│ ├── backbone
│ │ ├── backbone-min.js
│ │ ├── backbone.js
│ │ └── backbone.poller.js
│ ├── d3
│ │ ├── d3.js
│ │ └── d3.layout.min.js
│ ├── jquery
│ │ └── consolidated-jquery-functionalities.min.js
│ ├── require
│ │ └── require.js
│ ├── spin
│ │ └── spin.min.js
│ ├── timechart
│ │ └── timechart.js
│ └── underscore
│ │ ├── underscore-min.js
│ │ └── underscore.js
│ ├── models
│ ├── common
│ │ ├── AlertEmailsModel.js
│ │ ├── MultiCluster.js
│ │ ├── PopupModel.js
│ │ └── alertmodel.js
│ ├── configs
│ │ ├── backupmodel.js
│ │ ├── clustermodel.js
│ │ ├── restoremodel.js
│ │ ├── roleadminmodel.js
│ │ ├── statmodel.js
│ │ └── useradminmodel.js
│ ├── dashboard
│ │ ├── clustermodel.js
│ │ ├── clusterwidenamespacemodel.js
│ │ ├── namespacemodel.js
│ │ ├── nodemodel.js
│ │ ├── throughputmodel.js
│ │ └── xdrmodel.js
│ ├── definitions
│ │ ├── clustermodel.js
│ │ ├── setsmodel.js
│ │ ├── sindexmodel.js
│ │ ├── storagemodel.js
│ │ ├── udfmodel.js
│ │ └── xdrmodel.js
│ ├── jobs
│ │ ├── clustermodel.js
│ │ └── nodemodel.js
│ ├── latency
│ │ ├── clustermodel.js
│ │ ├── nodeCentralisedModel.js
│ │ └── nodemodel.js
│ └── statistics
│ │ ├── clustermodel.js
│ │ ├── statmodel.js
│ │ └── stattracker.js
│ ├── onepage.js
│ ├── prod.app.build.js
│ ├── setup.js
│ └── views
│ ├── common
│ ├── AlertEmailsView.js
│ ├── MultiClusterView.js
│ ├── alertview.js
│ └── nodelistview.js
│ ├── configs
│ ├── backupview.js
│ ├── restoreview.js
│ ├── roleadminview.js
│ ├── statview.js
│ └── useradminview.js
│ ├── dashboard
│ ├── clusterwidenamespaceview.js
│ ├── namespaceview.js
│ ├── nodeview.js
│ ├── pieview.js
│ ├── summaryView.js
│ ├── throughputview.js
│ └── xdrview.js
│ ├── definitions
│ ├── setsview.js
│ ├── sindexview.js
│ ├── storageview.js
│ ├── udfview.js
│ └── xdrview.js
│ ├── jobs
│ └── nodeview.js
│ ├── latency
│ └── nodeview.js
│ └── statistics
│ ├── stattrackerview.js
│ └── statview.js
└── tools
└── load
├── client.go
├── main
└── main.go
└── response
└── types.go
/.build.yml:
--------------------------------------------------------------------------------
1 | name: aerospike-console
2 | dir: src/github.com/aerospike-community/amc
3 |
4 | container:
5 | - base:
6 | - docker.qe.aerospike.com/build/amc:golang-1.11
7 |
8 | environment:
9 | GOPATH: /work/source
10 | BIN: $GOPATH/bin
11 | REPO: github.com/aerospike-community/amc
12 | CGO_ENABLED: 0
13 |
14 | build:
15 | - name: default
16 | script:
17 | - ls -la
18 | - cd src/$REPO
19 | - ./make.sh enterprise prod linux
20 | - ./make.sh community prod linux
21 | - ./make.sh enterprise prod darwin
22 | - ./make.sh community prod darwin
23 | artifact:
24 | - aerospike-amc-*.deb
25 | - aerospike-amc-*.rpm
26 | - aerospike-amc-*.gz
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | node_modules/
3 | build/
4 | amc.db3
5 | deployment/release/amc/opt/amc/amc
6 | deployment/release/amc/opt/amc/static
7 | deployment/release/amc/opt/amc/mailer
8 | amc
9 | *.todo
10 | amc.db.old
11 | amc.db
12 |
13 | aerospike-amc-enterprise-*.deb
14 | aerospike-amc-enterprise-*.rpm
15 | aerospike-amc-enterprise-*.tar.gz
16 |
17 | .71e384d8029d70a336275f921ad8b1f595c99da7
18 | .05294f73cd9a9a4b5633cc6b9b64eb362bddcae1
19 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:stretch-slim
2 |
3 | ARG AMC_VERSION=5.0.0
4 |
5 | RUN apt update -y \
6 | && apt -y install wget procps \
7 | && wget https://github.com/aerospike-community/amc/releases/download/${AMC_VERSION}/aerospike-amc-enterprise-${AMC_VERSION}_amd64.deb --no-check-certificate \
8 | && dpkg -i aerospike-amc-enterprise-${AMC_VERSION}_amd64.deb \
9 | && rm aerospike-amc-enterprise-${AMC_VERSION}_amd64.deb \
10 | && dpkg -r wget ca-certificates \
11 | && dpkg --purge wget ca-certificates \
12 | && apt-get purge -y \
13 | && apt autoremove -y
14 |
15 | COPY ./deployment/common/amc.docker.sh /opt/amc/amc.docker.sh
16 |
17 | EXPOSE 8081
18 |
19 | ENTRYPOINT [ "/opt/amc/amc.docker.sh", "amc" ]
20 |
--------------------------------------------------------------------------------
/Dockerfile_Build:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # build/golang:1.7
3 | ################################################################################
4 |
5 | # Base Image
6 | FROM golang:1.7
7 |
8 | # Dependencies
9 | RUN apt-get update
10 | RUN apt-get install -y build-essential
11 |
12 | RUN apt-get install -y curl
13 | RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
14 | RUN apt-get install -y nodejs
15 |
16 | RUN npm install grunt -g
17 |
18 | RUN apt-get install -y ruby ruby-dev rubygems gcc make
19 | RUN gem install --no-ri --no-rdoc fpm
20 | RUN apt-get install -y rpm
21 |
22 | RUN apt-get install -y zip tar gzip
23 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | grunt.initConfig({
3 | // clean directory
4 | clean: {
5 | build: 'build/'
6 | },
7 |
8 | // copy directory
9 | copy: {
10 | build: {
11 | expand: true,
12 | src: 'static/**',
13 | dest: 'build/'
14 | }
15 | },
16 |
17 | // revision javascript and css files
18 | filerev: {
19 | options: {
20 | algorithm: 'md5',
21 | length: 8
22 | },
23 | js: {
24 | src: [
25 | // exclude lib directory
26 | 'build/static/js/*.js',
27 | 'build/static/js/collections/**/*.js',
28 | 'build/static/js/config/**/*.js',
29 | 'build/static/js/helper/**/*.js',
30 | 'build/static/js/models/**/*.js',
31 | 'build/static/js/views/**/*.js',
32 | ]
33 | },
34 | css: {
35 | src: 'build/static/css/**/*.css',
36 | },
37 | },
38 |
39 | // replace filenames with revisioned file names
40 | filerev_replace: {
41 | options: {
42 | assets_root: 'build',
43 | },
44 | html: {
45 | src: 'build/static/index.html',
46 | },
47 | },
48 |
49 | // filerev_replace does not replace data-main argument supplied to
50 | // requirejs, doing that here
51 | replace: {
52 | requirejs: {
53 | src: 'build/static/index.html',
54 | overwrite: true,
55 | replacements: [{
56 | // replace data-main with the revisioned file name
57 | from: 'static/js/setup',
58 | to: function(match) {
59 | var k, v;
60 | for(k in grunt.filerev.summary) {
61 | v = grunt.filerev.summary[k];
62 | if(k.indexOf('static/js/setup') !== -1) {
63 | // remove prefix 'build/' and suffix '.js'
64 | return v.slice('build/'.length, -1*'.js'.length);
65 | }
66 | }
67 | return match;
68 | }
69 | }],
70 | },
71 | },
72 |
73 | // minify javascript files
74 | uglify: {
75 | options: {
76 | sourceMap: true,
77 | sourceMapIncludeSources: true,
78 | },
79 | js: {
80 | files: [{
81 | expand: true,
82 | src: ['build/static/js/**/*.js'],
83 | dest: '', // overwrite original files
84 | }]
85 | },
86 | },
87 |
88 | // minify css files
89 | cssmin: {
90 | css: {
91 | files: [{
92 | expand: true,
93 | src: ['build/static/css/**/*.css'],
94 | dest: '', // overwrite original files
95 | }]
96 | }
97 | },
98 |
99 | });
100 |
101 | // Configure requirejs paths to serve revved files
102 | grunt.registerTask('require-paths', '', function() {
103 | var config = concatConfig();
104 | var file = findMainConfigFile();
105 | grunt.file.write(file, config);
106 | return;
107 |
108 | // concat revved config and original config
109 | function concatConfig() {
110 | var config = 'require.config({ paths: {';
111 | var k, v;
112 | for(k in grunt.filerev.summary) {
113 | v = grunt.filerev.summary[k];
114 | if(k.indexOf('.js') !== -1) {
115 | // remove prefix 'build/static/js/' and suffix '.js'
116 | k = k.slice('build/static/js/'.length, -1*'.js'.length);
117 | v = v.slice('build/static/js/'.length, -1*'.js'.length);
118 | config += "'" + k + "'" + ":" + "'" + v + "'" + ", \n";
119 | }
120 | }
121 | config += '}});';
122 | // add original config
123 | config += '\n' + grunt.file.read('static/js/setup.js');
124 | return config;
125 | }
126 |
127 | // find the main config file for requirejs
128 | function findMainConfigFile() {
129 | var k, v;
130 | for(k in grunt.filerev.summary) {
131 | v = grunt.filerev.summary[k];
132 | // setup.js is the main config file for requirejs
133 | if(k.indexOf('setup.js') !== -1) {
134 | return v;
135 | }
136 | }
137 | }
138 | });
139 |
140 | // load modules
141 | grunt.loadNpmTasks('grunt-contrib-cssmin');
142 | grunt.loadNpmTasks('grunt-contrib-clean');
143 | grunt.loadNpmTasks('grunt-contrib-copy');
144 | grunt.loadNpmTasks('grunt-contrib-uglify');
145 | grunt.loadNpmTasks('grunt-filerev');
146 | grunt.loadNpmTasks('grunt-filerev-replace');
147 | grunt.loadNpmTasks('grunt-text-replace');
148 |
149 | grunt.registerTask('default', ['clean', 'copy', 'filerev', 'filerev_replace', 'replace', 'require-paths', 'uglify', 'cssmin']);
150 | }
151 |
152 |
--------------------------------------------------------------------------------
/Installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Upgrade to AMC 4.0
3 | description: Learn how to upgrade to AMC 4.0
4 | ---
5 |
6 | Upgrade to AMC 4.0 and above from previous versions.
7 |
8 | ### Debian Based Systems like Debian, Ubuntu
9 |
10 | 1. uninstall the older amc version
11 | ```
12 | sudo dpkg -P aerospike-amc-
13 | ```
14 |
15 | 2. install AMC
16 | ```
17 | sudo dpkg -i aerospike-amc--.deb
18 | ```
19 |
20 | 3. start AMC
21 | ```
22 | sudo service amc start
23 | ```
24 |
25 | 3. stop AMC
26 | ```
27 | sudo service amc stop
28 | ```
29 |
30 | ### RPM Based Systems like CentOS, Red Hat
31 | 1. uninstall the older amc version
32 | ```
33 | sudo rpm -e aerospike-amc-
34 | ```
35 |
36 | 2. install dependencies
37 | ```
38 | sudo yum install -y initscripts
39 | ```
40 |
41 | 3. install AMC
42 | ```
43 | sudo rpm -i aerospike-amc--.rpm
44 | ```
45 |
46 | 4. start AMC
47 | ```
48 | sudo service amc start
49 | ```
50 |
51 | 5. stop AMC
52 | ```
53 | sudo service amc stop
54 | ```
55 |
56 | ### zip installation
57 | 1. install AMC
58 | ```
59 | tar -xvf aerospike-amc--.tar.gz -C /
60 | ```
61 |
62 | 2. start AMC
63 | ```
64 | sudo /etc/init.d/amc start
65 | ```
66 |
67 | 3. stop AMC
68 | ```
69 | sudo /etc/init.d/amc stop
70 | ```
71 |
72 | ### MacOS
73 |
74 | 1. install AMC
75 | ```
76 | sudo tar -xvf aerospike-amc---darwin.tar.gz -C /Library
77 | ```
78 |
79 | 2. start AMC
80 | ```
81 | sudo launchctl load /Library/LaunchAgents/com.aerospike.amc.plist
82 | ```
83 |
84 | 3. stop AMC
85 | ```
86 | sudo launchctl unload /Library/LaunchAgents/com.aerospike.amc.plist
87 | ```
88 |
89 |
--------------------------------------------------------------------------------
/amc.dev.conf:
--------------------------------------------------------------------------------
1 | [AMC]
2 | update_interval = 5
3 | #certfile = ""
4 | #keyfile = ""
5 | #Example : File paths should be double quoted.
6 | #certfile = "/home/amc/self-ssl.crt"
7 | #keyfile = "/home/amc/self-ssl.key"
8 |
9 | database = "/home/zohar/go/src/github.com/aerospike-community/amc/amc.db"
10 |
11 | bind = "0.0.0.0:8081"
12 | pidfile = "/tmp/amc.pid"
13 | loglevel = "debug"
14 | errorlog = "/home/zohar/go/src/github.com/aerospike-community/amc/amc.log"
15 | chdir = "/home/zohar/go/src/github.com/aerospike-community/amc/"
16 | static_dir = "/home/zohar/go/src/github.com/aerospike-community/amc/static"
17 | timeout = 150
18 |
19 | # when you start monitoring a cluster, it will be polled activaly in the background.
20 | # this setting determines how long will that clustered be kept after it is not polled anymore.
21 | # This setting will not affect the clusters in the [amc.clusters] section.
22 | # values <= 0 mean never remove.
23 | cluster_inactive_before_removal = 1800
24 |
25 | [amc.clusters]
26 |
27 | # [amc.clusters.db1]
28 | # host = "ubvm"
29 | #tls_name =
30 | # port = 3000
31 | #user = "admin"
32 | #password = "admin"
33 | #alias =
34 |
35 | [amc.clusters.db2]
36 | host = "172.17.0.3"
37 | #tls_name = ""
38 | port = 3000
39 | #user = "admin"
40 | #password = "admin"
41 | #alias =
42 | show_in_ui = true
43 |
44 | [mailer]
45 | template_path = "/home/zohar/go/src/github.com/aerospike-community/amc/mailer/templates"
46 | #host = "smtp.outlook.com"
47 | #port = 587
48 | #user = ""
49 | #password = ""
50 | #send_to = ["khosrow@aerospike.com"]
51 | accept_invalid_cert = true
52 |
53 | [basic_auth]
54 | # you can also set $AMC_AUTH_USER env variable
55 | #user = "admin"
56 | # you can also set $AMC_AUTH_PASSWORD env variable
57 | #password = "admin"
58 |
59 | [TLS]
60 |
61 | # name of cert files to add to the pool for TLS connections
62 | # All entries should be a string
63 | server_cert_pool = [
64 | "/home/zohar/go/src/github.com/aerospike-community/amc/cert.pem",
65 | ]
66 |
67 | [tls.client_certs]
68 |
69 | # [tls.client_certs.a]
70 | # cert_file="/Users/khosrow/as_certs/ca/subject/ClusterName-a-Chainless/cert.pem"
71 | # key_file="/Users/khosrow/as_certs/ca/subject/ClusterName-a-Chainless/key.pem"
72 |
73 | # [tls.client_certs.b]
74 | # cert_file="/Users/khosrow/as_certs/ca/subject/ClusterName-a-Chainless/cluster_chainless_chain.pem"
75 | # key_file="/Users/khosrow/as_certs/ca/subject/ClusterName-a-Chainless/key.pem"
76 |
--------------------------------------------------------------------------------
/common/parser.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "strconv"
7 | "strings"
8 | )
9 |
10 | // InfoParser struct
11 | type InfoParser struct {
12 | *bufio.Reader
13 | }
14 |
15 | // NewInfoParser - new info parser
16 | func NewInfoParser(s string) *InfoParser {
17 | return &InfoParser{bufio.NewReader(strings.NewReader(s))}
18 | }
19 |
20 | // Expect expect a value, assert if not expected value
21 | func (ip *InfoParser) Expect(s string) error {
22 | bytes := make([]byte, len(s))
23 | v, err := ip.Read(bytes)
24 | if err != nil {
25 | return err
26 | }
27 | if string(bytes) != s {
28 | return fmt.Errorf("InfoParser: Wrong value. Expected %s, found %d", s, v)
29 | }
30 | return nil
31 | }
32 |
33 | // ReadUntil - read until delimiter
34 | func (ip *InfoParser) ReadUntil(delim byte) (string, error) {
35 | v, err := ip.ReadBytes(delim)
36 |
37 | switch len(v) {
38 | case 0:
39 | return string(v), err
40 | case 1:
41 | if v[0] == delim {
42 | return "", err
43 | }
44 | return string(v), err
45 | }
46 | return string(v[:len(v)-1]), err
47 | }
48 |
49 | // ReadFloat - read float
50 | func (ip *InfoParser) ReadFloat(delim byte) (float64, error) {
51 | s, err := ip.ReadUntil(delim)
52 | if err != nil {
53 | return 0, err
54 | }
55 |
56 | return strconv.ParseFloat(s, 64)
57 | }
58 |
59 | // func (ip *InfoParser) ReadTime(delim byte) (time.Time, error) {
60 | // s, err := ip.ReadUntil(delim)
61 | // if err != nil {
62 | // return time.Time{}, err
63 | // }
64 |
65 | // return time.Parse("2013-02-03 12:13:11-GMT", s)
66 | // }
67 |
--------------------------------------------------------------------------------
/common/remote_job.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "io/ioutil"
7 | "net"
8 | "os"
9 | "strings"
10 |
11 | "golang.org/x/crypto/ssh"
12 | "golang.org/x/crypto/ssh/agent"
13 | )
14 |
15 | // SSHCommand struct
16 | type SSHCommand struct {
17 | Path string
18 | Env []string
19 | Stdin io.Reader
20 | Stdout io.Writer
21 | Stderr io.Writer
22 | }
23 |
24 | // SSHClient struct
25 | type SSHClient struct {
26 | Config *ssh.ClientConfig
27 | Host string
28 | Port int
29 | }
30 |
31 | // RunCommand - run ssh command
32 | func (client *SSHClient) RunCommand(cmd *SSHCommand) error {
33 | var (
34 | session *ssh.Session
35 | err error
36 | )
37 |
38 | if session, err = client.newSession(); err != nil {
39 | return err
40 | }
41 |
42 | defer session.Close()
43 |
44 | if err = client.prepareCommand(session, cmd); err != nil {
45 | session.Close()
46 | return err
47 | }
48 |
49 | err = session.Run(cmd.Path)
50 | return err
51 | }
52 |
53 | // Session - return new ssh session
54 | func (client *SSHClient) Session(cmd *SSHCommand) (*ssh.Session, error) {
55 | return client.newSession()
56 | }
57 |
58 | // prepareCommand - prepare the command
59 | func (client *SSHClient) prepareCommand(session *ssh.Session, cmd *SSHCommand) error {
60 | for _, env := range cmd.Env {
61 | variable := strings.Split(env, "=")
62 | if len(variable) != 2 {
63 | continue
64 | }
65 |
66 | if err := session.Setenv(variable[0], variable[1]); err != nil {
67 | return err
68 | }
69 | }
70 |
71 | if cmd.Stdin != nil {
72 | stdin, err := session.StdinPipe()
73 | if err != nil {
74 | return fmt.Errorf("Unable to setup stdin for session: %v", err)
75 | }
76 | go io.Copy(stdin, cmd.Stdin)
77 | }
78 |
79 | if cmd.Stdout != nil {
80 | stdout, err := session.StdoutPipe()
81 | if err != nil {
82 | return fmt.Errorf("Unable to setup stdout for session: %v", err)
83 | }
84 | go io.Copy(cmd.Stdout, stdout)
85 | }
86 |
87 | if cmd.Stderr != nil {
88 | stderr, err := session.StderrPipe()
89 | if err != nil {
90 | return fmt.Errorf("Unable to setup stderr for session: %v", err)
91 | }
92 | go io.Copy(cmd.Stderr, stderr)
93 | }
94 |
95 | return nil
96 | }
97 |
98 | func (client *SSHClient) newSession() (*ssh.Session, error) {
99 | connection, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", client.Host, client.Port), client.Config)
100 | if err != nil {
101 | return nil, fmt.Errorf("Failed to dial: %s", err)
102 | }
103 |
104 | session, err := connection.NewSession()
105 | if err != nil {
106 | return nil, fmt.Errorf("Failed to create session: %s", err)
107 | }
108 |
109 | // modes := ssh.TerminalModes{
110 | // // ssh.ECHO: 0, // disable echoing
111 | // ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
112 | // ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
113 | // }
114 |
115 | if err := session.RequestPty("xterm", 80, 40, nil); err != nil {
116 | session.Close()
117 | return nil, fmt.Errorf("request for pseudo terminal failed: %s", err)
118 | }
119 |
120 | return session, nil
121 | }
122 |
123 | // PublicKeyFile - return Public Key
124 | func PublicKeyFile(file string) ssh.AuthMethod {
125 | buffer, err := ioutil.ReadFile(file)
126 | if err != nil {
127 | return nil
128 | }
129 |
130 | key, err := ssh.ParsePrivateKey(buffer)
131 | if err != nil {
132 | return nil
133 | }
134 | return ssh.PublicKeys(key)
135 | }
136 |
137 | // SSHAgent - get agent
138 | func SSHAgent() ssh.AuthMethod {
139 | if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
140 | return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers)
141 | }
142 | return nil
143 | }
144 |
145 | // func main() {
146 | // // ssh.Password("your_password")
147 | // sshConfig := &ssh.ClientConfig{
148 | // User: "jsmith",
149 | // Auth: []ssh.AuthMethod{
150 | // SSHAgent(),
151 | // },
152 | // }
153 |
154 | // client := &SSHClient{
155 | // Config: sshConfig,
156 | // Host: "example.com",
157 | // Port: 22,
158 | // }
159 |
160 | // cmd := &SSHCommand{
161 | // Path: "ls -l $LC_DIR",
162 | // Env: []string{"LC_DIR=/"},
163 | // Stdin: os.Stdin,
164 | // Stdout: os.Stdout,
165 | // Stderr: os.Stderr,
166 | // }
167 |
168 | // fmt.Printf("Running command: %s\n", cmd.Path)
169 | // if err := client.RunCommand(cmd); err != nil {
170 | // fmt.Fprintf(os.Stderr, "command run error: %s\n", err)
171 | // os.Exit(1)
172 | // }
173 | // }
174 |
--------------------------------------------------------------------------------
/common/set.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | // StrUniq is checking for uniqe strings
4 | func StrUniq(l []string) []string {
5 | if len(l) == 0 {
6 | return nil
7 | }
8 |
9 | set := map[string]struct{}{}
10 | for i := range l {
11 | set[l[i]] = struct{}{}
12 | }
13 |
14 | result := make([]string, 0, len(set))
15 | for k := range set {
16 | result = append(result, k)
17 | }
18 |
19 | return result
20 | }
21 |
--------------------------------------------------------------------------------
/common/sync_value.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import "sync"
4 |
5 | // SyncValue struct
6 | type SyncValue struct {
7 | value interface{}
8 | mutex sync.RWMutex
9 | }
10 |
11 | // NewSyncValue - new sync value
12 | func NewSyncValue(val interface{}) SyncValue {
13 | return SyncValue{
14 | value: val,
15 | }
16 | }
17 |
18 | // Get - get sync value
19 | func (sv *SyncValue) Get() interface{} {
20 | sv.mutex.RLock()
21 | v := sv.value
22 | sv.mutex.RUnlock()
23 | return v
24 | }
25 |
26 | // Set - set sync value
27 | func (sv *SyncValue) Set(val interface{}) {
28 | sv.mutex.Lock()
29 | sv.value = val
30 | sv.mutex.Unlock()
31 | }
32 |
--------------------------------------------------------------------------------
/common/types.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "database/sql/driver"
5 | "time"
6 | )
7 |
8 | // JSONRawString - Value should be a string
9 | type JSONRawString string
10 |
11 | // MarshalJSON returns *m as the JSON encoding of m.
12 | func (m *JSONRawString) MarshalJSON() ([]byte, error) {
13 | return []byte(*m), nil
14 | }
15 |
16 | // IndexType - Value should be a string
17 | type IndexType string
18 |
19 | var indexType = struct {
20 | STRING IndexType
21 | NUMERIC IndexType
22 | }{"string", "numeric"}
23 |
24 | // NullTime to store time and nullibility
25 | type NullTime struct {
26 | time time.Time
27 | valid bool // Valid is true if Time is not NULL
28 | }
29 |
30 | // Set - sets the time
31 | func (nt *NullTime) Set(t time.Time) {
32 | nt.time = t
33 | nt.valid = true
34 | }
35 |
36 | // Valid - check if Time is not NULL
37 | func (nt *NullTime) Valid() bool {
38 | return nt.valid
39 | }
40 |
41 | // Scan implements the Scanner interface.
42 | func (nt *NullTime) Scan(value interface{}) error {
43 | nt.time, nt.valid = value.(time.Time)
44 | return nil
45 | }
46 |
47 | // Value implements the driver Valuer interface.
48 | func (nt NullTime) Value() (driver.Value, error) {
49 | if !nt.valid {
50 | return nil, nil
51 | }
52 | return nt.time, nil
53 | }
54 |
--------------------------------------------------------------------------------
/common/utils.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "database/sql"
5 | "errors"
6 | "fmt"
7 | "math"
8 | "sort"
9 | "strconv"
10 | "strings"
11 | "time"
12 | )
13 |
14 | // SplitHostPort - convert aerospike host string to basic parts
15 | func SplitHostPort(addr string) (host string, port int, err error) {
16 | addr = strings.Trim(addr, "\t\n\r ")
17 | if len(addr) == 0 {
18 | return "", 0, errors.New("Invalid address: " + addr)
19 | }
20 |
21 | index := strings.LastIndex(addr, ":")
22 | if index < 0 || len(addr) < index {
23 | return addr, 0, errors.New("Invalid address: " + addr)
24 | }
25 |
26 | portStr := addr[index+1:]
27 | if len(portStr) > 0 {
28 | var err error
29 | port, err = strconv.Atoi(portStr)
30 | if err != nil {
31 | return addr, 0, err
32 | }
33 | }
34 | return addr[:index], port, nil
35 | }
36 |
37 | // Round - convert float to rounded int
38 | func Round(val float64, roundOn float64, places int) (newVal float64) {
39 | var round float64
40 | pow := math.Pow(10, float64(places))
41 | digit := pow * val
42 | _, div := math.Modf(digit)
43 | if div >= roundOn {
44 | round = math.Ceil(digit)
45 | } else {
46 | round = math.Floor(digit)
47 | }
48 | newVal = round / pow
49 | return
50 | }
51 |
52 | // DeleteEmpty - remove empty item from slice
53 | func DeleteEmpty(s []string) []string {
54 | var r []string
55 | for _, str := range s {
56 | if strings.Trim(str, " ") != "" {
57 | r = append(r, str)
58 | }
59 | }
60 | return r
61 | }
62 |
63 | // StrDiff - compare slices into added and remove slices
64 | func StrDiff(o, n []string) (added, removed []string) {
65 | for _, sn := range n {
66 | exists := false
67 | for _, so := range o {
68 | if sn == so {
69 | exists = true
70 | break
71 | }
72 | }
73 | if !exists {
74 | added = append(added, sn)
75 | }
76 | }
77 |
78 | for _, so := range o {
79 | exists := false
80 | for _, sn := range n {
81 | if sn == so {
82 | exists = true
83 | break
84 | }
85 | }
86 | if !exists {
87 | removed = append(removed, so)
88 | }
89 | }
90 |
91 | return added, removed
92 | }
93 |
94 | // Comma - convert integer into comma string
95 | func Comma(v int64, sep string) string {
96 | sign := ""
97 |
98 | // minin64 can't be negated to a usable value, so it has to be special cased.
99 | if v == math.MinInt64 {
100 | return "-9,223,372,036,854,775,808"
101 | }
102 |
103 | if v < 0 {
104 | sign = "-"
105 | v = 0 - v
106 | }
107 |
108 | parts := []string{"", "", "", "", "", "", ""}
109 | j := len(parts) - 1
110 |
111 | for v > 999 {
112 | parts[j] = strconv.FormatInt(v%1000, 10)
113 | switch len(parts[j]) {
114 | case 2:
115 | parts[j] = "0" + parts[j]
116 | case 1:
117 | parts[j] = "00" + parts[j]
118 | }
119 | v = v / 1000
120 | j--
121 | }
122 | parts[j] = strconv.Itoa(int(v))
123 | return sign + strings.Join(parts[j:], sep)
124 | }
125 |
126 | // SortStrings - sort slice (?)
127 | func SortStrings(s []string) []string {
128 | sort.Strings(s)
129 | return s
130 | }
131 |
132 | // ToNullString - convert string into sql.NullString
133 | func ToNullString(s string) sql.NullString {
134 | return sql.NullString{String: s, Valid: s != ""}
135 | }
136 |
137 | // MaxInt64 - Max function for Int64
138 | func MaxInt64(a, b int64) int64 {
139 | if a > b {
140 | return a
141 | }
142 | return b
143 | }
144 |
145 | // ParseTimeStrict parses a formatted string and returns the time value it
146 | // represents. The output is identical to time.Parse except it returns an
147 | // error for strings that don't format to the input value.
148 | //
149 | // An example where the output differs from time.Parse would be:
150 | // parseTimeStrict("1/2/06", "11/31/15")
151 | // - time.Parse returns "2015-12-01 00:00:00 +0000 UTC"
152 | // - parseTimeStrict returns an error
153 | func ParseTimeStrict(layout, value string) (time.Time, error) {
154 | t, err := time.Parse(layout, value)
155 | if err != nil {
156 | return t, fmt.Errorf("invalid date time: %q. Must follow the pattern %s", value, layout)
157 | }
158 | if t.Format(layout) != value {
159 | return t, fmt.Errorf("invalid date time: %q. Must follow the pattern %s", value, layout)
160 | }
161 | return t, nil
162 | }
163 |
--------------------------------------------------------------------------------
/controllers/common.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "github.com/aerospike-community/amc/models"
5 | )
6 |
7 | //----------
8 | // Handlers
9 | //----------
10 |
11 | // NodeResult strunct
12 | type NodeResult struct {
13 | Node *models.Node
14 | Name string
15 | Status string
16 | Err error
17 | UnsetParams []string
18 | }
19 |
20 | func errorMap(err string) map[string]interface{} {
21 | return map[string]interface{}{
22 | "status": "failure",
23 | "error": err,
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/controllers/main_enterprise.go:
--------------------------------------------------------------------------------
1 | // build enterprise
2 |
3 | package controllers
4 |
5 | import "github.com/labstack/echo/v4"
6 |
7 | func registerEnterprise(e *echo.Echo) {
8 | e.GET("/aerospike/service/clusters/:clusterUUID/get-current-user", sessionValidator(getClusterCurrentUser))
9 | e.GET("/aerospike/service/clusters/:clusterUUID/get_user_roles", sessionValidator(getClusterUserRoles))
10 |
11 | e.POST("/aerospike/service/clusters/:clusterUUID/initiate_backup", sessionValidator(postInitiateBackup))
12 | e.GET("/aerospike/service/clusters/:clusterUUID/get_backup_progress", sessionValidator(getBackupProgress))
13 | e.GET("/aerospike/service/clusters/:clusterUUID/get_successful_backups", sessionValidator(getSuccessfulBackups))
14 | e.POST("/aerospike/service/clusters/:clusterUUID/get_available_backups", sessionValidator(getAvailableBackups))
15 |
16 | e.POST("/aerospike/service/clusters/:clusterUUID/initiate_restore", sessionValidator(postInitiateRestore))
17 | e.GET("/aerospike/service/clusters/:clusterUUID/get_restore_progress", sessionValidator(getRestoreProgress))
18 |
19 | e.GET("/alert-emails", sessionValidator(getAlertEmails))
20 | e.POST("/alert-emails", sessionValidator(postAlertEmails))
21 | e.POST("/delete-alert-emails", sessionValidator(deleteAlertEmails))
22 |
23 | e.GET("/aerospike/get_multicluster_view/:port", getMultiClusterView)
24 |
25 | e.POST("/aerospike/service/clusters/:clusterUUID/fire_cmd", sessionValidator(postClusterFireCmd))
26 | e.GET("/aerospike/service/clusters/:clusterUUID/get_all_users", sessionValidator(getClusterAllUsers))
27 | e.GET("/aerospike/service/clusters/:clusterUUID/get_all_roles", sessionValidator(getClusterAllRoles))
28 | e.POST("/aerospike/service/clusters/:clusterUUID/add_user", sessionValidator(postClusterAddUser))
29 | e.POST("/aerospike/service/clusters/:clusterUUID/user/:user/remove", sessionValidator(postClusterDropUser))
30 | e.POST("/aerospike/service/clusters/:clusterUUID/user/:user/update", sessionValidator(postClusterUpdateUser))
31 | e.POST("/aerospike/service/clusters/:clusterUUID/roles/:role/add_role", sessionValidator(postClusterAddRole))
32 | e.POST("/aerospike/service/clusters/:clusterUUID/roles/:role/update", sessionValidator(postClusterUpdateRole))
33 | e.POST("/aerospike/service/clusters/:clusterUUID/roles/:role/drop_role", sessionValidator(postClusterDropRole))
34 |
35 | e.GET("/aerospike/service/clusters/:clusterUUID/latency/:nodes", sessionValidator(getNodeLatency))
36 | e.GET("/aerospike/service/clusters/:clusterUUID/latency_history/:nodes", sessionValidator(getNodeLatencyHistory))
37 | e.GET("/aerospike/service/clusters/:clusterUUID/nodes/:nodes/latency_history", sessionValidator(getNodesLatencyHistory))
38 | e.POST("/aerospike/service/clusters/:clusterUUID/change_password", sessionValidator(postClusterChangePassword))
39 | e.GET("/aerospike/service/clusters/:clusterUUID/alerts", sessionValidator(getClusterAlerts))
40 | e.POST("/aerospike/service/clusters/:clusterUUID/nodes/:node/switch_xdr_off", sessionValidator(postSwitchXDROff))
41 | e.POST("/aerospike/service/clusters/:clusterUUID/nodes/:node/switch_xdr_on", sessionValidator(postSwitchXDROn))
42 | e.GET("/aerospike/service/clusters/:clusterUUID/xdr/:xdrPort/nodes/:nodes", sessionValidator(getClusterXdrNodes))
43 | e.GET("/aerospike/service/clusters/:clusterUUID/xdr/:xdrPort/nodes/:nodes/allconfig", sessionValidator(getClusterXdrNodesAllConfig))
44 | e.POST("/aerospike/service/clusters/:clusterUUID/xdr/:xdrPort/nodes/:nodes/setconfig", sessionValidator(setClusterXdrNodesConfig))
45 | }
46 |
47 | func init() {
48 | registerEnterpriseAPI = registerEnterprise
49 | }
50 |
--------------------------------------------------------------------------------
/controllers/middleware/sessions/cookie.go:
--------------------------------------------------------------------------------
1 | package sessions
2 |
3 | import "github.com/gorilla/sessions"
4 |
5 | // CookieStore used for storing session cookies
6 | type CookieStore interface {
7 | Store
8 | }
9 |
10 | // NewCookieStore used for cookieStore
11 | // Keys are defined in pairs to allow key rotation, but the common case is to set a single
12 | // authentication key and optionally an encryption key.
13 | //
14 | // The first key in a pair is used for authentication and the second for encryption. The
15 | // encryption key can be set to nil or omitted in the last pair, but the authentication key
16 | // is required in all pairs.
17 | //
18 | // It is recommended to use an authentication key with 32 or 64 bytes. The encryption key,
19 | // if set, must be either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256 modes.
20 | func NewCookieStore(keyPairs ...[]byte) CookieStore {
21 | return &cookieStore{sessions.NewCookieStore(keyPairs...)}
22 | }
23 |
24 | type cookieStore struct {
25 | *sessions.CookieStore
26 | }
27 |
28 | func (c *cookieStore) Options(options Options) {
29 | c.CookieStore.Options = &sessions.Options{
30 | Path: options.Path,
31 | Domain: options.Domain,
32 | MaxAge: options.MaxAge,
33 | Secure: options.Secure,
34 | HttpOnly: options.HttpOnly,
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/controllers/session.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "errors"
5 | "net/http"
6 |
7 | "github.com/labstack/echo/v4"
8 | uuid "github.com/satori/go.uuid"
9 | log "github.com/sirupsen/logrus"
10 |
11 | "github.com/aerospike-community/amc/common"
12 | "github.com/aerospike-community/amc/controllers/middleware/sessions"
13 | )
14 |
15 | func sessionValidator(f func(c echo.Context) error) func(c echo.Context) error {
16 | return func(c echo.Context) error {
17 | sid, err := sessionID(c)
18 | if err != nil || !_observer.SessionExists(sid) {
19 | invalidateSession(c)
20 | return c.JSON(http.StatusUnauthorized, errorMap("invalid session : None"))
21 | }
22 |
23 | return f(c)
24 | }
25 | }
26 |
27 | func sessionID(c echo.Context) (string, error) {
28 | session := sessions.Default(c)
29 | id := session.Get("id")
30 |
31 | if id == nil || id.(string) == "" {
32 | return "", errors.New("Invalid session")
33 | }
34 |
35 | return id.(string), nil
36 | }
37 |
38 | func manageSession(c echo.Context) string {
39 | id, err := sessionID(c)
40 | if err != nil || id == "" {
41 | return setSession(c)
42 | }
43 |
44 | if !_observer.SessionExists(id) {
45 | return setSession(c)
46 | }
47 |
48 | return id
49 | }
50 |
51 | func invalidateSession(c echo.Context) {
52 | session := sessions.Default(c)
53 | session.Clear()
54 | if err := session.Save(); err != nil {
55 | log.Error(err)
56 | }
57 | }
58 |
59 | func setSession(c echo.Context) string {
60 | sid := "00000000-0000-0000-0000-000000000000"
61 | // commonity version is single-session
62 | if common.AMCIsEnterprise() {
63 | sid = uuid.NewV4().String()
64 | }
65 |
66 | session := sessions.Default(c)
67 | session.Options(
68 | sessions.Options{
69 | Path: "/",
70 | // Domain: options.Domain,
71 | // MaxAge: 30 * 60,
72 | Secure: false,
73 | HttpOnly: true,
74 | })
75 | session.Clear()
76 | session.Set("id", sid)
77 | if err := session.Save(); err != nil {
78 | log.Error(err)
79 | }
80 |
81 | return sid
82 | }
83 |
--------------------------------------------------------------------------------
/deployment/common/amc.conf:
--------------------------------------------------------------------------------
1 | CONF files are platform dependant; please edit all of them
--------------------------------------------------------------------------------
/deployment/common/amc.deb:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # amc Manage the amc app server
4 | #
5 | # chkconfig: 2345 95 01
6 | # description: amc is Aerospike Cloud's Application Server
7 | # processname: amc
8 | # config: /etc/amc.conf
9 | # pidfile: /var/run/amc.pid
10 |
11 | ### BEGIN INIT INFO
12 | # Provides: amc
13 | # Required-Start: $local_fs $network
14 | # Required-Stop:
15 | # Should-Start:
16 | # Should-Stop:
17 | # Default-Start: 2 3 4 5
18 | # Default-Stop: 0 1 6
19 | # Short-Description: Manage the amc app server
20 | # Description: amc is the Aerospike Cloud Application Server
21 | ### END INIT INFO
22 |
23 | # source function library
24 | #. /etc/init.d/functions
25 | . /lib/lsb/init-functions
26 |
27 | #set -x
28 |
29 | PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/opt/amc
30 |
31 | prog="amc"
32 | user="root"
33 | exec="/opt/amc/$prog"
34 | pidfile="/var/run/$prog.pid"
35 | logfile="/var/log/$prog.log"
36 | conffile="/etc/amc/amc.conf"
37 | confdir="/etc/amc"
38 |
39 | # pull in sysconfig settings
40 | [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
41 |
42 | export GOMAXPROCS=${GOMAXPROCS:-2}
43 |
44 | start() {
45 | [ -x $exec ] || exit 5
46 |
47 | # [ -f $conffile ] || exit 6
48 | # [ -d $confdir ] || exit 6
49 |
50 | umask 077
51 | touch $pidfile
52 | umask 022
53 | touch $logfile
54 | chown $user:$user $logfile $pidfile
55 |
56 | echo -n $"Starting $prog: "
57 |
58 | ## holy shell shenanigans, batman!
59 | ## daemon can't be backgrounded. we need the pid of the spawned process,
60 | ## which is actually done via runuser thanks to --user. you can't do "cmd
61 | ## &; action" but you can do "{cmd &}; action".
62 | ##start-stop-daemon --start –-background –-quiet –-pidfile $pidfile -c $user –-exec $exec —- -config-file=$conffile -config-dir=$confdir >> $logfile
63 | start-stop-daemon --start --pidfile $pidfile -c $user --exec $exec --background -C -m -- -config-file=$conffile -config-dir=$confdir >> $logfile 2>/dev/null
64 |
65 | RETVAL=$?
66 | echo $RETVAL
67 |
68 | return $RETVAL
69 | }
70 |
71 | stop() {
72 | echo -n $"Shutting down $prog: "
73 | ## graceful shutdown with SIGINT
74 | start-stop-daemon --stop --pidfile $pidfile
75 | RETVAL=$?
76 | echo $RETVAL
77 | return $RETVAL
78 | }
79 |
80 | status() {
81 | echo -n $"Status of $prog: "
82 | start-stop-daemon --status --pidfile $pidfile
83 | RETVAL=$?
84 | echo $RETVAL
85 | return $RETVAL
86 | }
87 |
88 | restart() {
89 | stop
90 | start
91 | }
92 |
93 | case "$1" in
94 | start)
95 | $1
96 | ;;
97 | stop)
98 | $1
99 | ;;
100 | restart)
101 | $1
102 | ;;
103 | status)
104 | $1
105 | ;;
106 | *)
107 | echo $"Usage: $0 {start|stop|status|restart}"
108 | exit 2
109 | esac
110 |
111 | exit $?
112 |
--------------------------------------------------------------------------------
/deployment/common/amc.docker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PROJECT="/opt/amc"
4 | PIDFILE="/tmp/amc.pid"
5 | CONFIG="/etc/amc/amc.conf"
6 |
7 | CMD="${PROJECT}/amc -config-file=${CONFIG}"
8 |
9 | # Fill out conffile with above values
10 | if [ -f /etc/amc/amc.template.conf ]; then
11 | envsubst < /etc/amc/amc.template.conf > ${CONFIG}
12 | fi
13 |
14 | check_amc_status(){
15 | status=1
16 | if [ -z "`ps aux | grep /opt/amc/amc | grep -v grep`" ]; then
17 | status=0
18 | fi
19 | echo $status
20 | }
21 |
22 | start_amc(){
23 | status=$(check_amc_status)
24 | if [ $status -eq 0 ] ; then
25 | rm -f $PIDFILE
26 | fi
27 | exec ${CMD}
28 | }
29 |
30 | if [ "$1" = "amc" ]; then
31 | start_amc
32 | else
33 | # the command isn't amc so run the command the user specified
34 | exec "$@"
35 | fi
36 |
--------------------------------------------------------------------------------
/deployment/common/amc.other.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | SIGNAL=${1:-status}
4 |
5 | PROJECT="/opt/amc"
6 | PIDFILE="/tmp/amc.pid"
7 | CONFIG="/etc/amc/amc.conf"
8 |
9 | CMD="${PROJECT}/amc -daemon -config-file=${CONFIG}"
10 | port="8081"
11 | check_amc_status(){
12 | status=1
13 | if [ -z "`ps aux | grep /opt/amc/amc | grep -v grep`" ]; then
14 | status=0
15 | fi
16 | echo $status
17 | }
18 |
19 | start_amc(){
20 | status=$(check_amc_status)
21 | if [ $status -eq 0 ] ; then
22 | rm -f $PIDFILE
23 | ${CMD}
24 | fi
25 | }
26 |
27 | stop_amc(){
28 | status=$(check_amc_status)
29 | if [ $status -ne 0 ] ; then
30 | ${CMD} -signal stop
31 | fi
32 | }
33 |
34 | case "$SIGNAL" in
35 | start)
36 | start_amc
37 | ;;
38 | stop)
39 | stop_amc
40 | ;;
41 | status)
42 | status=$(check_amc_status)
43 | if [ $status -eq 0 ] ; then
44 | echo "stopped"
45 | else
46 | echo "running"
47 | fi
48 | ;;
49 | *)
50 | echo "Unrecognized signal"
51 | exit 1
52 | ;;
53 | esac
54 |
--------------------------------------------------------------------------------
/deployment/common/amc.rpm:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # amc Aerospike's Management Console
4 | #
5 | # chkconfig: 2345 95 01
6 | # description: AMC is Aerospike's Management Console
7 | # processname: amc
8 | # config: /etc/amc.conf
9 | # pidfile: /var/run/amc.pid
10 |
11 | ### BEGIN INIT INFO
12 | # Provides: amc
13 | # Required-Start: $local_fs $network
14 | # Required-Stop:
15 | # Should-Start:
16 | # Should-Stop:
17 | # Default-Start: 2 3 4 5
18 | # Default-Stop: 0 1 6
19 | # Short-Description: Aerospike's Management Console
20 | # Description: AMC is Aerospike's Management Console
21 | ### END INIT INFO
22 |
23 | # source function library
24 | . /etc/rc.d/init.d/functions
25 |
26 | PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/opt/amc
27 |
28 | prog="amc"
29 | user="root"
30 | exec="/opt/amc/$prog"
31 | pidfile="/var/run/$prog.pid"
32 | lockfile="/var/lock/subsys/$prog"
33 | logfile="/var/log/$prog.log"
34 | conffile="/etc/amc/amc.conf"
35 | confdir="/etc/amc"
36 |
37 | # pull in sysconfig settings
38 | [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
39 |
40 | export GOMAXPROCS=${GOMAXPROCS:-2}
41 |
42 | start() {
43 | [ -x $exec ] || exit 5
44 |
45 | # [ -f $conffile ] || exit 6
46 | # [ -d $confdir ] || exit 6
47 |
48 | umask 077
49 |
50 | touch $logfile $pidfile
51 | chown $user:$user $logfile $pidfile
52 |
53 | echo -n $"Starting $prog: "
54 |
55 | ## holy shell shenanigans, batman!
56 | ## daemon can't be backgrounded. we need the pid of the spawned process,
57 | ## which is actually done via runuser thanks to --user. you can't do "cmd
58 | ## &; action" but you can do "{cmd &}; action".
59 | daemon \
60 | --pidfile=$pidfile \
61 | --user=$user \
62 | " { $exec -config-file=$conffile -config-dir=$confdir &>> $logfile & } ; echo \$! >| $pidfile "
63 |
64 | RETVAL=$?
65 | echo
66 |
67 | [ $RETVAL -eq 0 ] && touch $lockfile
68 |
69 | return $RETVAL
70 | }
71 |
72 | stop() {
73 | echo -n $"Shutting down $prog: "
74 | ## graceful shutdown with SIGINT
75 | killproc -p $pidfile -b $exec -INT
76 | RETVAL=$?
77 | echo
78 | [ $RETVAL -eq 0 ] && rm -f $lockfile
79 | return $RETVAL
80 | }
81 |
82 | restart() {
83 | stop
84 | start
85 | }
86 |
87 | reload() {
88 | echo -n $"Reloading $prog: "
89 | killproc -p $pidfile -b $exec -HUP
90 | echo
91 | }
92 |
93 | force_reload() {
94 | restart
95 | }
96 |
97 | rh_status() {
98 | status -p "$pidfile" -l $prog $exec
99 | }
100 |
101 | rh_status_q() {
102 | rh_status >/dev/null 2>&1
103 | }
104 |
105 | case "$1" in
106 | start)
107 | rh_status_q && exit 0
108 | $1
109 | ;;
110 | stop)
111 | rh_status_q || exit 0
112 | $1
113 | ;;
114 | restart)
115 | $1
116 | ;;
117 | reload)
118 | rh_status_q || exit 7
119 | $1
120 | ;;
121 | force-reload)
122 | force_reload
123 | ;;
124 | status)
125 | rh_status
126 | ;;
127 | condrestart|try-restart)
128 | rh_status_q || exit 0
129 | restart
130 | ;;
131 | *)
132 | echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
133 | exit 2
134 | esac
135 |
136 | exit $?
137 |
--------------------------------------------------------------------------------
/deployment/common/amc.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Aerospike Management Console
3 | After=syslog.target network.target local-fs.target nss-lookup.target
4 |
5 | [Service]
6 | Type=simple
7 | WorkingDirectory=/opt/amc
8 | ExecStart=/opt/amc/amc
9 | Restart=on-failure
10 | LimitNOFILE=10000
11 |
12 | [Install]
13 | WantedBy=multi-user.target
14 |
--------------------------------------------------------------------------------
/deployment/common/systemd_after_install.sh:
--------------------------------------------------------------------------------
1 | # move systemd startup
2 | cp /opt/amc/amc.service /etc/systemd/system/
3 | systemctl enable amc.service
4 |
--------------------------------------------------------------------------------
/deployment/release/darwin/LaunchAgents/com.aerospike.amc.plist:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Label
7 | com.aerospike.amc
8 | ProgramArguments
9 |
10 | /Library/amc/amc
11 | -config-file=/Library/amc/amc.conf
12 |
13 | Sockets
14 |
15 | Listeners
16 |
17 | SockServiceName
18 | 6060
19 |
20 |
21 | KeepAlive
22 |
23 | StandardOutPath
24 | /Library/amc/amc.txt
25 | StandardErrorPath
26 | /Library/amc/amc.txt
27 |
28 |
--------------------------------------------------------------------------------
/deployment/release/darwin/Logs/amc/.placeholder:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/deployment/release/darwin/Logs/amc/.placeholder
--------------------------------------------------------------------------------
/deployment/release/darwin/amc/amc.conf:
--------------------------------------------------------------------------------
1 | [AMC]
2 | update_interval = 5
3 | #certfile = ""
4 | #keyfile = ""
5 | #Example : File paths should be double quoted.
6 | #certfile = "/home/amc/self-ssl.crt"
7 | #keyfile = "/home/amc/self-ssl.key"
8 | # The following option forces the the server to only use TLS v1.2 as the minimum TLS version.
9 | #force_tls12=true
10 | # The following option forces the server to use TLS v1.2 with the following options, resulting in higher level of security:
11 | ## CurvePreferences will be {CurveP521, CurveP384, CurveP256}
12 | ## Client will prefer the server cipher suites
13 | ## CipherSuites will be { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA }
14 | #max_tls_security=true
15 |
16 | # Backup will be done on the following machine. If a key is set, that will be used
17 | # If no key or password is set, SSH Agent will be tried
18 | # You must put all the string inside double-quotes.
19 | # Comment out the methods you don't need
20 | #backup_host_public_key_file =
21 |
22 | bind = "0.0.0.0:8081"
23 | pidfile = "/tmp/amc.pid"
24 | loglevel = "info"
25 | errorlog = "/Library/Logs/amc/amc.log"
26 | #proc_name = "amc"
27 | chdir = "/Library/amc/"
28 | static_dir = "/Library/amc/static"
29 | timeout = 10
30 |
31 | # when you start monitoring a cluster, it will be polled activaly in the background.
32 | # this setting determines how long will that clustered be kept after it is not polled anymore.
33 | # This setting will not affect the clusters in the [amc.clusters] section.
34 | # values <= 0 mean never remove.
35 | cluster_inactive_before_removal = 1800
36 |
37 | database = "/Library/amc/amc.db"
38 |
39 | # The following clusters will be automatically monitored on AMC start
40 | #[amc.clusters]
41 | #
42 | # [amc.clusters.db1]
43 | # host = ""
44 | # tls_name =
45 | # port = 3000
46 | # user = ""
47 | # password = ""
48 | # show_in_ui = true
49 |
50 | # [amc.clusters.db2]
51 | # host = ""
52 | # tls_name =
53 | # port = 3000
54 | # user = ""
55 | # password = ""
56 | # show_in_ui = true
57 |
58 | [mailer]
59 | template_path = "/Library/amc/mailer/templates"
60 | #host = "smtp."
61 | #port = 587
62 | #user = ""
63 | #password = ""
64 | #send_to = ["", ""]
65 | #from_address = ""
66 | #accept_invalid_cert = false
67 |
68 | [basic_auth]
69 | # you can also set $AMC_AUTH_USER env variable
70 | #user = ""
71 | # you can also set $AMC_AUTH_PASSWORD env variable
72 | #password = ""
73 |
74 | [TLS]
75 |
76 | # name of cert files to add to the pool for TLS connections
77 | # All entries should be a string
78 | # System certs are automatically added
79 | server_cert_pool = [
80 | # "",
81 | # "",
82 | ]
83 |
84 | [tls.client_certs]
85 |
86 | # [tls.client_certs.a]
87 | # cert_file=""
88 | # key_file=""
89 |
90 | # [tls.client_certs.b]
91 | # cert_file=""
92 | # key_file=""
93 |
--------------------------------------------------------------------------------
/deployment/release/darwin/amc/uninstall.sh:
--------------------------------------------------------------------------------
1 | #/bin/sh
2 |
3 | if [ `id -u` -ne 0 ] ; then
4 | echo "This script should be run as root only"
5 | exit 1
6 | fi
7 |
8 | set +e
9 |
10 | launchctl unload /Library/LaunchAgents/com.aerospike.amc.plist
11 |
12 | rm -rf /Library/amc
13 | rm -rf /Library/Logs/amc
14 | rm -rf /Library/LaunchAgents/com.aerospike.amc.plist
15 |
16 | echo "AMC was uninstalled successfully."
17 |
--------------------------------------------------------------------------------
/deployment/release/linux/etc/amc/amc.conf:
--------------------------------------------------------------------------------
1 | [AMC]
2 | update_interval = 5
3 | #certfile = ""
4 | #keyfile = ""
5 | #Example : File paths should be double quoted.
6 | #certfile = "/home/amc/self-ssl.crt"
7 | #keyfile = "/home/amc/self-ssl.key"
8 | # The following option forces the the server to only use TLS v1.2 as the minimum TLS version.
9 | #force_tls12=true
10 | # The following option forces the server to use TLS v1.2 with the following options, resulting in higher level of security:
11 | ## CurvePreferences will be {CurveP521, CurveP384, CurveP256}
12 | ## Client will prefer the server cipher suites
13 | ## CipherSuites will be { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA }
14 | #max_tls_security=true
15 |
16 | # Backup will be done on the following machine. If a key is set, that will be used
17 | # If no key or password is set, SSH Agent will be tried
18 | # You must put all the string inside double-quotes.
19 | # Comment out the methods you don't need
20 | #backup_host_public_key_file =
21 |
22 | bind = "0.0.0.0:8081"
23 | pidfile = "/var/run/amc.pid"
24 | loglevel = "info"
25 | errorlog = "/var/log/amc/amc.log"
26 | #proc_name = "amc"
27 | chdir = "/opt/amc/"
28 | static_dir = "/opt/amc/static"
29 | timeout = 10
30 |
31 | # when you start monitoring a cluster, it will be polled activaly in the background.
32 | # this setting determines how long will that clustered be kept after it is not polled anymore.
33 | # This setting will not affect the clusters in the [amc.clusters] section.
34 | # values <= 0 mean never remove.
35 | cluster_inactive_before_removal = 1800
36 |
37 | database = "/opt/amc/amc.db"
38 |
39 | # The following clusters will be automatically monitored on AMC start
40 | #[amc.clusters]
41 | #
42 | # [amc.clusters.db1]
43 | # host = ""
44 | # tls_name =
45 | # port = 3000
46 | # user = ""
47 | # password = ""
48 | # show_in_ui = true
49 |
50 | # [amc.clusters.db2]
51 | # host = ""
52 | # tls_name =
53 | # port = 3000
54 | # user = ""
55 | # password = ""
56 | # show_in_ui = true
57 |
58 | [mailer]
59 | template_path = "/opt/amc/mailer/templates"
60 | #host = "smtp."
61 | #port = 587
62 | #user = ""
63 | #password = ""
64 | #send_to = ["", ""]
65 | #from_address = ""
66 | #accept_invalid_cert = false
67 |
68 | [basic_auth]
69 | # you can also set $AMC_AUTH_USER env variable
70 | #user = ""
71 | # you can also set $AMC_AUTH_PASSWORD env variable
72 | #password = ""
73 |
74 | [TLS]
75 |
76 | # name of cert files to add to the pool for TLS connections
77 | # All entries should be a string
78 | # System certs are automatically added
79 | server_cert_pool = [
80 | # "",
81 | # "",
82 | ]
83 |
84 | [tls.client_certs]
85 |
86 | # [tls.client_certs.a]
87 | # cert_file=""
88 | # key_file=""
89 |
90 | # [tls.client_certs.b]
91 | # cert_file=""
92 | # key_file=""
93 |
--------------------------------------------------------------------------------
/deployment/release/linux/var/log/amc/.placeholder:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/deployment/release/linux/var/log/amc/.placeholder
--------------------------------------------------------------------------------
/go-time-series/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Neri Marschik
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/go-time-series/README.md:
--------------------------------------------------------------------------------
1 | # go-time-series
2 |
3 |
4 | [](./LICENSE)
5 | [](https://godoc.org/github.com/codesuki/go-time-series)
6 | [](https://travis-ci.org/codesuki/go-time-series)
7 | [](https://codecov.io/gh/codesuki/go-time-series)
8 |
9 | Time series implementation in Go.
10 |
11 | It is used in [go-trending](https://www.github.com/codesuki/go-trending) as a backend for a trending algorithm.
12 | The time series supports storing counts at different granularities, e.g. seconds, minutes, hours, ....
13 | In case of go-trending the time series is configured to have recent data available at small granularity, i.e. the recent 60 seconds, and historical data available at large granularity, i.e. the last few hours, days of data.
14 |
15 | A redis backend is planned.
16 |
17 | * Simple interface
18 | * Store time series data at different granularities
19 | * Use your own clock implementation, e.g. for testing or similar
20 |
21 | ## Examples
22 |
23 | ### Creating a time series with default settings
24 | The default settings use `time.Now()` as clock and `time.Second * 60`, `time.Minute * 60` and `time.Hour * 24` as granularities.
25 |
26 | ```go
27 | import "github.com/codesuki/go-time-series"
28 |
29 | ...
30 |
31 | ts, err := timeseries.NewTimeSeries()
32 | if err != nil {
33 | // handle error
34 | }
35 | ```
36 |
37 | ### Creating a customized time series
38 | You can specify the clock and/or granularities to use. A clock must implement the `timeseries.Clock` interface.
39 |
40 | ```go
41 | import "github.com/codesuki/go-time-series"
42 |
43 | ...
44 | type clock struct {}
45 | func (c *clock) Now() {
46 | return time.Time{} // always returns the zero time
47 | }
48 | var myClock clock
49 | ...
50 |
51 | ts, err := timeseries.NewTimeSeries(
52 | timeseries.WithGranularities(
53 | []timeseries.Granularity{
54 | {Granularity: time.Second, Count: 60},
55 | {Granularity: time.Minute, Count: 60},
56 | {Granularity: time.Hour, Count: 24},
57 | {Granularity: time.Hour * 24, Count: 7},
58 | }),
59 | timeseries.WithClock(&myClock),
60 | )
61 | if err != nil {
62 | // handle error
63 | }
64 | ```
65 |
66 | ### Filling the time series
67 | To fill the time series with counts, e.g. events, you can use two different functions.
68 |
69 | ```go
70 | import "github.com/codesuki/go-time-series"
71 |
72 | ...
73 |
74 | ts, err := timeseries.NewTimeSeries()
75 | if err != nil {
76 | // handle error
77 | }
78 |
79 | ts.Increase(2) // adds 2 to the counter at the current time
80 | ts.IncreaseAtTime(3, time.Now().Add(-2 * time.Minute)) // adds 3 to the counter 2 minutes ago
81 | ```
82 |
83 | ### Querying the time series
84 | The `Range()` function takes 2 arguments, i.e. the start and end of a time span.
85 | `Recent()` is a small helper function that just uses `clock.Now()` as `end` in `Range`.
86 | Please refer to the [documentation](https://godoc.org/github.com/codesuki/go-time-series) for how `Range()` works exactly. There are some details depending on what range you query and what range is available.
87 |
88 | ```go
89 | import "github.com/codesuki/go-time-series"
90 |
91 | ...
92 |
93 | ts, err := timeseries.NewTimeSeries()
94 | if err != nil {
95 | // handle error
96 | }
97 |
98 | ts.Increase(2) // adds 2 to the counter at the current time
99 | // 1s passes
100 | ts.Increase(3)
101 | // 1s passes
102 |
103 | ts.Recent(5 * time.Second) // returns 5
104 |
105 | ts.Range(time.Now().Add(-5 * time.Second), time.Now()) // returns 5
106 | ```
107 |
108 | ## Documentation
109 | GoDoc is located [here](https://godoc.org/github.com/codesuki/go-time-series)
110 |
111 | ## License
112 | go-time-series is [MIT licensed](./LICENSE).
113 |
--------------------------------------------------------------------------------
/go-time-series/glide.lock:
--------------------------------------------------------------------------------
1 | hash: 80928db660f9141f86dec3e84b2757bb44620f19f055cacb698cba8ccd738218
2 | updated: 2016-10-07T14:25:01.423423679+09:00
3 | imports: []
4 | testImports:
5 | - name: github.com/benbjohnson/clock
6 | version: a620c1cc9866f84a2550ad53f4f353ec030fa26b
7 |
--------------------------------------------------------------------------------
/go-time-series/glide.yaml:
--------------------------------------------------------------------------------
1 | package: github.com/codesuki/go-time-series
2 | homepage: https://github.com/codesuki/go-time-series
3 | license: MIT
4 | import: []
5 | testImport:
6 | - package: github.com/benbjohnson/clock
7 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/aerospike-community/amc
2 |
3 | go 1.16
4 |
5 | require (
6 | github.com/BurntSushi/toml v0.3.1
7 | github.com/aerospike/aerospike-client-go/v5 v5.0.2
8 | github.com/gorilla/context v1.1.1
9 | github.com/gorilla/sessions v1.2.1
10 | github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
11 | github.com/kennygrant/sanitize v1.2.4
12 | github.com/labstack/echo/v4 v4.3.0
13 | github.com/mattn/go-isatty v0.0.13 // indirect
14 | github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2
15 | github.com/onsi/ginkgo v1.16.4
16 | github.com/onsi/gomega v1.13.0
17 | github.com/satori/go.uuid v1.2.0
18 | github.com/sevlyar/go-daemon v0.1.5
19 | github.com/sirupsen/logrus v1.8.1
20 | github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 // indirect
21 | golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
22 | golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
23 | golang.org/x/sys v0.0.0-20210603125802-9665404d3644 // indirect
24 | golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
25 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
26 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
27 | modernc.org/b v1.0.1 // indirect
28 | modernc.org/db v1.0.1 // indirect
29 | modernc.org/file v1.0.2 // indirect
30 | modernc.org/golex v1.0.1 // indirect
31 | modernc.org/lldb v1.0.1 // indirect
32 | modernc.org/mathutil v1.4.0 // indirect
33 | modernc.org/ql v1.3.1
34 | modernc.org/strutil v1.1.1 // indirect
35 | modernc.org/zappy v1.0.3 // indirect
36 | )
37 |
--------------------------------------------------------------------------------
/mailer/mailer.go:
--------------------------------------------------------------------------------
1 | package mailer
2 |
3 | import (
4 | "bytes"
5 | "crypto/tls"
6 | "fmt"
7 | "html/template"
8 |
9 | log "github.com/sirupsen/logrus"
10 | gomail "gopkg.in/gomail.v2"
11 |
12 | "github.com/aerospike-community/amc/common"
13 | )
14 |
15 | func processTemplate(config *common.Config, tplName string, context interface{}) ([]byte, error) {
16 |
17 | defer func() {
18 | if r := recover(); r != nil {
19 | log.Error("Sending email failed with a panic: ", r)
20 | }
21 | }()
22 |
23 | t := template.Must(template.ParseFiles(config.Mailer.TemplatePath+"/"+tplName, config.Mailer.TemplatePath+"/base.html"))
24 |
25 | // Execute the template for each recipient.
26 | data := bytes.Buffer{}
27 | err := t.Execute(&data, context)
28 | if err != nil {
29 | log.Errorf("Error executing template `%s`, err: `%s`.", tplName, err)
30 | return nil, err
31 | }
32 |
33 | return data.Bytes(), nil
34 | }
35 |
36 | // SendMail - send email
37 | func SendMail(config *common.Config, tplName, subject string, context interface{}) error {
38 | body, err := processTemplate(config, tplName, context)
39 | if err != nil {
40 | return err
41 | }
42 |
43 | msg := gomail.NewMessage(gomail.SetEncoding(gomail.Unencoded))
44 | msg.SetHeader("From", fmt.Sprintf("AMC <%s>", config.FromAddress()))
45 | msg.SetHeader("To", config.AlertEmails()...)
46 | msg.SetHeader("Subject", subject)
47 | msg.SetBody("text/html", string(body))
48 |
49 | mailer := gomail.NewDialer(config.Mailer.Host, int(config.Mailer.Port), config.Mailer.User, config.Mailer.Password)
50 | // Allow invalid/self-signed certs if requested by user
51 | if config.Mailer.AcceptInvalidCert {
52 | if mailer.TLSConfig != nil {
53 | mailer.TLSConfig.InsecureSkipVerify = true
54 | } else {
55 | mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
56 | }
57 | }
58 | if err := mailer.DialAndSend(msg); err != nil {
59 | return err
60 | }
61 |
62 | return nil
63 | }
64 |
--------------------------------------------------------------------------------
/mailer/templates/alerts/generic.html:
--------------------------------------------------------------------------------
1 | {{define "content"}}
2 |
3 | {{.Title}}
4 |
5 |
6 |
Cluster: {{.Cluster}}
7 | Node: {{.Node}}
8 | Status: {{.Status}}
9 | Message: {{.Message}}
10 |
11 | {{end}}
12 |
13 | {{template "base" .}}
14 |
--------------------------------------------------------------------------------
/mailer/templates/base.html:
--------------------------------------------------------------------------------
1 | {{define "base"}}
2 |
4 |
5 |
6 |
7 |
8 |
9 | AMC Alert
10 |
26 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
60 |
61 |
62 |
63 | |
64 |
65 |
66 |
67 |
68 |
69 | {{template "content" .}}
70 |
71 |
72 | |
73 |
74 |
75 | |
76 |
77 |
78 |
79 |
80 |
81 | {{end}}
82 |
--------------------------------------------------------------------------------
/main_darwin.go:
--------------------------------------------------------------------------------
1 | // +build darwin
2 |
3 | package main
4 |
5 | import (
6 | "flag"
7 | "net/http"
8 | _ "net/http/pprof"
9 | "runtime"
10 | "runtime/debug"
11 |
12 | log "github.com/sirupsen/logrus"
13 |
14 | "github.com/aerospike-community/amc/common"
15 | "github.com/aerospike-community/amc/controllers"
16 | )
17 |
18 | var (
19 | configFile = flag.String("config-file", "/etc/amc/amc.conf", "Configuration file.")
20 | configDir = flag.String("config-dir", "/etc/amc/", "Configuration dir.")
21 | profileMode = flag.Bool("profile", false, "Run benchmarks with profiler active on port 6060.")
22 | daemonMode = flag.Bool("daemon", false, "Run AMC in daemon mode.")
23 | daemonSignal = flag.String("signal", "", `send signal to the daemon
24 | stop — graceful shutdown.`)
25 | )
26 |
27 | func main() {
28 | defer func() {
29 | if err := recover(); err != nil {
30 | log.Fatal(string(debug.Stack()))
31 | }
32 | }()
33 |
34 | runtime.GOMAXPROCS(runtime.NumCPU())
35 |
36 | flag.Parse()
37 |
38 | // launch profiler if in profile mode
39 | if *profileMode {
40 | go func() {
41 | log.Println(http.ListenAndServe(":6060", nil))
42 | }()
43 | }
44 |
45 | log.Infof("Trying to start the AMC server...")
46 |
47 | config := common.Config{}
48 | common.InitConfig(*configFile, *configDir, &config)
49 |
50 | // close the log file on exit
51 | defer func() {
52 | if config.LogFile != nil {
53 | config.LogFile.Close()
54 | }
55 | }()
56 |
57 | common.SetupDatabase(config.AMC.Database)
58 | controllers.Server(&config)
59 | }
60 |
--------------------------------------------------------------------------------
/main_linux.go:
--------------------------------------------------------------------------------
1 | // +build !darwin
2 |
3 | package main
4 |
5 | import (
6 | "flag"
7 | "io/ioutil"
8 | "net/http"
9 | _ "net/http/pprof"
10 | "os"
11 | "runtime"
12 | "runtime/debug"
13 | "syscall"
14 |
15 | "github.com/sevlyar/go-daemon"
16 | log "github.com/sirupsen/logrus"
17 |
18 | "github.com/aerospike-community/amc/common"
19 | "github.com/aerospike-community/amc/controllers"
20 | )
21 |
22 | var (
23 | configFile = flag.String("config-file", "/etc/amc/amc.conf", "Configuration file.")
24 | configDir = flag.String("config-dir", "/etc/amc/", "Configuration dir.")
25 | profileMode = flag.Bool("profile", false, "Run benchmarks with profiler active on port 6060.")
26 | daemonMode = flag.Bool("daemon", false, "Run AMC in daemon mode.")
27 | daemonSignal = flag.String("signal", "", `send signal to the daemon
28 | stop — graceful shutdown.`)
29 | )
30 |
31 | func main() {
32 | defer func() {
33 | if err := recover(); err != nil {
34 | log.Fatal(string(debug.Stack()))
35 | }
36 | }()
37 |
38 | runtime.GOMAXPROCS(runtime.NumCPU())
39 |
40 | flag.Parse()
41 |
42 | if *daemonSignal == "stop" {
43 | log.SetOutput(ioutil.Discard)
44 | }
45 |
46 | // launch profiler if in profile mode
47 | if *profileMode {
48 | go func() {
49 | log.Println(http.ListenAndServe(":6060", nil))
50 | }()
51 | }
52 |
53 | log.Infof("Trying to start the AMC server...")
54 |
55 | config := common.Config{}
56 | common.InitConfig(*configFile, *configDir, &config)
57 |
58 | // close the log file on exit
59 | defer func() {
60 | if config.LogFile != nil {
61 | config.LogFile.Close()
62 | }
63 | }()
64 |
65 | /*
66 |
67 | manage daemon
68 |
69 | */
70 |
71 | daemon.AddCommand(daemon.StringFlag(daemonSignal, "stop"), syscall.SIGTERM, shutdownHandler)
72 |
73 | cntxt := &daemon.Context{
74 | PidFileName: config.AMC.PIDFile,
75 | PidFilePerm: 0644,
76 | LogFileName: config.AMC.ErrorLog,
77 | LogFilePerm: 0640,
78 | WorkDir: config.AMC.Chdir,
79 | Umask: 027,
80 | Args: flag.Args(),
81 | }
82 |
83 | if len(daemon.ActiveFlags()) > 0 {
84 | d, err := cntxt.Search()
85 | if err != nil {
86 | log.Fatalln("Unable to send signal to the daemon:", err)
87 | }
88 | if err := daemon.SendCommands(d); err != nil {
89 | log.Fatalln(err)
90 | }
91 | return
92 | }
93 |
94 | if *daemonMode {
95 | d, err := cntxt.Reborn()
96 | if err != nil {
97 | log.Fatalln(err)
98 | }
99 | if d != nil {
100 | return
101 | }
102 | defer cntxt.Release()
103 |
104 | common.SetupDatabase(config.AMC.Database)
105 | log.Infoln("Starting AMC daemon...")
106 | go controllers.Server(&config)
107 | log.Infoln("AMC daemon started.")
108 |
109 | err = daemon.ServeSignals()
110 | if err != nil {
111 | log.Errorln("Error: ", err)
112 | }
113 | log.Println("daemon terminated.")
114 | } else {
115 | common.SetupDatabase(config.AMC.Database)
116 | controllers.Server(&config)
117 | }
118 | }
119 |
120 | func shutdownHandler(sig os.Signal) error {
121 | log.Println("Shutting down AMC gracefully...")
122 | controllers.ShutdownServer()
123 | return daemon.ErrStop
124 | }
125 |
--------------------------------------------------------------------------------
/models/attr_aliases.go:
--------------------------------------------------------------------------------
1 | package models
2 |
3 | var nsAliases = map[string]string{}
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "amc",
3 | "version": "5.0.0",
4 | "description": "AMC client integrated with the new go server",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "author": "tejas@aerospike.com",
9 | "license": "AGPLv3",
10 | "devDependencies": {
11 | "grunt": "^1.2.1",
12 | "grunt-cli": "^1.3.2",
13 | "grunt-contrib-clean": "^2.0.0",
14 | "grunt-contrib-copy": "^1.0.0",
15 | "grunt-contrib-cssmin": "^3.0.0",
16 | "grunt-contrib-uglify": "^5.0.0",
17 | "grunt-filerev": "^2.3.1",
18 | "grunt-filerev-replace": "^0.1.5",
19 | "grunt-text-replace": "^0.4.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/rrd/rrd_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013-2016 Aerospike, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package rrd
16 |
17 | import (
18 | "time"
19 |
20 | . "github.com/onsi/ginkgo"
21 | . "github.com/onsi/gomega"
22 |
23 | "testing"
24 |
25 | "github.com/aerospike-community/amc/common"
26 | )
27 |
28 | func TestRRD(t *testing.T) {
29 | RegisterFailHandler(Fail)
30 | RunSpecs(t, "RRD Suite")
31 | }
32 |
33 | var _ = Describe("Stats Bucket", func() {
34 |
35 | It("must Add the first values correctly", func() {
36 | bucket := NewBucket(5, 10, true)
37 | Expect(bucket.LastValue()).To(BeNil())
38 |
39 | tm1 := time.Now().Unix()
40 | val1 := float64(1)
41 | bucket.Add(tm1, val1)
42 | // fmt.Printf("%#v\n", *bucket)
43 | Expect(bucket.LastValue()).To(BeNil())
44 |
45 | tm2 := tm1 + 5
46 | val2 := float64(2)
47 | bucket.Add(tm2, val2)
48 |
49 | // fmt.Printf("%#v\n", *bucket)
50 |
51 | expectedTm2 := tm1 + 5
52 | expectedVal2 := float64(1) / 5 // delta / resolution
53 | Expect(*bucket.LastValue()).To(Equal(*common.NewSinglePointValue(&expectedTm2, &expectedVal2)))
54 |
55 | tm3 := tm2 + 5
56 | val3 := float64(7)
57 | bucket.Add(tm3, val3)
58 |
59 | // fmt.Printf("%#v\n", *bucket)
60 |
61 | expectedTm3 := tm2 + 5
62 | expectedVal3 := float64(5) / 5 // delta / resolution
63 | Expect(*bucket.LastValue()).To(Equal(*common.NewSinglePointValue(&expectedTm3, &expectedVal3)))
64 |
65 | // skip two slots
66 | tm4 := tm3 + 15
67 | val4 := float64(22)
68 | bucket.Add(tm4, val4)
69 |
70 | // fmt.Printf("%#v\n", *bucket)
71 |
72 | expectedTm4 := tm3 + 15
73 | expectedVal4 := float64(15) / (3 * 5) // delta / (empty ticks * resolution)
74 | Expect(*bucket.LastValue()).To(Equal(*common.NewSinglePointValue(&expectedTm4, &expectedVal4)))
75 |
76 | // check inside values
77 | expectedTm4_1 := tm3 + 5
78 | expectedTm4_2 := tm3 + 10
79 | Expect(bucket.ValuesSince(time.Unix(tm1-1, 0))).To(Equal([]*common.SinglePointValue{
80 | common.NewSinglePointValue(&expectedTm2, &expectedVal2),
81 | common.NewSinglePointValue(&expectedTm3, &expectedVal3),
82 | common.NewSinglePointValue(&expectedTm4_1, &expectedVal4),
83 | common.NewSinglePointValue(&expectedTm4_2, &expectedVal4),
84 | common.NewSinglePointValue(&expectedTm4, &expectedVal4),
85 | }))
86 | })
87 | })
88 |
--------------------------------------------------------------------------------
/rrd/simple_bucket.go:
--------------------------------------------------------------------------------
1 | package rrd
2 |
3 | import (
4 | "math"
5 | "sync"
6 | "time"
7 |
8 | // "github.com/sasha-s/go-deadlock"
9 | // log "github.com/sirupsen/logrus"
10 |
11 | "github.com/aerospike-community/amc/common"
12 | )
13 |
14 | // SimpleBucket type struct
15 | type SimpleBucket struct {
16 | beginTime *int64
17 | resolution int
18 |
19 | values []interface{}
20 | offset int // determines the offset from beginTime in resolution steps
21 |
22 | lastValue interface{}
23 | lastTimestamp *int64
24 |
25 | mutex sync.RWMutex
26 | }
27 |
28 | // NewSimpleBucket - create simple bucket
29 | func NewSimpleBucket(resolution, size int) *SimpleBucket {
30 | if !common.AMCIsProd() {
31 | // log.Info("creating bucket...")
32 | }
33 | return &SimpleBucket{
34 | resolution: 5,
35 | values: make([]interface{}, size),
36 | }
37 | }
38 |
39 | // Size - get bucket size
40 | func (b *SimpleBucket) Size() int {
41 | return len(b.values)
42 | }
43 |
44 | // Add - add to bucket
45 | func (b *SimpleBucket) Add(timestamp int64, val interface{}) {
46 | b.mutex.Lock()
47 | defer b.mutex.Unlock()
48 |
49 | // don't add out of order timestamps
50 | if b.lastTimestamp != nil && *b.lastTimestamp > timestamp {
51 | return
52 | }
53 |
54 | if b.beginTime == nil {
55 | b.beginTime = ×tamp
56 | }
57 |
58 | // protect against values set in the past
59 | if timestamp < *b.beginTime {
60 | return
61 | }
62 |
63 | var newOffset int64 = (timestamp - *b.beginTime) / int64(b.resolution)
64 | emptyTicks := int(newOffset) - b.offset
65 |
66 | if emptyTicks >= b.Size() {
67 | for i := range b.values {
68 | b.values[i] = nil
69 | }
70 | } else if emptyTicks > 1 {
71 | for i := b.offset; i <= emptyTicks; i++ {
72 | b.values[i%b.Size()] = &val
73 | }
74 | }
75 |
76 | b.offset = int(newOffset)
77 | b.values[b.offset%b.Size()] = &val
78 | b.lastTimestamp = ×tamp
79 | b.lastValue = val
80 | }
81 |
82 | // ValuesSince - get values since time
83 | func (b *SimpleBucket) ValuesSince(tm time.Time) []interface{} {
84 | b.mutex.RLock()
85 | defer b.mutex.RUnlock()
86 |
87 | // if map is empty,
88 | if b.beginTime == nil {
89 | return []interface{}{}
90 | }
91 |
92 | if tm.Unix() < *b.beginTime {
93 | tm = time.Unix(*b.beginTime, 0)
94 | }
95 | count := int(math.Ceil(float64((*b.beginTime+int64(b.offset*b.resolution))-tm.Unix()) / float64(b.resolution)))
96 |
97 | if count <= 0 {
98 | return []interface{}{}
99 | }
100 |
101 | if count > b.Size() {
102 | count = b.Size()
103 | }
104 |
105 | if count > b.offset {
106 | count = b.offset + 1
107 | }
108 |
109 | res := make([]interface{}, 0, count)
110 | for i := b.offset - count + 1; i <= b.offset; i++ {
111 | if v := b.values[i%b.Size()]; v != nil {
112 | res = append(res, v)
113 | }
114 | }
115 |
116 | return res
117 | }
118 |
119 | // LastValue - get last value
120 | func (b *SimpleBucket) LastValue() interface{} {
121 | b.mutex.RLock()
122 | defer b.mutex.RUnlock()
123 |
124 | return b.lastValue
125 | }
126 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -x
4 | set -e
5 |
6 | cd $GOPATH/src/github.com/aerospike-community/amc
7 |
8 | edition=${1:-enterprise}
9 | environ=${2:-dev}
10 |
11 | build=`date -u +%Y%m%d.%H%M%S`
12 | version=`git describe --tags $(git rev-list --tags --max-count=1)`
13 | # tag=`git rev-parse --short HEAD`
14 | version_build="$edition-$version"
15 |
16 | # build binary
17 | go build -race -a -o amc -tags $edition -ldflags "-X github.com/aerospike-community/amc/common.AMCEdition=$edition -X github.com/aerospike-community/amc/common.AMCBuild=$build -X github.com/aerospike-community/amc/common.AMCVersion=$version -X github.com/aerospike-community/amc/common.AMCEnv=$environ"
18 |
19 | ./amc -config-file=$GOPATH/src/github.com/aerospike-community/amc/amc.dev.conf
20 |
--------------------------------------------------------------------------------
/server-dev.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -x
4 | set -e
5 |
6 | cd $GOPATH/src/github.com/aerospike-community/amc
7 |
8 | edition=$1
9 | edition=enterprise
10 |
11 | build=`date -u +%Y%m%d.%H%M%S`
12 | version=`git describe --tags $(git rev-list --tags --max-count=1)`
13 | # tag=`git rev-parse --short HEAD`
14 | version_build="$edition-$version"
15 |
16 | # build binary
17 | #godep go build -race -a -tags $edition -ldflags "-X github.com/aerospike-community/amc/common.AMCEdition=$edition -X github.com/aerospike-community/amc/common.AMCBuild=$build -X github.com/aerospike-community/amc/common.AMCVersion=$version -X github.com/aerospike-community/amc/common.AMCEnv=dev" -o amc .
18 | go build -race -a -tags $edition -ldflags "-X github.com/aerospike-community/amc/common.AMCEdition=$edition -X github.com/aerospike-community/amc/common.AMCBuild=$build -X github.com/aerospike-community/amc/common.AMCVersion=$version -X github.com/aerospike-community/amc/common.AMCEnv=dev" -o amc .
19 |
20 | ./amc -config-file=$GOPATH/src/github.com/aerospike-community/amc/amc.dev.conf -profile
21 |
--------------------------------------------------------------------------------
/static/css/fonts/MavenPro-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/fonts/MavenPro-Regular.ttf
--------------------------------------------------------------------------------
/static/css/fonts/icomoon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/fonts/icomoon.ttf
--------------------------------------------------------------------------------
/static/css/jqgrid/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqgrid/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/static/css/jqgrid/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqgrid/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/animated-overlay.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/animated-overlay.gif
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_flat_30_cccccc_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_flat_30_cccccc_40x100.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_flat_50_5c5c5c_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_flat_50_5c5c5c_40x100.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_glass_20_555555_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_glass_20_555555_1x400.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_glass_40_0078a3_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_glass_40_0078a3_1x400.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_glass_40_ffc73d_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_glass_40_ffc73d_1x400.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_glass_75_d0e5f5_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_glass_75_d0e5f5_1x400.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_gloss-wave_25_333333_500x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_gloss-wave_25_333333_500x100.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_highlight-soft_80_eeeeee_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_highlight-soft_80_eeeeee_1x100.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_inset-hard_100_fcfdfd_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_inset-soft_25_000000_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_inset-soft_25_000000_1x100.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-bg_inset-soft_30_f58400_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-bg_inset-soft_30_f58400_1x100.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-icons_4b8e0b_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-icons_4b8e0b_256x240.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-icons_a83300_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-icons_a83300_256x240.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-icons_cccccc_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-icons_cccccc_256x240.png
--------------------------------------------------------------------------------
/static/css/jqueryui/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/jqueryui/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/static/css/sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/css/sprite.png
--------------------------------------------------------------------------------
/static/css/timeseries.css:
--------------------------------------------------------------------------------
1 | svg.timeseries{
2 | display: block;
3 | }
4 |
5 | .timeseries.axis.y.line {
6 | stroke : #000000;
7 | stroke-width : 2px;
8 | }
9 |
10 | .timeseries.axis.x.line {
11 | stroke : #3355aa;
12 | stroke-width : 2px;
13 |
14 | }
15 |
16 | .timeseries.axis.tickline{
17 | stroke : #888888;
18 | stroke-width : 1px;
19 | opacity : 0.6;
20 | stroke-dasharray : 2px 4px;
21 | z-index : 2;
22 | }
23 |
24 | .timeseries.axis.y.ticktext{
25 | fill : #000000;
26 | font-size : 10px;
27 | font-weight : bold;
28 | }
29 |
30 | .timeseries.axis.x.ticktext{
31 | fill : #666666;
32 | font-size: 0.7em;
33 | }
34 |
35 | .timeseries.path {
36 | stroke-width : 2px;
37 | z-index : 5;
38 | }
39 |
40 | .timeseries.bubble.container{
41 | position : fixed;
42 | z-index : 1000;
43 | display : inline-block;
44 | pointer-events : none;
45 | box-shadow: -4px -2px 20px -5px black;
46 | }
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/static/css/vertical-tabs.css:
--------------------------------------------------------------------------------
1 |
2 | .wrapper
3 | {
4 | padding: 10px;
5 | min-height: 100px;
6 | }
7 | .wrapper h1, .wrapper h4, .wrapper p, .wrapper pre, .wrapper ul, .wrapper li
8 | {
9 | margin: 0;
10 | padding: 0;
11 | border: 0;
12 | vertical-align: baseline;
13 | background: transparent;
14 | }
15 | .wrapper li
16 | {
17 |
18 | outline: 0;
19 | text-decoration: none;
20 | -webkit-transition-property: background color;
21 | -moz-transition-property: background color;
22 | -o-transition-property: background color;
23 | -ms-transition-property: background color;
24 | transition-property: background color;
25 | -webkit-transition-duration: 0.12s;
26 | -moz-transition-duration: 0.12s;
27 | -o-transition-duration: 0.12s;
28 | -ms-transition-duration: 0.12s;
29 | transition-duration: 0.12s;
30 | -webkit-transition-timing-function: ease-out;
31 | -moz-transition-timing-function: ease-out;
32 | -o-transition-timing-function: ease-out;
33 | -ms-transition-timing-function: ease-out;
34 | transition-timing-function: ease-out;
35 | }
36 | #v-nav
37 | {
38 | height: 100%;
39 | margin: auto;
40 | color: #333;
41 | }
42 | #v-nav >ul
43 | {
44 | float: left;
45 | width: 213px;
46 | display: block;
47 | position: relative;
48 | top: 0;
49 | border: 1px solid #DDD;
50 | margin: auto 0 !important;
51 | padding:0;
52 | font-size: 0.8em;
53 | }
54 | #v-nav >ul >li
55 | {
56 | cursor: pointer;
57 |
58 | width: 180px;
59 | list-style-type: none;
60 | display: block;
61 | text-shadow: 0px 1px 1px #F2F1F0;
62 | font-size: 1.11em;
63 | position: relative;
64 | border-right-width: 0;
65 | border-bottom: 1px solid #DDD;
66 | margin: auto;
67 | padding: 8px 15px !important;
68 | background: whiteSmoke;
69 | background: -moz-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
70 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f2f2f2));
71 | background: -webkit-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
72 | background: -o-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
73 | background: -ms-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
74 | background: linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
75 | }
76 | #v-nav >ul >li.current
77 | {
78 | color: black;
79 | border-right: none;
80 | z-index: 10;
81 | background: white;
82 | position: relative;
83 | moz-box-shadow: inset 0 0 35px 5px #fafbfd;
84 | -webkit-box-shadow: inset 0 0 35px 5px #fafbfd;
85 | box-shadow: inset 0 0 35px 5px #fafbfd;
86 | }
87 | #v-nav >ul >li.first.current
88 | {
89 | border-bottom: 1px solid #DDD;
90 | }
91 | #v-nav >ul >li.last
92 | {
93 | border-bottom: none;
94 | }
95 | #v-nav >div.tab-content
96 | {
97 | margin-left: 210px;
98 | border: 1px solid #ddd;
99 | background-color: #FFF;
100 |
101 | min-height: 350px;
102 | position: relative;
103 | z-index: 9;
104 | box-shadow: inset 0 0 35px 5px #fafbfd;
105 | display: none;
106 | padding: 10px 20px;
107 | }
108 | #v-nav >div.tab-content >h4
109 | {
110 | font-size: 1.1em;
111 | color: Black;
112 | border-bottom: 1px dotted #EEEDED;
113 | padding-top: 5px;
114 | padding-bottom: 5px;
115 | font-weight: normal;
116 | }
117 | @media screen and (max-width: 755px) {
118 | #v-nav >ul{
119 | width: 104px;
120 | }
121 |
122 | #v-nav >ul >li{
123 | width: 100px;
124 |
125 | padding-left: 2px !important;
126 | padding-right: 2px !important;
127 | }
128 |
129 | #v-nav >div.tab-content {
130 | margin-left: 104px;
131 | padding:8px;
132 | font-size:10px;
133 |
134 | text-align: center;
135 | }
136 |
137 | #v-nav >div.tab-content input{
138 | display:block;
139 | width: 94% !important;
140 | text-align: center;
141 |
142 | }
143 |
144 | #v-nav >div.tab-content button{
145 | width:80%;
146 | max-width:240px;
147 | }
148 | .runSubmit{
149 | margin: 15px 0px 0px 0px;
150 | }
151 |
152 | .vsubmit{
153 | margin: 15px 0px 0px 0px;
154 | }
155 | #applyConfig{
156 | margin-right: 0.5%;
157 | margin-top: -1px;
158 | }
159 | #applyConfigBtn{
160 | width: 35px;
161 | height: 20px;
162 |
163 | padding: 0;
164 | }
165 |
166 | #v-nav label{
167 | float: none;
168 |
169 | }
170 | }
--------------------------------------------------------------------------------
/static/images/arrow_down.svg:
--------------------------------------------------------------------------------
1 |
2 |
66 |
--------------------------------------------------------------------------------
/static/images/arrow_up.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
14 |
--------------------------------------------------------------------------------
/static/images/bg-btn-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/images/bg-btn-blue.png
--------------------------------------------------------------------------------
/static/images/bg-btn-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/images/bg-btn-grey.png
--------------------------------------------------------------------------------
/static/images/cog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/images/cog.png
--------------------------------------------------------------------------------
/static/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/images/favicon.png
--------------------------------------------------------------------------------
/static/images/link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/images/link.png
--------------------------------------------------------------------------------
/static/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/images/loading.gif
--------------------------------------------------------------------------------
/static/images/sidepanelpattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aerospike-community/amc/6eec0fdf877db255a77791aa87d8870ca1dc9b38/static/images/sidepanelpattern.png
--------------------------------------------------------------------------------
/static/js/collections/configs/namespaces.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["jquery", "underscore", "backbone", "helper/util", "models/configs/statmodel", "views/configs/statview", "config/app-config", "config/view-config", "helper/edit-config"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
7 | var NamespaceCollection = Backbone.Collection.extend({
8 | model: StatModel,
9 | initVariables :function(){
10 | },
11 | initialize : function(){
12 | this.statTableID = AppConfig.stat.statTableDiv;
13 | this.statList = AppConfig.namespaceConfigList;
14 | },
15 | initializeGrid: function(){
16 | // StatTable.startInitGrid(AppConfig.namespaceConfigList);
17 | },
18 | clearAndInitGridData: function(){
19 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
20 | // StatTable.initAndSetGridData(AppConfig.namespaceConfigList);
21 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
22 | },
23 | addModel: function(address, clusterID, namespaceName){
24 | var namespace = new StatModel();
25 | namespace.setParamaters(address, clusterID, 'namespace', AppConfig.stat.statTableDiv, AppConfig.namespaceConfigList, namespaceName);
26 | namespace.colView = new StatView({el : ("[id='statListTable_" + address + "']")});
27 | this.add(namespace);
28 | return namespace;
29 | }
30 | });
31 | return NamespaceCollection;
32 | });
33 |
34 |
35 |
--------------------------------------------------------------------------------
/static/js/collections/configs/nodes.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["jquery", "underscore", "backbone", "helper/util", "models/configs/statmodel", "views/configs/statview", "config/app-config", "config/view-config", "helper/edit-config"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
7 | var NodeCollection = Backbone.Collection.extend({
8 | model: StatModel,
9 | initialize : function(){
10 | },
11 | initializeGrid: function(){
12 | // StatTable.startInitGrid(AppConfig.nodeConfigList);
13 | },
14 | clearAndInitGridData: function(){
15 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData',true);
16 | //StatTable.initAndSetGridData(AppConfig.nodeConfigList);
17 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
18 | },
19 | addModel: function(address, clusterID, tobeUsed){
20 | var node = new StatModel();
21 | node.colView = new StatView({el : ("[id='statListTable_" + address + "']")});
22 | this.add(node);
23 | node.setParamaters(address, clusterID, 'nodes', AppConfig.stat.statTableDiv, AppConfig.nodeConfigList, tobeUsed);
24 | return node;
25 | }
26 | });
27 | return NodeCollection;
28 | });
29 |
30 |
31 |
--------------------------------------------------------------------------------
/static/js/collections/configs/sindex.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["jquery", "underscore", "backbone", "helper/util", "models/configs/statmodel", "views/configs/statview", "config/app-config", "config/view-config", "helper/edit-config"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
7 | var SIndexesCollection = Backbone.Collection.extend({
8 | model: StatModel,
9 | initialize : function(){
10 | // this.statTableID = AppConfig.stat.statTableDiv;
11 | // this.statList = AppConfig.namespaceConfigList;
12 | },
13 | initializeGrid: function(){
14 | // StatTable.startInitGrid(AppConfig.sIndexStatsList);
15 | },
16 | clearAndInitGridData: function(){
17 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
18 | // StatTable.initAndSetGridData(AppConfig.sIndexStatsList);
19 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
20 | },
21 | addModel: function(address, clusterID, tobeUsed){
22 | var sIndex = new StatModel();
23 | sIndex.colView = new StatView({el : ("[id='statListTable_" + address + "']")});
24 | sIndex.setParamaters(address, clusterID, 'sindex', AppConfig.stat.statTableDiv, AppConfig.sIndexStatsList, tobeUsed);
25 | this.add(sIndex);
26 | return sIndex;
27 | }
28 | });
29 | return SIndexesCollection;
30 | });
31 |
32 |
33 |
--------------------------------------------------------------------------------
/static/js/collections/configs/xdr.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["jquery", "underscore", "backbone", "helper/util", "models/configs/statmodel", "views/configs/statview", "config/app-config", "config/view-config", "helper/edit-config"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
7 | var XDRCollection = Backbone.Collection.extend({
8 | model: StatModel,
9 | initialize : function(){
10 | this.statTableID = AppConfig.stat.statTableDiv;
11 | this.statList = AppConfig.xdrConfigList;
12 | },
13 | initializeGrid: function(){
14 | // StatTable.startInitGrid(AppConfig.xdrConfigList);
15 | },
16 | clearAndInitGridData: function(){
17 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
18 | // StatTable.initAndSetGridData(AppConfig.xdrConfigList);
19 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
20 | },
21 | addModel: function(address, clusterID, xdrPort){
22 | var xdr = new StatModel();
23 | xdr.setParamaters(address, clusterID, 'xdr', AppConfig.stat.statTableDiv, AppConfig.xdrConfigList, xdrPort);
24 | xdr.colView = new StatView({el : ("[id='statListTable_" + address + "']")});
25 | this.add(xdr);
26 | return xdr;
27 | }
28 | });
29 | return XDRCollection;
30 | });
31 |
32 |
33 |
--------------------------------------------------------------------------------
/static/js/collections/definitions/sets.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var SetsCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initialize : function(){
24 | // this.statTableID = AppConfig.stat.statTableDiv;
25 | // this.statList = AppConfig.xdrStatsList;
26 | },
27 | initializeGrid: function(){
28 | StatTable.startInitGrid(AppConfig.xdrStatsList);
29 | },
30 | clearAndInitGridData: function(){
31 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
32 | StatTable.initAndSetGridData(AppConfig.xdrStatsList);
33 | $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
34 | },
35 | addModel: function(address, clusterID, xdrPort){
36 | var xdr = new StatModel({"update_interval" : 5});
37 | xdr.setParamaters(address, clusterID, 'xdr', AppConfig.stat.statTableDiv, AppConfig.xdrStatsList, xdrPort);
38 | xdr.colView = new StatView();
39 | this.add(xdr);
40 | return xdr;
41 | }
42 | });
43 | return SetsCollection;
44 | });
45 |
46 |
47 |
--------------------------------------------------------------------------------
/static/js/collections/definitions/sindexes.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var SIndexCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initialize : function(){
24 | // this.statTableID = AppConfig.stat.statTableDiv;
25 | // this.statList = AppConfig.xdrStatsList;
26 | },
27 | initializeGrid: function(){
28 | StatTable.startInitGrid(AppConfig.xdrStatsList);
29 | },
30 | clearAndInitGridData: function(){
31 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
32 | StatTable.initAndSetGridData(AppConfig.xdrStatsList);
33 | $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
34 | },
35 | addModel: function(address, clusterID, xdrPort){
36 | var xdr = new StatModel({"update_interval" : 5});
37 | xdr.setParamaters(address, clusterID, 'xdr', AppConfig.stat.statTableDiv, AppConfig.xdrStatsList, xdrPort);
38 | xdr.colView = new StatView({model: xdr});
39 | this.add(xdr);
40 | return xdr;
41 | }
42 | });
43 | return SIndexCollection;
44 | });
45 |
46 |
47 |
--------------------------------------------------------------------------------
/static/js/collections/definitions/udf.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var UDFCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initialize : function(){
24 | // this.statTableID = AppConfig.stat.statTableDiv;
25 | // this.statList = AppConfig.xdrStatsList;
26 | },
27 | initializeGrid: function(){
28 | StatTable.startInitGrid(AppConfig.xdrStatsList);
29 | },
30 | clearAndInitGridData: function(){
31 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
32 | StatTable.initAndSetGridData(AppConfig.xdrStatsList);
33 | $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
34 | },
35 | addModel: function(address, clusterID, xdrPort){
36 | var xdr = new StatModel({"update_interval" : 5});
37 | xdr.setParamaters(address, clusterID, 'xdr', AppConfig.stat.statTableDiv, AppConfig.xdrStatsList, xdrPort);
38 | xdr.colView = new StatView();
39 | this.add(xdr);
40 | return xdr;
41 | }
42 | });
43 | return UDFCollection;
44 | });
45 |
46 |
47 |
--------------------------------------------------------------------------------
/static/js/collections/definitions/xdrs.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var XDRCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initialize : function(){
24 | // this.statTableID = AppConfig.stat.statTableDiv;
25 | // this.statList = AppConfig.xdrStatsList;
26 | },
27 | initializeGrid: function(){
28 | StatTable.startInitGrid(AppConfig.xdrStatsList);
29 | },
30 | clearAndInitGridData: function(){
31 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
32 | StatTable.initAndSetGridData(AppConfig.xdrStatsList);
33 | $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
34 | },
35 | addModel: function(address, clusterID, xdrPort){
36 | var xdr = new StatModel({"update_interval" : 5});
37 | xdr.setParamaters(address, clusterID, 'xdr', AppConfig.stat.statTableDiv, AppConfig.xdrStatsList, xdrPort);
38 | xdr.colView = new StatView();
39 | this.add(xdr);
40 | return xdr;
41 | }
42 | });
43 | return XDRCollection;
44 | });
45 |
46 |
47 |
--------------------------------------------------------------------------------
/static/js/collections/jobs/nodes.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/jobs/nodemodel", "views/jobs/nodeview", "config/app-config", "config/view-config", "helper/job-table"], function($, _, Backbone, Util, NodeModel, NodeView, AppConfig, ViewConfig, JobTable){
21 | var PAGE_SIZE = 10;
22 | var NodeCollection = Backbone.Collection.extend({
23 | model: NodeModel,
24 | initVariables :function(){
25 | this.clusterSizeAlertShown = false;
26 | this.clusterIntegrityAlertShown = false;
27 | },
28 | initialize : function(){
29 | try{
30 | this.initVariables();
31 | JobTable.initNodeGrid(AppConfig.node.nodeTableDiv, ViewConfig.nodePieConfig, this.models, AppConfig.job.runningJobPager, PAGE_SIZE, 'inprogress');
32 | JobTable.initNodeGrid(AppConfig.job.nodeTableCompletedJobsDiv, ViewConfig.nodePieConfig, this.models, AppConfig.job.completedJobPager, PAGE_SIZE, 'completed');
33 | }catch(e){
34 | console.info(e.toString());
35 | }
36 | },
37 | addModel: function(modelID, clusterID, status, container){
38 | var node = new NodeModel({model_id:modelID, cluster_id:clusterID, status: status, container: container, page_size: PAGE_SIZE});
39 | node.rowView = {};
40 | this.add(node);
41 | }
42 |
43 | });
44 | return NodeCollection;
45 | });
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/static/js/collections/latency/nodes.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["jquery", "underscore", "backbone", "helper/util", "models/latency/nodemodel",
7 | "config/app-config", "config/view-config", "helper/job-table", "helper/AjaxManager"],
8 | function($, _, Backbone, Util, NodeModel, AppConfig, ViewConfig, JobTable, AjaxManager){
9 | var NodeCollection = Backbone.Collection.extend({
10 | model: NodeModel,
11 | initVariables :function(){
12 | this.clusterSizeAlertShown = false;
13 | this.clusterIntegrityAlertShown = false;
14 | this.parent = {};
15 | this.latencyHistory = {}; // map of node address to latency history
16 | this.historyFetched = false;
17 | this.latencyFetchError = false;
18 | },
19 | initialize : function(){
20 | try{
21 | this.bind('add', this.onModelAdded, this);
22 | this.bind('remove', this.onModelRemoved, this);
23 | this.initVariables();
24 | this._fetchLatencyHistory();
25 | }catch(e){
26 | console.log(e);
27 | }
28 | },
29 |
30 | _fetchLatencyHistory: function() {
31 | var that = this;
32 | var url = AppConfig.baseUrl + window.AMCGLOBALS.persistent.clusterID + '/nodes/';
33 | url += window.AMCGLOBALS.persistent.nodeList.join(',');
34 | url += '/latency_history';
35 |
36 | AjaxManager.sendRequest(url, {},
37 | function success(history) {
38 | that.historyFetched = true;
39 | that.latencyHistory = history;
40 | that._initNodes();
41 | }, function error() {
42 | that.historyFetched = true;
43 | that.latencyFetchError = true;
44 | that._initNodes();
45 | }
46 | );
47 | },
48 |
49 | _initNodes: function() {
50 | var that = this;
51 | this.each(function(model) {
52 | that._initNode(model);
53 | });
54 | },
55 |
56 | // initialize node based on fetch status
57 | _initNode: function(model) {
58 | var address = model.address;
59 | var history = this.latencyHistory[address];
60 | try {
61 | if(this.latencyFetchError) {
62 | model.initLatencyHistoryOnError();
63 | } else if(history) {
64 | model.initLatencyHistory(history);
65 | } else {
66 | console.log('INFO: History not yet fetched. Not initializing node ' + address);
67 | }
68 | } catch(e) {
69 | console.log(e);
70 | }
71 | },
72 |
73 | addModel: function(modelID, address, clusterID, totalNodes){
74 | var node = new NodeModel({model_id:modelID, address: address, cluster_id:clusterID, total_nodes:totalNodes});
75 | var history = this.latencyHistory[address];
76 | var that = this;
77 | var url;
78 |
79 | this.add(node);
80 |
81 | if(this.historyFetched) {
82 | if(history) {
83 | this._initNode(node);
84 | } else {
85 | url = AppConfig.baseUrl + window.AMCGLOBALS.persistent.clusterID + '/latency_history/' + address;
86 | AjaxManager.sendRequest(url, {},
87 | function success(data) {
88 | that.latencyHistory[address] = data;
89 | that._initNode(node);
90 | },
91 | function failure() {
92 | node.initLatencyHistoryOnError();
93 | }
94 | );
95 | }
96 | }
97 | },
98 | onModelAdded: function(model, collection, options){
99 | this.parent.nodes.push(model.address);
100 | Util.updateModelPoller(this.parent, AppConfig.updateInterval['nodes'], true);
101 | },
102 | onModelRemoved: function(model, collection, options){
103 | if(this.parent.nodes != null){
104 | this.parent.nodes.splice(this.parent.nodes.indexOf(model.address),1);
105 | }
106 | $(AppConfig.node.nodeTableDiv).jqGrid('delRowData',/*AppConfig.node.nodeTablePrefix + */model.get("row_id"));
107 | }
108 |
109 | });
110 | return NodeCollection;
111 | });
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/static/js/collections/statistics/namespaces.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var NamespaceCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initVariables :function(){
24 | },
25 | initialize : function(){
26 | this.statTableID = AppConfig.stat.statTableDiv;
27 | this.statList = AppConfig.namespaceStatsList;
28 | },
29 | initializeGrid: function(){
30 | // StatTable.startInitGrid(AppConfig.namespaceStatsList);
31 | },
32 | clearAndInitGridData: function(){
33 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
34 | // StatTable.initAndSetGridData(AppConfig.namespaceStatsList);
35 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
36 | },
37 | addModel: function(address, clusterID, namespaceName){
38 | var namespace = new StatModel();
39 | namespace.setParamaters(address, clusterID, 'namespace', AppConfig.stat.statTableDiv, AppConfig.namespaceStatsList, namespaceName);
40 | namespace.colView = new StatView({model: namespace, el : ("[id='statListTable_" + address + "']")});
41 | this.add(namespace);
42 | return namespace;
43 | }
44 | });
45 | return NamespaceCollection;
46 | });
47 |
48 |
49 |
--------------------------------------------------------------------------------
/static/js/collections/statistics/nodes.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var NodeCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initialize : function(){
24 | },
25 | initializeGrid: function(){
26 | // StatTable.startInitGrid(AppConfig.nodeStatsList);
27 | },
28 | clearAndInitGridData: function(){
29 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
30 | // StatTable.initAndSetGridData(AppConfig.nodeStatsList);
31 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
32 | },
33 | addModel: function(address, clusterID, tobeUsed){
34 | var node = new StatModel();
35 | node.colView = new StatView({model: node, el : ("[id='statListTable_" + address + "']")});
36 | this.add(node);
37 | node.setParamaters(address, clusterID, 'nodes', AppConfig.stat.statTableDiv, AppConfig.nodeStatsList, tobeUsed);
38 | return node;
39 | }
40 | });
41 | return NodeCollection;
42 | });
43 |
44 |
45 |
--------------------------------------------------------------------------------
/static/js/collections/statistics/sindex.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var SIndexesCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initialize : function(){
24 | // this.statTableID = AppConfig.stat.statTableDiv;
25 | // this.statList = AppConfig.namespaceStatsList;
26 | },
27 | initializeGrid: function(){
28 | // StatTable.startInitGrid(AppConfig.sIndexStatsList);
29 | },
30 | clearAndInitGridData: function(){
31 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
32 | // StatTable.initAndSetGridData(AppConfig.sIndexStatsList);
33 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
34 | },
35 | addModel: function(address, clusterID, tobeUsed){
36 | var sIndex = new StatModel();
37 | sIndex.colView = new StatView({model: sIndex, el : ("[id='statListTable_" + address + "']")});
38 | sIndex.setParamaters(address, clusterID, 'sindex', AppConfig.stat.statTableDiv, AppConfig.sIndexStatsList, tobeUsed);
39 | this.add(sIndex);
40 | return sIndex;
41 | }
42 | });
43 | return SIndexesCollection;
44 | });
45 |
46 |
47 |
--------------------------------------------------------------------------------
/static/js/collections/statistics/xdr.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/util", "models/statistics/statmodel", "views/statistics/statview", "config/app-config", "config/view-config", "helper/stat-table"], function($, _, Backbone, Util, StatModel, StatView, AppConfig, ViewConfig, StatTable){
21 | var XDRCollection = Backbone.Collection.extend({
22 | model: StatModel,
23 | initialize : function(){
24 | this.statTableID = AppConfig.stat.statTableDiv;
25 | this.statList = AppConfig.xdrStatsList;
26 | },
27 | initializeGrid: function(){
28 | // StatTable.startInitGrid(AppConfig.xdrStatsList);
29 | },
30 | clearAndInitGridData: function(){
31 | $(AppConfig.stat.statTableDiv).jqGrid('clearGridData');
32 | // StatTable.initAndSetGridData(AppConfig.xdrStatsList);
33 | // $(AppConfig.stat.statTableDiv).trigger("reloadGrid");
34 | },
35 | addModel: function(address, clusterID, xdrPort){
36 | var xdr = new StatModel();
37 | xdr.setParamaters(address, clusterID, 'xdr', AppConfig.stat.statTableDiv, AppConfig.xdrStatsList, xdrPort);
38 | xdr.colView = new StatView({model: xdr, el : ("[id='statListTable_" + address + "']")});
39 | this.add(xdr);
40 | return xdr;
41 | }
42 | });
43 | return XDRCollection;
44 | });
45 |
46 |
47 |
--------------------------------------------------------------------------------
/static/js/config/view-config.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone" ], function($, _, Backbone){
21 | var ViewConfig = {
22 | clusterPieConfig:{
23 | width : 150,
24 | height : 150,
25 | outerRadius : 50,
26 | innerRadius : 40,
27 | textOffset : 5,
28 | tweenDuration : 1000,
29 | outerBorderWidth : 3,
30 | innerBorderWidth : 3,
31 | color : ["#61CAFF", "#FFFFFF"],
32 | textColor : ["#61CAFF", "#000000"]
33 | },
34 | tablePieConfig: {
35 | width : 45,
36 | height : 50,
37 | outerRadius : 20,
38 | innerRadius : 0,
39 | textOffset : 5,
40 | tweenDuration : 1000,
41 | outerBorderWidth : 2,
42 | color : ["#61CAFF", "#FFFFFF"]
43 | },
44 | throughputChartConfig: {
45 | gWidth : 440,
46 | gHeight : 250,
47 | initMaxY : 1000,
48 | initMinY : 0
49 | }
50 |
51 | };
52 |
53 | return ViewConfig;
54 |
55 |
56 | });
--------------------------------------------------------------------------------
/static/js/dev.app.build.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | ({
21 | appDir : "../",
22 | baseUrl: "./js",
23 | dir: "../../script-build",
24 |
25 | paths: {
26 | //Libraries
27 | jquery: "libs/jquery/consolidated-jquery-functionalities.min",
28 | underscore: "libs/underscore/underscore",
29 | backbone: "libs/backbone/backbone",
30 | poller: "libs/backbone/backbone.poller.min",
31 | d3: "libs/d3/d3",
32 | d3Layout: "libs/d3/d3.layout.min",
33 | timechart: "libs/timechart/timechart",
34 | //Aerospike JS
35 | piechart: "helper/piechart",
36 | timeseriesChart: "helper/timechart-helper"
37 | }
38 | })
39 |
40 |
41 |
--------------------------------------------------------------------------------
/static/js/helper/AjaxManager.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery","underscore","helper/util"],function($,_,Util){
21 | var AjaxManager = {
22 |
23 | //Request type constants
24 | GET : "GET",
25 | POST : "POST",
26 | UPDATE : 'UPDATE',
27 | DELETE : 'DELETE',
28 |
29 | initAjaxFailureCatch : function(){
30 | $(function(){
31 | //setup ajax error handling
32 | $.ajaxSetup({
33 | always : function(x){
34 | if(typeof x.responseText !== 'undefined' && x.responseText.indexOf("Invalid cluster id") != -1){
35 | Util.clusterIDReset();
36 | }
37 | },
38 | fail: function (x, status, error) {
39 | if (x.status == 401) {
40 | Util.showUserSessionInvalidateError(window.AMCGLOBALS.persistent.clusterID);
41 | }
42 | }
43 | });
44 | });
45 | },
46 |
47 | //Send the ajax request
48 | sendRequest : function(url, customOption, successCallback, failCallback){
49 | var defaultOptions = {
50 | type : this.GET,
51 | async : true,
52 | cache : true,
53 | data : {},
54 | dataType : 'json',
55 | contentType : 'application/json; charset=utf-8'
56 | };
57 |
58 | var options = $.extend({}, defaultOptions, customOption);
59 |
60 | //Actual send the ajax request
61 | var request = $.ajax({
62 | type : options.type,
63 | url : url,
64 | async : options.async,
65 | cache : options.cache,
66 | data : options.data,
67 | headers : options.header || {}
68 | })
69 | .done(function(data,textStatus, jqXHR ){
70 | successCallback && successCallback(data);
71 | })
72 | .fail(function(data,textStatus, errorThrown){
73 | failCallback && failCallback(data,textStatus, errorThrown);
74 | });
75 |
76 | return request;
77 | },
78 |
79 | //This function will abort the ajax request
80 | abortAjaxRequest : function(request){
81 | //Abort the ajax request, it is not completed
82 | if(request && request.readyState !== 4){
83 | request.abort();
84 | }
85 | }
86 | };
87 |
88 | return AjaxManager;
89 |
90 | });
--------------------------------------------------------------------------------
/static/js/helper/def-table.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "d3", "helper/jqgrid-helper", "helper/util", "config/app-config", "config/var-details"], function($, _, Backbone, D3, GridHelper, Util, AppConfig, VarDetails) {
21 | var StatTable = {
22 |
23 |
24 |
25 | };
26 |
27 | return StatTable;
28 | });
--------------------------------------------------------------------------------
/static/js/helper/definitions/set-table.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "d3", "helper/jqgrid-helper", "helper/util", "config/app-config"], function($, _, Backbone, D3, GridHelper, Util, AppConfig){
21 | var XdrTable = {
22 | nodeTableIds: [],
23 | updateRowData: function(container, data, rowID){
24 | data = XdrTable.getNodeListData(data);
25 | try{
26 | if(!jQuery(container).getInd(rowID)){
27 | jQuery(container).addRowData(rowID, data);
28 | }else{
29 | jQuery(container).setRowData(rowID, data);
30 | }
31 | }catch(e){
32 | console.info(e.toString());
33 | }
34 | //NodeTable.nodeTableIds = GridHelper.maintainExpandedState(container, NodeTable.nodeTableIds);
35 | //$(container).trigger("reloadGrid");
36 | },
37 | getNodeListData: function(data){
38 | data['esmt-bytes-shipped'] = GridHelper.formatExpandRow(data['esmt-bytes-shipped'], "size");
39 | data['timediff_lastship_cur_secs'] = GridHelper.formatExpandRow(data['timediff_lastship_cur_secs'], "sec");
40 | data['xdr_timelag'] = GridHelper.formatExpandRow(data['xdr_timelag'], "sec");
41 | data['stat_recs_outstanding'] = GridHelper.formatExpandRow(data['stat_recs_outstanding'], "number");
42 | data['stat_recs_shipped'] = GridHelper.formatExpandRow(data['stat_recs_shipped'], "number");
43 | data['stat_recs_relogged'] = GridHelper.formatExpandRow(data['stat_recs_relogged'], "number");
44 | data['cur_throughput'] = GridHelper.formatExpandRow(data['cur_throughput'], "number");
45 | return data;
46 | },
47 | initNodeGrid: function(container, pieConfig, models){
48 | //$(container).jqGrid('GridDestroy');
49 | var containerWidth = Math.max(window.innerWidth * 0.93, 750);
50 | var grid = jQuery(container).jqGrid({
51 | datatype:'local',
52 | //data: nodeListData,
53 | hidegrid: false,
54 | colNames: AppConfig.xdrColumnNames,
55 | colModel: AppConfig.xdrListColumn,
56 | height:'auto',
57 | loadui : 'disable',
58 | loadonce:true,
59 | //ExpandColClick: true,
60 | subGrid: false,
61 | headertitles : true,
62 | //sortname: "address",
63 | //sortorder: "asc",
64 | //cmTemplate: {sortable:false},
65 | width:containerWidth,
66 | loadComplete: function () {
67 | $(container).jqGrid('hideCol', 'subgrid');
68 | $("#nodeStatListGrid1 .toggleSearchHeader").show();
69 | }
70 | });
71 | GridHelper.columnHeaderTitleFormatter(grid, AppConfig.xdrListColumn );
72 | function handler() {
73 | if(window.AMCGLOBALS.activePage !== "definitions"){
74 | window.removeEventListener("resize", handler,true);
75 | return;
76 | }
77 | $(container.selector).setGridWidth(Math.max(window.innerWidth * 0.93, 750));
78 | }
79 | window.addEventListener('resize', handler, true);
80 | return grid;
81 | }
82 |
83 | };
84 |
85 | return XdrTable;
86 | });
87 |
--------------------------------------------------------------------------------
/static/js/helper/definitions/udf-table.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "d3", "helper/jqgrid-helper", "helper/util", "config/app-config"], function($, _, Backbone, D3, GridHelper, Util, AppConfig){
21 | var XdrTable = {
22 | nodeTableIds: [],
23 | updateRowData: function(container, data, rowID){
24 | data = XdrTable.getNodeListData(data);
25 | try{
26 | if(!jQuery(container).getInd(rowID)){
27 | jQuery(container).addRowData(rowID, data);
28 | }else{
29 | jQuery(container).setRowData(rowID, data);
30 | }
31 | }catch(e){
32 | console.info(e.toString());
33 | }
34 | //NodeTable.nodeTableIds = GridHelper.maintainExpandedState(container, NodeTable.nodeTableIds);
35 | //$(container).trigger("reloadGrid");
36 | },
37 | getNodeListData: function(data){
38 | data['esmt-bytes-shipped'] = GridHelper.formatExpandRow(data['esmt-bytes-shipped'], "size");
39 | data['timediff_lastship_cur_secs'] = GridHelper.formatExpandRow(data['timediff_lastship_cur_secs'], "sec");
40 | data['xdr_timelag'] = GridHelper.formatExpandRow(data['xdr_timelag'], "sec");
41 | data['stat_recs_outstanding'] = GridHelper.formatExpandRow(data['stat_recs_outstanding'], "number");
42 | data['stat_recs_shipped'] = GridHelper.formatExpandRow(data['stat_recs_shipped'], "number");
43 | data['stat_recs_relogged'] = GridHelper.formatExpandRow(data['stat_recs_relogged'], "number");
44 | data['cur_throughput'] = GridHelper.formatExpandRow(data['cur_throughput'], "number");
45 | return data;
46 | },
47 | initNodeGrid: function(container, pieConfig, models){
48 | //$(container).jqGrid('GridDestroy');
49 | var containerWidth = Math.max(window.innerWidth * 0.93, 750);
50 | var grid = jQuery(container).jqGrid({
51 | datatype:'local',
52 | //data: nodeListData,
53 | hidegrid: false,
54 | colNames: AppConfig.xdrColumnNames,
55 | colModel: AppConfig.xdrListColumn,
56 | height:'auto',
57 | loadui : 'disable',
58 | loadonce:true,
59 | //ExpandColClick: true,
60 | subGrid: false,
61 | headertitles : true,
62 | //sortname: "address",
63 | //sortorder: "asc",
64 | //cmTemplate: {sortable:false},
65 | width:containerWidth,
66 | loadComplete: function () {
67 | $(container).jqGrid('hideCol', 'subgrid');
68 | }
69 | });
70 | GridHelper.columnHeaderTitleFormatter(grid, AppConfig.xdrListColumn );
71 | function handler() {
72 | if(window.AMCGLOBALS.activePage !== "definitions"){
73 | window.removeEventListener("resize", handler,true);
74 | return;
75 | }
76 | $(container.selector).setGridWidth(Math.max(window.innerWidth * 0.93, 750));
77 | }
78 | window.addEventListener('resize', handler, true);
79 | return grid;
80 | }
81 |
82 | };
83 |
84 | return XdrTable;
85 | });
86 |
--------------------------------------------------------------------------------
/static/js/helper/definitions/xdr-table.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "d3", "helper/jqgrid-helper", "helper/util", "config/app-config"], function($, _, Backbone, D3, GridHelper, Util, AppConfig){
21 | var XdrTable = {
22 | nodeTableIds: [],
23 | updateRowData: function(container, data, rowID){
24 | data = XdrTable.getNodeListData(data);
25 | try{
26 | if(!jQuery(container).getInd(rowID)){
27 | jQuery(container).addRowData(rowID, data);
28 | }else{
29 | jQuery(container).setRowData(rowID, data);
30 | }
31 | }catch(e){
32 | console.info(e.toString());
33 | }
34 | //NodeTable.nodeTableIds = GridHelper.maintainExpandedState(container, NodeTable.nodeTableIds);
35 | //$(container).trigger("reloadGrid");
36 | },
37 | getNodeListData: function(data){
38 | data['esmt-bytes-shipped'] = GridHelper.formatExpandRow(data['esmt-bytes-shipped'], "size");
39 | data['timediff_lastship_cur_secs'] = GridHelper.formatExpandRow(data['timediff_lastship_cur_secs'], "sec");
40 | data['xdr_timelag'] = GridHelper.formatExpandRow(data['xdr_timelag'], "sec");
41 | data['stat_recs_outstanding'] = GridHelper.formatExpandRow(data['stat_recs_outstanding'], "number");
42 | data['stat_recs_shipped'] = GridHelper.formatExpandRow(data['stat_recs_shipped'], "number");
43 | data['stat_recs_relogged'] = GridHelper.formatExpandRow(data['stat_recs_relogged'], "number");
44 | data['cur_throughput'] = GridHelper.formatExpandRow(data['cur_throughput'], "number");
45 | return data;
46 | },
47 | initNodeGrid: function(container, pieConfig, models){
48 | //$(container).jqGrid('GridDestroy');
49 | var grid = jQuery(container).jqGrid({
50 | datatype:'local',
51 | //data: nodeListData,
52 | hidegrid: false,
53 | colNames: AppConfig.xdrColumnNames,
54 | colModel: AppConfig.xdrListColumn,
55 | height:'auto',
56 | loadui : 'disable',
57 | loadonce:true,
58 | //ExpandColClick: true,
59 | subGrid: false,
60 | headertitles : true,
61 | //sortname: "address",
62 | //sortorder: "asc",
63 | //cmTemplate: {sortable:false},
64 | width: Math.max(window.innerWidth * 0.93, 750),
65 | loadComplete: function () {
66 | $(container).jqGrid('hideCol', 'subgrid');
67 | }
68 | });
69 | GridHelper.columnHeaderTitleFormatter(grid, AppConfig.xdrListColumn );
70 | function handler() {
71 | if(window.AMCGLOBALS.activePage !== "dashboard"){
72 | window.removeEventListener("resize", handler,true);
73 | return;
74 | }
75 | $(container.selector).setGridWidth(Math.max(window.innerWidth * 0.93, 750));
76 | }
77 | window.addEventListener('resize', handler, true);
78 | return grid;
79 | }
80 |
81 | };
82 |
83 | return XdrTable;
84 | });
85 |
--------------------------------------------------------------------------------
/static/js/helper/modal.js:
--------------------------------------------------------------------------------
1 | define(['jquery', 'underscore', 'models/common/PopupModel'], function($, _, PopupModel) {
2 | var modal = {
3 | showModalDialog : function(DOM, modalSettings, submit, cancel){
4 | $("#ModalWrapper").remove();
5 | $("body").append(DOM);
6 | $("#ModalWrapper").dialog(_.extend({
7 | modal: true,
8 | resizable: false
9 | }, modalSettings));
10 |
11 | if(submit){
12 | $("#ModalSubmit").on("click", submit);
13 | }
14 |
15 | if(cancel){
16 | $("#ModalCancel").on("click", cancel);
17 | }
18 |
19 | $("#modalBody .modal-content").on("keydown", function(e){
20 | if (e.keyCode === 13) {
21 | submit(e);
22 | }
23 | });
24 | $(window).resize(function() {
25 | $("#ModalWrapper").dialog("option", "position", "center");
26 | });
27 | },
28 |
29 | hideModalDialog : function(){
30 | $("#ModalWrapper").remove();
31 | },
32 |
33 | confirmModal: function(title, content, onselect, oncancel) {
34 | var popupModel = new PopupModel({
35 | cancelButtonValue: 'Cancel',
36 | content: '' + content + '
',
37 | modalClass: 'user-popup',
38 | submitButtonValue: 'OK',
39 | title: title,
40 | });
41 | var DOM = _.template($("#ModalTemplate").text(), popupModel.toJSON());
42 | var modalSettings = {width: '600px', closeOnEscape: true, dialogClass: 'no-dialog-title'};
43 |
44 | var success = function() {
45 | modal.hideModalDialog();
46 | onselect && onselect();
47 | };
48 | var cancel = function() {
49 | modal.hideModalDialog();
50 | oncancel && oncancel();
51 | };
52 | modal.showModalDialog(DOM, modalSettings, success, cancel);
53 | },
54 |
55 | messageModal: function(title, content, callback) {
56 | var popupModel = new PopupModel({
57 | showCancelButton: false,
58 | content: '' + content + '
',
59 | modalClass: 'user-popup',
60 | submitButtonValue: 'OK',
61 | title: '' + title + '',
62 | });
63 | var DOM = _.template($("#ModalTemplate").text(), popupModel.toJSON());
64 | var modalSettings = {width: '600px', closeOnEscape: true, dialogClass: 'no-dialog-title'};
65 |
66 | var success = function() {
67 | modal.hideModalDialog();
68 | callback && callback();
69 | };
70 | modal.showModalDialog(DOM, modalSettings, success);
71 | },
72 | };
73 |
74 | return modal;
75 | });
76 |
77 |
78 |
--------------------------------------------------------------------------------
/static/js/helper/notification.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery"], function($){
21 |
22 | var Notification = {
23 | toastNotification : function(notificationType, message, timeout, showNotificationAsModel){
24 | var notificationObj = {
25 | text : message,
26 | layout : "center",
27 | type : notificationType,
28 | timeout : (timeout == null ? 1000 : timeout),
29 | model : (showNotificationAsModel == null ? false : showNotificationAsModel),
30 | closeWith: ["click"]
31 |
32 | };
33 | if(this.toastMsg != null){
34 | /*Destroying old notification message*/
35 | if ($("#" + this.toastMsg.options.id).parent()) {
36 | $("#" + this.toastMsg.options.id).parent().remove();
37 | }
38 | }
39 | this.toastMsg = noty(notificationObj);
40 | },
41 |
42 | cleanUp : function(){
43 | $.noty.closeAll();
44 | $(".noty_bar").parent().remove();
45 | }
46 | };
47 |
48 | return Notification;
49 | });
--------------------------------------------------------------------------------
/static/js/helper/overlay.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["libs/spin/spin.min"], function(Spinner){
21 | var _defaults = {
22 | lines: 13, // The number of lines to draw
23 | length: 8, // The length of each line
24 | width: 3, // The line thickness
25 | radius: 7, // The radius of the inner circle
26 | corners: 1, // Corner roundness (0..1)
27 | rotate: 0, // The rotation offset
28 | direction: 1, // 1: clockwise, -1: counterclockwise
29 | color: '#000', // #rgb or #rrggbb or array of colors
30 | speed: 1.3, // Rounds per second
31 | trail: 60, // Afterglow percentage
32 | shadow: false, // Whether to render a shadow
33 | hwaccel: false, // Whether to use hardware acceleration
34 | className: 'spinner', // The CSS class to assign to the spinner
35 | zIndex: 2e9, // The z-index (defaults to 2000000000)
36 | top: '50%', // Top position relative to parent
37 | left: '50%' // Left position relative to parent
38 | };
39 |
40 | var OverlayLoader = function(elementId,options){
41 | options = options || {};
42 | var options = _.extend(_defaults,options) ;
43 | this.spinner = new Spinner(options).spin(document.getElementById(elementId));
44 | };
45 |
46 | OverlayLoader.prototype.stopOverlay = function(){
47 | this.spinner.stop();
48 | };
49 |
50 | var Overlay = function(elementId, options){
51 | if(typeof elementId !== 'undefined'){
52 | var overlay = new OverlayLoader(elementId, options);
53 | return overlay;
54 | }
55 | return null;
56 |
57 | };
58 |
59 | return Overlay;
60 | });
61 |
--------------------------------------------------------------------------------
/static/js/helper/sessionmanager.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 |
7 | define(["jquery","config/app-config"],function($,AppConfig){
8 | var SessionManager = {
9 | putItemIntoSession : function(key, value) {
10 | try{
11 | sessionStorage.setItem(key,value);
12 | return value;
13 | } catch(e){
14 | alert('Your web browser does not support storing settings locally. In Safari, the most common cause of this is using "Private Browsing Mode". Some settings may not save or some features may not work properly for you.');
15 | }
16 | },
17 |
18 | getItemFromSession : function(key) {
19 | return sessionStorage.getItem(key);
20 | },
21 |
22 | removeItemFromSession : function(key) {
23 | var value = localStorage.getItem(key);
24 | if(value !== undefined || value !== null) {
25 | sessionStorage.removeItem(key);
26 | return value;
27 | }
28 | return null;
29 | },
30 |
31 | cleanupLocalUserSession : function(){
32 | this._cleanupusersession_();
33 | },
34 |
35 | _cleanupusersession_ : function(){
36 | this.removeItemFromSession(AppConfig.sessionKeys.username);
37 | this.removeItemFromSession(AppConfig.sessionKeys.isSecurityEnable);
38 | this.removeItemFromSession(AppConfig.sessionKeys.userClusterId);
39 | }
40 | }
41 |
42 | return SessionManager;
43 | });
--------------------------------------------------------------------------------
/static/js/helper/usermanager.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["jquery","helper/servicemanager","helper/notification","config/app-config","helper/AjaxManager"],
7 | function($,ServiceManager,Notification,AppConfig,AjaxManager){
8 |
9 | var usermanager = {
10 | showUserHomePage : function(){
11 | var scm = ServiceManager.serviceComponentMap;
12 | var seedNode = window.AMCGLOBALS.persistent.seedNode;
13 | if(ServiceManager.isUserHasAccessToService(scm.DASHBOARD_PAGE.SERVICE_KEY)){
14 | window.location.hash = "dashboard/" + (seedNode !== null ? seedNode :"");
15 | } else if(ServiceManager.isUserHasAccessToService(scm.STATISTIC_PAGE.SERVICE_KEY)){
16 | window.location.hash = "statistics/" + (seedNode !== null ? seedNode :"");
17 | } else if(ServiceManager.isUserHasAccessToService(scm.DEFINITION_PAGE.SERVICE_KEY)){
18 | window.location.hash = "definitions/" + (seedNode !== null ? seedNode :"");
19 | } else if(ServiceManager.isUserHasAccessToService(scm.JOBS_PAGE.SERVICE_KEY)){
20 | window.location.hash = "jobs/" + (seedNode !== null ? seedNode :"");
21 | } else if(ServiceManager.isUserHasAccessToService(scm.LATENCY_PAGE.SERVICE_KEY)){
22 | window.location.hash = "latency/" + (seedNode !== null ? seedNode :"");
23 | } else if(ServiceManager.isUserHasAccessToService(scm.MANAGE_PAGE.SERVICE_KEY)){
24 | window.location.hash = "admin-console/" + (seedNode !== null ? seedNode :"");
25 | } else {
26 | Notification.toastNotification("red","You don't have access to any module",false,true);
27 | }
28 | },
29 |
30 | getUserHomePageByRoles : function(roles){
31 | var url = window.location.protocol + "//"+window.location.host;
32 | if(roles.length === 1 && roles.indexOf("user-admin") !== -1){
33 | return url + "/#admin-console";
34 | } else {
35 | return url + "/#dashboard";
36 | }
37 | },
38 |
39 | getDefaultActivePageByRoles : function(roles){
40 | if(roles.length === 1 && roles.indexOf("user-admin") !== -1){
41 | return "admin-console";
42 | } else {
43 | return "dashboard";
44 | }
45 | },
46 |
47 | /*
48 | * This method will fetch all currently monitoring cluster information in current session
49 | */
50 | getCurrentMonitoringCluster : function(successCallback,failureCallback,isSynchronous){
51 | if(isSynchronous == null || (typeof isSynchronous === "undefined")) {
52 | isSynchronous = false;
53 | }
54 | AjaxManager.sendRequest(AppConfig.urls.GET_CURRENT_MONITORING_CLUSTESR, {async:isSynchronous}, successCallback,failureCallback);
55 | }
56 | };
57 | return usermanager;
58 | });
--------------------------------------------------------------------------------
/static/js/libs/backbone/backbone.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 |
21 | define(["jquery", "underscore", 'libs/backbone/backbone-min'], function($, _){
22 | $.noConflict();
23 | return Backbone.noConflict();
24 | });
--------------------------------------------------------------------------------
/static/js/libs/spin/spin.min.js:
--------------------------------------------------------------------------------
1 | //fgnass.github.com/spin.js#v2.0.1
2 | /**
3 | * Copyright (c) 2011-2014 Felix Gnass
4 | * Licensed under the MIT license
5 | */
6 | !function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Spinner=b()}(this,function(){"use strict";function a(a,b){var c,d=document.createElement(a||"div");for(c in b)d[c]=b[c];return d}function b(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return l[e]||(m.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",m.cssRules.length),l[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d',c)}m.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.width,left:d.radius,top:-d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.length+d.width,k=2*j,l=2*-(d.width+d.length)+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;k" + (response.get('address')) + " cannot be monitored here as it belongs to a different cluster");
54 | }
55 | var row = response.rowView;
56 | row.render(response, response.attributes);
57 | }catch(e){
58 | console.info(e.toString());
59 | }
60 |
61 | if(this.clusterID !== window.AMCGLOBALS.persistent.clusterID){
62 | this.clusterID = window.AMCGLOBALS.persistent.clusterID;
63 | }
64 |
65 | if(typeof response.attributes.error !== 'undefined' && response.attributes.error.indexOf("Invalid cluster id") != -1){
66 | delete response.attributes.error;
67 | Util.clusterIDReset();
68 | }
69 | },
70 | fetchError: function(response){
71 | if(response.CID !== window.AMCGLOBALS.currentCID){
72 | response.destroy(); return;
73 | }
74 | try{
75 | var row = response.rowView;
76 | row.renderNetworkError(response);
77 | }catch(e){
78 | console.info(e.toString());
79 | }
80 |
81 | }
82 |
83 |
84 | });
85 |
86 | return NodeModel;
87 | });
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/static/js/models/dashboard/xdrmodel.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["underscore", "backbone", "poller", "config/app-config", "helper/util"], function(_, Backbone, Poller, AppConfig, Util){
7 | var XdrModel = Backbone.Model.extend({
8 | idAttribute : "address",
9 |
10 | initVariables :function(){
11 | this.totalNodes = +this.get("total_nodes");
12 | this.address = this.get("address");
13 | this.clusterID = window.AMCGLOBALS.persistent.clusterID;
14 | },
15 | initialize :function(){
16 | this.CID = window.AMCGLOBALS.currentCID;
17 | try{
18 | this.initVariables();
19 | this.startEventListeners();
20 | }catch(e){
21 | console.info(e.toString());
22 | }
23 |
24 | },
25 |
26 | startEventListeners : function (){
27 | var that = this;
28 | },
29 |
30 | fetchSuccess: function(response){
31 | if(response.CID !== window.AMCGLOBALS.currentCID){
32 | response.destroy(); return;
33 | }
34 |
35 | try{
36 | if(typeof(response.attributes["error"]) !== "undefined")
37 | return;
38 | var row = response.rowView;
39 | row.render(response, response.attributes);
40 | }catch(e){
41 | console.info(e);
42 | }
43 |
44 | if(this.clusterID !== window.AMCGLOBALS.persistent.clusterID){
45 | this.clusterID = window.AMCGLOBALS.persistent.clusterID;
46 |
47 | }
48 |
49 | if(typeof response.attributes.error !== 'undefined' && response.attributes.error.indexOf("Invalid cluster id") != -1){
50 | delete response.attributes.error;
51 | Util.clusterIDReset();
52 | }
53 | },
54 | fetchError: function(response){
55 | if(response.CID !== window.AMCGLOBALS.currentCID){
56 | response.destroy(); return;
57 | }
58 | try{
59 | var row = response.rowView;
60 | row.renderNetworkError(response);
61 | }catch(e){
62 | console.info(e.toString());
63 | }
64 | }
65 | });
66 |
67 | return XdrModel;
68 | });
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/static/js/models/definitions/xdrmodel.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["underscore", "backbone", "poller", "views/definitions/sindexview", "helper/definitions/sindex-table", "config/app-config", "helper/util"], function(_, Backbone, Poller, SIndexView, SIndexTable, AppConfig, Util){
21 | var SIndexModel = Backbone.Model.extend({
22 | initialize: function(){
23 | this.CID = window.AMCGLOBALS.currentCID;
24 | this.initVariables();
25 | this.startEventListeners(this);
26 | },
27 | initVariables: function(){
28 | this.clusterID = window.AMCGLOBALS.persistent.clusterID;//this.get("cluster_id");
29 | this.isInitialized = false;
30 | this.views = {};
31 | this.indexListFull = {};
32 | var tableWidth = ($(".table-container.box-container").width() - 70);
33 | SIndexTable.initGrid($(AppConfig.sindex.tableDiv), AppConfig.secondaryIndexDefList, AppConfig.secondaryIndexDefListColumn, tableWidth);
34 | },
35 | url: function(){
36 | return AppConfig.baseUrl + window.AMCGLOBALS.persistent.clusterID/*this.clusterID*/ + '/namespaces/' + window.AMCGLOBALS.persistent.namespaceName + '/sindexes';
37 | },
38 | fetchSuccess: function(response){
39 | if(response.CID !== window.AMCGLOBALS.currentCID){
40 | response.destroy(); return;
41 | }
42 |
43 | if(!this.model.isInitialized){
44 | this.model.initSIndexView(response);
45 | this.model.isInitialized = true;
46 | }else{
47 |
48 | }
49 | this.stop();
50 |
51 | if(this.clusterID !== window.AMCGLOBALS.persistent.clusterID){
52 | this.clusterID = window.AMCGLOBALS.persistent.clusterID;
53 |
54 | }
55 |
56 | if(typeof response.attributes.error !== 'undefined' && response.attributes.error.indexOf("Invalid cluster id") != -1){
57 | delete response.attributes.error;
58 | Util.clusterIDReset();
59 | }
60 | },
61 |
62 | startEventListeners : function (){
63 | var that = this;
64 | function viewDestroy(){
65 | $(document).off("view:Destroy", viewDestroy);
66 | that.destroy();
67 | };
68 |
69 | $(document).off("view:Destroy", viewDestroy).on("view:Destroy", viewDestroy);
70 | },
71 |
72 | initSIndexView: function(model){
73 | var modelData = model.attributes;
74 | var indexData = modelData.indexes;
75 | model.indexList = _.pluck(indexData, 'indexname');
76 |
77 | for(var i in model.indexList){
78 | for(var j in indexData){
79 | if(indexData[j].indexname === model.indexList[i]){
80 | model.indexListFull[model.indexList[i]] = indexData[j];
81 | break;
82 | }
83 | }
84 | }
85 |
86 | for(var index in model.indexListFull){
87 | model.views[index] = new SIndexView({tableDiv:AppConfig.sindex.tableDiv,indexName:index ,model: this});
88 | model.views[index].render(model, model.indexListFull[index], index);
89 |
90 | }
91 |
92 | },
93 | fetchError: function(response){
94 | if(response.CID !== window.AMCGLOBALS.currentCID){
95 | response.destroy(); return;
96 | }
97 |
98 | var that = this;
99 | try{
100 | //DISPLAY ERROR
101 | }catch(e){
102 | console.info(e.toString());
103 | }
104 | },
105 |
106 |
107 |
108 | });
109 |
110 | return SIndexModel;
111 | });
112 |
--------------------------------------------------------------------------------
/static/js/setup.js:
--------------------------------------------------------------------------------
1 | require.config({
2 | paths: {
3 | //Libraries
4 | jquery: "libs/jquery/consolidated-jquery-functionalities.min",
5 | underscore: "libs/underscore/underscore",
6 | backbone: "libs/backbone/backbone",
7 | poller: "libs/backbone/backbone.poller",
8 | d3: "libs/d3/d3",
9 | d3Layout: "libs/d3/d3.layout.min",
10 | timechart: "libs/timechart/timechart",
11 | },
12 | shim: {
13 | 'backbone': {
14 | deps: ['underscore', 'jquery'],
15 | }
16 | }
17 | });
18 |
19 | require(["onepage"],function(onepage){
20 | onepage();
21 | });
22 |
--------------------------------------------------------------------------------
/static/js/views/common/AlertEmailsView.js:
--------------------------------------------------------------------------------
1 | define(['jquery', 'underscore', 'backbone', 'helper/notification', 'helper/modal'],
2 | function($, _, Backbone, Notification, modal) {
3 | function validateEmail(email) {
4 | // see http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
5 | var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
6 | return re.test(email);
7 | }
8 |
9 | var TOAST_TIMEOUT = 3*1000;
10 |
11 | var AlertEmailsView = Backbone.View.extend({
12 | initialize: function() {
13 | _.bindAll(this, 'addEmail', 'removeEmail', 'render');
14 | this.listenTo(this.model, 'change', this.render, this);
15 | },
16 |
17 | render: function() {
18 | var emails = this.model.attributes.emails;
19 | var tmpl = this.template(emails);
20 | this.$el.html(tmpl);
21 | return this;
22 | },
23 |
24 | events: {
25 | 'click li .icon-cancel-circle': 'removeEmail',
26 | 'click button': 'addEmail',
27 | },
28 |
29 | removeEmail: function(evt) {
30 | var that = this;
31 | var email = evt.target.parentElement.innerText;
32 | var emails = [email];
33 | var content = 'Remove email: ' + email + ' from receving alerts';
34 |
35 | modal.confirmModal('Remove Email', content, success);
36 | return;
37 |
38 | function success() {
39 | that.model.remove(emails,
40 | function success() {
41 | Notification.toastNotification('green', 'Email: ' + email + ' removed successfully', TOAST_TIMEOUT);
42 | },
43 | function failure() {
44 | Notification.toastNotification('red', 'Unable to remove email: ' + email, TOAST_TIMEOUT);
45 | }
46 | );
47 | }
48 | },
49 |
50 | addEmail: function() {
51 | var that = this;
52 | var input = this.$('form input[name=email]');
53 | var email = input.val();
54 | var valid = validateEmail(email);
55 | var err = this.$('.err-text');
56 | if(!valid) {
57 | err.show();
58 | window.setTimeout(function() {
59 | err.hide();
60 | }, 2000);
61 | return;
62 | }
63 | err.hide();
64 |
65 | var content = 'Add email: ' + email + ' to receive alerts';
66 | modal.confirmModal('Add Email', content, success);
67 | return;
68 |
69 | function success() {
70 | input.val('');
71 | that.model.add([email],
72 | function success() {
73 | Notification.toastNotification('green', 'Email: ' + email + ' added successfully', TOAST_TIMEOUT);
74 | },
75 | function failure() {
76 | Notification.toastNotification('red', 'Unable to add email: ' + email, TOAST_TIMEOUT);
77 | }
78 | );
79 | }
80 | },
81 |
82 | template: function(emails) {
83 | var tmpl = '';
95 |
96 | tmpl += '';
101 | return tmpl;
102 | },
103 | });
104 |
105 | return AlertEmailsView;
106 | });
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/static/js/views/configs/statview.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | *Copyright 2008-2014 by Aerospike, Inc. All rights reserved.
3 | *THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
4 | *ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
5 | ******************************************************************************/
6 | define(["jquery", "underscore", "backbone", "helper/edit-config", "helper/jqgrid-helper", "config/view-config", "config/app-config" ], function($, _, Backbone, StatTable, GridHelper, ViewConfig, AppConfig){
7 |
8 | var StatView = Backbone.View.extend({
9 | initialize: function( options ){
10 | this.el = options.el;
11 | },
12 |
13 | lazyRender: function(event){
14 | event.data.model.colView.render(event.data.model);
15 | },
16 |
17 | render: function(model){
18 | if( !window.AMCGLOBALS.pageSpecific.configGridSet )
19 | StatTable.startInitGrid([]);
20 |
21 | window.AMCGLOBALS.pageSpecific.configGridSet = true;
22 |
23 | if( this.attrList == null ){
24 | switch(model.modelType){
25 | case "nodes" :
26 | this.attrList = "nodeConfigList"; break;
27 | case "namespace" :
28 | this.attrList = "namespaceConfigList"; break;
29 | case "xdr" :
30 | this.attrList = "xdrConfigList"; break;
31 | }
32 |
33 | window.AMCGLOBALS.pageSpecific.lazyRender = window.AMCGLOBALS.pageSpecific.lazyRender || [];
34 | window.AMCGLOBALS.pageSpecific.lazyRendered = window.AMCGLOBALS.pageSpecific.lazyRendered || [];
35 | window.AMCGLOBALS.pageSpecific.statListGenerated = ! _.isEmpty( AppConfig[this.attrList] );
36 |
37 | if(!window.AMCGLOBALS.pageSpecific.statListGenerated && model['attributes'].node_status === "on" && (model.modelType !== "xdr" || model['attributes'].xdr_status === "on") ){
38 | window.AMCGLOBALS.pageSpecific.statListGenerated = true;
39 | AppConfig[this.attrList] = _.keys(model['attributes']);
40 | }
41 |
42 | model.statList = AppConfig[this.attrList];
43 | if( _.isEmpty( $('#statListTable').jqGrid('getGridParam','data') ) && window.AMCGLOBALS.pageSpecific.statListGenerated ){
44 | StatTable.initAndSetGridData(AppConfig[this.attrList], model.modelType);
45 | window.$(AppConfig.stat.statTableDiv).trigger("renderall", [window.AMCGLOBALS.pageSpecific.lazyRender]);
46 | }
47 | }
48 |
49 | if( !_.isEmpty( _.difference( window.AMCGLOBALS.persistent.selectedNodes, window.AMCGLOBALS.pageSpecific.lazyRender) ) && !window.AMCGLOBALS.pageSpecific.statListGenerated && (model['attributes'].node_status === "off" || model['attributes'].xdr_status === "off") ){
50 | window.AMCGLOBALS.pageSpecific.lazyRender.push(model.address);
51 |
52 | if( _.isEmpty( _.difference( window.AMCGLOBALS.persistent.selectedNodes, window.AMCGLOBALS.pageSpecific.lazyRender) ) )
53 | window.$(AppConfig.stat.statTableDiv).trigger("renderall", [window.AMCGLOBALS.pageSpecific.lazyRender]);
54 | } else{
55 |
56 | window.AMCGLOBALS.pageSpecific.lazyRendered.push(model.address);
57 |
58 | if( _.isEmpty( _.difference( window.AMCGLOBALS.pageSpecific.lazyRender, window.AMCGLOBALS.pageSpecific.lazyRendered) ) ){
59 | window.AMCGLOBALS.pageSpecific.lazyRender = [];
60 | window.AMCGLOBALS.pageSpecific.lazyRendered = [];
61 | }
62 |
63 | Util.checkVisibilityAndCall(this, function(){
64 | if(model['attributes']['node_status'] === "off"){
65 | StatTable.updateRowData(model.statTableID, model.modelType, model.statList, model.address, model['attributes'], 'Node Down');
66 | }else{
67 | StatTable.updateRowData(model.statTableID, model.modelType, model.statList, model.address, model['attributes']);
68 | }
69 | }, "horizontal", "#nodeStatListGrid .ui-jqgrid-bdiv");
70 |
71 | }
72 | },
73 | renderNetworkError: function(model){
74 | StatTable.updateRowData(model.statTableID, model.modelType, model.statList, model.address, model['attributes'], 'N/E');
75 | },
76 |
77 |
78 | });
79 |
80 | return StatView;
81 | });
82 |
--------------------------------------------------------------------------------
/static/js/views/dashboard/pieview.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "d3", "helper/drilldown-charts", "config/view-config", "helper/util"], function($, _, Backbone, D3, PieChart, ViewConfig, Util){
21 | var ClusterView = Backbone.View.extend({
22 | pieChartHolder: null,
23 | initialize: function(){
24 | this.el = this.options.el;
25 | },
26 | render: function(data){
27 | var pieChartData = this.getRelationshipArray(data);
28 | try{
29 | if( !isNaN(data.used) && !isNaN(data.free)){
30 | if(!this.pieChartHolder){
31 | $(this.el+' .pie_chart').empty();
32 | this.pieChartHolder = new healthChart(this.el+' .pie_chart', 150, 150, 20, true);
33 | }
34 | this.pieChartHolder.updatePieData(pieChartData);
35 | }else{
36 | //Display Error
37 | }
38 | }catch(e){
39 | if(!this.pieChartHolder){
40 | this.pieChartHolder = new healthChart(this.el+' .pie_chart', 150, 150, 20, true);
41 | }
42 | this.pieChartHolder.updatePieData(pieChartData);
43 | console.info(e.toString());
44 | }
45 |
46 | },
47 | getRelationshipArray : function(data){
48 | var parent = [];
49 | parent.push({name : "totalFree", title : "Total Free", value : data.free, color : "#999", children : []});
50 | parent.push({name : "totalUsed", title : "Total Used", value : data.used, color : "#0e90d2", children : []});
51 |
52 | for(var node in data.details){
53 | parent[0].children.push({value : data.details[node].free, title : node, color : window.AMCGLOBALS.persistent.nodesColorList[node], name : "free[" + node + "]"});
54 | parent[1].children.push({value : data.details[node].used, title : node, color : window.AMCGLOBALS.persistent.nodesColorList[node], name : "used[" + node + "]"});
55 | }
56 |
57 | return parent;
58 | }
59 | });
60 |
61 | return ClusterView;
62 | });
--------------------------------------------------------------------------------
/static/js/views/dashboard/throughputview.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "d3", "timechart", "helper/timechart-helper", "config/view-config", "config/app-config"], function($, _, Backbone, D3, TimeChart, TimeseriesChart, ViewConfig, AppConfig){
21 | var ThroughputView = Backbone.View.extend({
22 | initialize: function(){
23 | this.el = this.options.el;
24 | this.chartDiv = this.options.chartDiv;
25 | this.legendDiv = this.options.legendDiv;
26 | this.xAxisDiv = this.options.xAxisDiv;
27 | this.slider = this.options.slider;
28 | this.tpsDiv = this.options.tpsDiv;
29 | this.chartType = this.options.chartType;
30 | this.chartID = null;
31 |
32 | },
33 | render: function(newData, oldData, numberOfDataPoints){
34 | if(newData !== null && Object.getOwnPropertyNames(newData).length > 0)
35 | TimeseriesChart.updateTimeseriesData(newData, oldData, this.chartID, this.legendDiv);
36 | if(!this.chartID){
37 | this.chartID = TimeseriesChart.initTimeSeriesChart(AMCGLOBALS.pageSpecific.charts[ this.chartType + "ChartType"], this.chartDiv, this.legendDiv, this.xAxisDiv, this.slider, ViewConfig.throughputChartConfig, oldData, numberOfDataPoints);
38 | }else{
39 | Util.checkVisibilityAndCall(this, function(){
40 | TimeseriesChart.updateTimeSeriesChart(this.chartID, oldData, this.legendDiv, numberOfDataPoints);
41 | TimeseriesChart.updateTPS(this.tpsDiv, oldData, this.chartType);
42 | });
43 | }
44 | },
45 |
46 | initializeTPS: function(history){
47 | TimeseriesChart.initTPS(history, this.tpsDiv);
48 | },
49 |
50 | remove: function(){
51 | if(this.chartID){
52 | this.chartID.remove();
53 | }
54 | }
55 | });
56 |
57 | return ThroughputView;
58 | });
59 |
--------------------------------------------------------------------------------
/static/js/views/definitions/setsview.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/definitions/sindex-table", "helper/jqgrid-helper", "config/view-config", "config/app-config" ], function($, _, Backbone, SIndexTable, GridHelper, ViewConfig, AppConfig){
21 |
22 | var SetsView = Backbone.View.extend({
23 | initialize: function(){
24 | this.tableDiv = this.options.tableDiv;
25 | this.indexName = this.options.indexName;
26 | },
27 | render: function(model, newData, rowID){
28 | newData = this.formatRowData(newData, rowID);
29 | SIndexTable.updateRowData(this.tableDiv, newData, rowID);
30 |
31 | },
32 | renderNetworkError: function(model, newData, rowID){
33 | SIndexTable.updateRowData(this.tableDiv, newData, rowID);
34 | },
35 | formatRowData: function(newData, rowID){
36 | if(newData['sync_state'] !== 'synced'){
37 | newData['sync_state'] = 'YES';
38 | }else{
39 | var synButtonID = 'sIndexTable_'+rowID;
40 | newData['sync_state'] = 'NO
'
41 | //ADD EVENT LISTENER 'NO'
42 | $('#'+synButtonID).click(function(e){
43 | $("#syncedDialog").dialog({
44 | dialogClass: 'sync-dialog'
45 | });
46 | });
47 | }
48 | if(typeof newData['enable-xdr'] === 'undefined'){
49 | newData['enable-xdr'] = 'Not Supported';
50 | }
51 |
52 | return newData;
53 | },
54 |
55 | });
56 |
57 | return SetsView;
58 | });
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/static/js/views/definitions/xdrview.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/definitions/sindex-table", "helper/jqgrid-helper", "config/view-config", "config/app-config" ], function($, _, Backbone, SIndexTable, GridHelper, ViewConfig, AppConfig){
21 |
22 | var SIndexView = Backbone.View.extend({
23 | initialize: function(){
24 | this.tableDiv = this.options.tableDiv;
25 | this.indexName = this.options.indexName;
26 | },
27 | render: function(model, newData, rowID){
28 | newData = this.formatRowData(newData, rowID);
29 | SIndexTable.updateRowData(this.tableDiv, newData, rowID);
30 |
31 | },
32 | renderNetworkError: function(model){
33 | },
34 | formatRowData: function(newData, rowID){
35 | if(newData['sync_state'] !== 'synced'){
36 | newData['sync_state'] = 'YES';
37 | }else{
38 | var synButtonID = 'sIndexTable_'+rowID;
39 | newData['sync_state'] = 'NO
'
40 | //ADD EVENT LISTENER 'NO'
41 | $('#'+synButtonID).click(function(e){
42 | $("#syncedDialog").dialog({
43 | dialogClass: 'sync-dialog'
44 | });
45 | });
46 | }
47 |
48 | return newData;
49 | },
50 |
51 | });
52 |
53 | return SIndexView;
54 | });
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/static/js/views/jobs/nodeview.js:
--------------------------------------------------------------------------------
1 | /******************************************************************************
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. See the NOTICE file
4 | distributed with this work for additional information
5 | regarding copyright ownership. The ASF licenses this file
6 | to you under the Apache License, Version 2.0 (the
7 | "License"); you may not use this file except in compliance
8 | with the License. You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing,
13 | software distributed under the License is distributed on an
14 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | KIND, either express or implied. See the License for the
16 | specific language governing permissions and limitations
17 | under the License.
18 | ******************************************************************************/
19 |
20 | define(["jquery", "underscore", "backbone", "helper/job-table", "helper/jqgrid-helper", "config/view-config", "config/app-config" ], function($, _, Backbone, JobTable, GridHelper, ViewConfig, AppConfig){
21 |
22 | var NodeView = Backbone.View.extend({
23 | isInitialized: false,
24 | initialize: function(){
25 | this.rowID = this.options.rowID;
26 | this.modelID = this.options.modelID;
27 | this.jobID = this.options.jobID;
28 | },
29 | removeRow: function(){
30 | var selRow = $('#'+this.rowID),
31 | nextRow = selRow.next();
32 |
33 | if (nextRow.hasClass('ui-subgrid')) {
34 | nextRow.remove();
35 | }
36 |
37 | $(AppConfig.node.nodeTableDiv).delRowData(this.rowID);
38 | $(AppConfig.job.nodeTableCompletedJobsDiv).delRowData(this.rowID);
39 |
40 | var jobs = $("#nodeListTable tr").not(".jqgfirstrow");
41 | var completedJobs = $("#nodeListTableCompletedJobs tr").not(".jqgfirstrow");
42 |
43 | if( jobs.length === 0 ){
44 | $("#nodeListTable").addClass("no-jobs");
45 | }
46 |
47 | if( completedJobs.length === 0 ){
48 | $("#nodeListTable").addClass("no-jobs");
49 | }
50 |
51 | this.remove();
52 | },
53 | render: function(container, job, model){
54 | this.createJobListRow(container, job, this.rowID, this.jobID, model, false);
55 | },
56 | renderNetworkError: function(container, job, model){
57 | this.createJobListRow(container, job, this.rowID, this.jobID, model, true);
58 | },
59 | createJobListRow: function(container, data, rowID, jobID, model, isError){
60 | $(container).removeClass("no-jobs");
61 | JobTable.createOrUpdateRow(container, data, rowID, model, isError);
62 | JobTable.updateRow(container, data, rowID);
63 | if(!isError){
64 | window.setTimeout(function() {
65 | data['mem_pie_chart'] = GridHelper.jqCustomPieFormatter(null, container, rowID, ViewConfig.tablePieConfig, data['mem_arr'], 5);
66 | }, 200);
67 | }
68 |
69 | if(model.subGridEnabled[rowID] === true){
70 | var expandContainer = container.substr(1)+'_'+ rowID;
71 | var tableHtmlStr = "";
72 | if(Util.versionCompare(data.build,"3.6.0") >= 0){
73 | tableHtmlStr = GridHelper.create2LevelTable("job","nodeExpanded_"+ rowID, "expandDynamic", data);
74 | }else{
75 | tableHtmlStr = GridHelper.create2LevelTable("jobOldVersion","nodeExpanded_"+ rowID, "expandDynamic", data);
76 | }
77 | $("#" + expandContainer).html(tableHtmlStr);
78 | }
79 | }
80 |
81 |
82 | });
83 |
84 | return NodeView;
85 | });
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/tools/load/main/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "sync"
6 |
7 | "github.com/aerospike-community/amc/tools/load"
8 | )
9 |
10 | const nconn = 10 // connections per cluster
11 |
12 | func main() {
13 |
14 | // base url of the AMC server
15 | load.BaseURL = "http://localhost:8082/aerospike/service/clusters/"
16 |
17 | // instances of the aerospike clusters
18 | var clients []load.Client = []load.Client{
19 | {IP: "172.17.0.2", Port: "3000"},
20 | {IP: "172.17.0.5", Port: "7000", Username: "all", Password: "all"},
21 | {IP: "192.168.121.116", Port: "3000", Username: "admin", Password: "admin"},
22 | {IP: "192.168.121.116", Port: "3000", Username: "subadmin", Password: "subadmin"},
23 | }
24 |
25 | var wg sync.WaitGroup
26 | for i := 0; i < len(clients); i++ {
27 | cc := clients[i]
28 | for j := 0; j < nconn; j++ {
29 | c := load.Client{
30 | IP: cc.IP,
31 | Port: cc.Port,
32 | Username: cc.Username,
33 | Password: cc.Password,
34 | TLSName: cc.TLSName,
35 | }
36 | err := c.Connect()
37 | if err != nil {
38 | log.Println(err.Error())
39 | break
40 | }
41 | c.Start(&wg)
42 | }
43 | }
44 |
45 | wg.Wait()
46 | }
47 |
--------------------------------------------------------------------------------
/tools/load/response/types.go:
--------------------------------------------------------------------------------
1 | package response
2 |
3 | // Basic type struct
4 | type Basic struct {
5 | Nodes []string
6 | Namespaces []string
7 | }
8 |
9 | // Connect type struct
10 | type Connect struct {
11 | ClusterID string `json:"cluster_id"`
12 | Status string
13 | }
14 |
--------------------------------------------------------------------------------