UNPKG

4.9 kBJavaScriptView Raw
1'use strict';
2
3const BbPromise = require('bluebird');
4const chalk = require('chalk');
5
6class OpenWhiskInfo {
7 constructor(serverless, options) {
8 this.serverless = serverless;
9 this.options = options || {};
10 this.provider = this.serverless.getProvider('openwhisk');
11
12 this.hooks = {
13 'info:info': () => BbPromise.bind(this)
14 .then(this.validate)
15 .then(this.info),
16 'after:deploy:deploy': () => BbPromise.bind(this)
17 .then(() => {
18 if (this.options.noDeploy) {
19 return BbPromise.resolve();
20 }
21 this.consoleLog('');
22 this.failsafe = true;
23 return BbPromise.bind(this)
24 .then(this.validate)
25 .then(this.info)
26 })
27 };
28 }
29
30 validate() {
31 if (!this.serverless.config.servicePath) {
32 throw new this.serverless.classes.Error('This command can only be run inside a service.');
33 }
34
35 return this.provider.props().then(props => {
36 this.props = props;
37 return this.provider.client();
38 }).then(client => {
39 this.client = client;
40 })
41 }
42
43 info () {
44 this.consoleLog(`${chalk.yellow.underline('Service Information')}`);
45
46 return BbPromise.bind(this)
47 .then(this.showServiceInfo)
48 .then(this.showActionsInfo)
49 .then(this.showTriggersInfo)
50 .then(this.showRulesInfo)
51 .then(this.showRoutesInfo)
52 .then(this.showWebActionsInfo);
53 }
54
55 showServiceInfo () {
56 this.consoleLog(`platform:\t${this.props.apihost}`);
57 this.consoleLog(`namespace:\t${this.props.namespace || '_'}`);
58 this.consoleLog(`service:\t${this.serverless.service.service}\n`);
59 }
60
61 showActionsInfo () {
62 this.consoleLog(`${chalk.yellow('actions:')}`);
63 return this.client.actions.list().then(actions => {
64 this._actions = actions;
65 if (!actions.length) return console.log('**no actions deployed**\n');
66 const names = actions.map(action => action.name).join(' ');
67 this.consoleLog(names + '\n')
68 })
69 }
70
71 showWebActionsInfo () {
72 this.consoleLog(`${chalk.yellow('endpoints (web actions):')}`);
73 const web_actions = this._actions.filter(action => {
74 const annotations = action.annotations || []
75 return annotations.some(a => a.key === 'web-export' && a.value === true)
76 })
77 if (!web_actions.length) {
78 this.consoleLog('**no web actions deployed**\n');
79 return Promise.resolve();
80 }
81
82 return this.provider.props().then(props => {
83 web_actions.forEach(action => {
84 this.consoleLog(`https://${props.apihost}/api/v1/web/${action.namespace}/default/${action.name}`)
85 })
86 })
87 }
88
89 showTriggersInfo () {
90 this.consoleLog(`${chalk.yellow('triggers:')}`);
91 return this.client.triggers.list().then(triggers => {
92 if (!triggers.length) return console.log('**no triggers deployed**\n');
93 const names = triggers.map(trigger => trigger.name).join(' ');
94 this.consoleLog(names + '\n')
95 })
96 }
97
98 showRulesInfo () {
99 this.consoleLog(`${chalk.yellow('rules:')}`);
100 return this.client.rules.list().then(rules => {
101 if (!rules.length) return console.log('**no rules deployed**\n');
102 const names = rules.map(rule => rule.name).join(' ');
103 this.consoleLog(names + '\n')
104 })
105 }
106
107 showRoutesInfo () {
108 this.consoleLog(`${chalk.yellow('endpoints (api-gw):')}`)
109 let operation = this.client.routes.list().then(routes => {
110 if (!routes.apis.length) return console.log('**no routes deployed**\n')
111 routes.apis.forEach(api => this.logApiEndPoints(api.value))
112 this.consoleLog('')
113 })
114
115 operation = operation.catch(err => {
116 this.consoleLog(`${chalk.red('**failed to fetch routes**')}`)
117 if(err.message.match(/status code 400/) && err.message.match(/expired/)) {
118 this.consoleLog(`${chalk.red('**api gateway key is wrong or has expired! if it has expired, please refresh with wsk bluemix login**\n')}`)
119 }
120
121 if (!this.failsafe) throw err
122 })
123
124 return operation
125 }
126
127 logEndPoint (baseUrl, path, method, actionName) {
128 if (!path.startsWith('/')) {
129 path = `/${path}`
130 }
131 this.consoleLog(`${method.toUpperCase()} ${baseUrl}${path} --> ${actionName}`)
132 }
133
134 logApiEndPoints (api) {
135 const paths = api.apidoc.paths
136 Object.keys(paths).forEach(path => {
137 const methods = Object.keys(paths[path])
138 methods.forEach(method => {
139 const operation = paths[path][method]
140 let actionName = 'unknown'
141 if (operation.hasOwnProperty('x-openwhisk')) {
142 actionName = operation['x-openwhisk'].action;
143 } else if (operation.hasOwnProperty('x-ibm-op-ext')) {
144 actionName = operation['x-ibm-op-ext'].actionName;
145 }
146 this.logEndPoint(api.gwApiUrl, path, method, actionName)
147 })
148 })
149 }
150
151 consoleLog (message) {
152 console.log(message)
153 }
154}
155
156module.exports = OpenWhiskInfo;