From 2befb5b8d27145aca5213adafd05b928738804b8 Mon Sep 17 00:00:00 2001 From: LiorSho Date: Thu, 25 Mar 2021 11:49:03 +0200 Subject: [PATCH 1/3] test1 --- amazon-alexa-skill-nutanix/getCluster copy.py | 504 ++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100755 amazon-alexa-skill-nutanix/getCluster copy.py diff --git a/amazon-alexa-skill-nutanix/getCluster copy.py b/amazon-alexa-skill-nutanix/getCluster copy.py new file mode 100755 index 0000000..888ef96 --- /dev/null +++ b/amazon-alexa-skill-nutanix/getCluster copy.py @@ -0,0 +1,504 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +from __future__ import print_function +import argparse +import time +import datetime +import json +import sys +import boto3 +import os +import requests +import logging +import rds_config +import pymysql + +# rds settings +rds_host = '' +name = rds_config.db_username +password = rds_config.db_password +db_name = rds_config.db_name + +# Cluster connection settings +ntnx_clusterIP = '' +ntnx_password = '' +ntnx_username = '' +ntnx_clusterPort = '' +ntnx_nickname = '' + +# Speechlets +NUTANIX = "newtanicks" +INTELNUC = "intel nuck" + +logger = logging.getLogger() +logger.setLevel(logging.INFO) + +API_PRISM = '/PrismGateway/services/rest/v1' +API_PRISM_V2 = "/api/nutanix/v2.0/" + + +def __supress_security(): + # supress security warnings + requests.packages.urllib3.disable_warnings() + + +def __htpp_request(base_url): + # supress security warnings + __supress_security() + + s = requests.Session() + s.auth = (ntnx_username, ntnx_password) + s.headers.update({'Content-Type': 'application/json; charset=utf-8'}) + return json.dumps(s.get(base_url, verify=False).json(), sort_keys=True) + + +def __request_clusters(cluster_ip_address, cluster_port): + base_url = "https://" + cluster_ip_address + ":" + str(cluster_port) + API_PRISM + "/clusters/" + return __htpp_request(base_url) + + +def __request_cluster_hosts(cluster_ip_address, cluster_port): + base_url = "https://" + cluster_ip_address + ":" + str(cluster_port) + API_PRISM + "/hosts/" + return __htpp_request(base_url) + + +def __request_cluster_vms(cluster_ip_address, cluster_port): + base_url = "https://" + cluster_ip_address + ":" + str(cluster_port) + API_PRISM + "/vms/" + return __htpp_request(base_url) + + +def __request_cluster_alerts(cluster_ip_address, cluster_port, type): + # Type must be'warning' or 'critical' + base_url = "https://" + cluster_ip_address + ":" + str(cluster_port) + API_PRISM + "/clusters/alerts?severity=" + type + return __htpp_request(base_url) + + +def __set_rds_host_region(event): + # Define request source and assign correct RDS instance + global rds_host + if event['request']['locale'] == "en-US": + rds_host = "nutanix-beta.cel0uwqzzgpj.us-east-1.rds.amazonaws.com" + elif event['request']['locale'] == "en-GB": + rds_host = "nutanix-beta-eu.cpdl28a97nyk.eu-west-1.rds.amazonaws.com" + + +def __request_userID_data(userId): + + global ntnx_clusterIP + global ntnx_username + global ntnx_password + global ntnx_clusterPort + global ntnx_nickname + + conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5) + cur = conn.cursor() + logger.info("RDS connection sucessfull") + + try: + cur.execute("SELECT * FROM alexa.alexa_beta WHERE alexa_userId = (%s)", (userId)) + data = cur.fetchone() + if data: + ntnx_clusterIP = data[2] + ntnx_username = data[3] + ntnx_password = data[4] + ntnx_nickname = data[5] + ntnx_clusterPort = data[6] + return data + else: + # + # + # Must be changed once only registered clusters are accepted + # + # + logger.error(userId) + userId = "amzn1.ask.account.AGGNJ6WTSGQ5VEWK2J4FAHXPL477LF35VWR6KMIEDMFAVBYZR5CT5GO4U73ZWSEAKONHR3KW7NKUA4GATOTIZB24FP6L4BPD4UVENI23YUSCMOJAWYRWDG6ZDJNIRH4VSENFFXUEO2TJ24EEOF7NXDYR5RH7YDQA7RHIXTKEL7625UZ25YTWMZGWGV26C4PM6G7DYCZNFC7S2AY" + cur.execute("SELECT * FROM alexa.alexa_beta WHERE alexa_userId = (%s)", (userId)) + data = cur.fetchone() + if data: + ntnx_clusterIP = data[2] + ntnx_username = data[3] + ntnx_password = data[4] + ntnx_nickname = 'stranger' + ntnx_clusterPort = data[6] + return data + except Exception as e: + logger.error(e) + return None + finally: + cur.close() + conn.close() + + +def cluster_registration(intent, session): + session_attributes = {} + card_title = "Cluster Registration" + card_content = "Use the URL below to register your Nutanix cluster \n http://myvirtualcloud.net/alexa-skill-for-nutanix-registration-form \n Your Alexa ID for cluster registration is " + session['user']['userId'] + speech_output = '

Please check your Alexa card to retrieve the Alexa user id, and follow the registration instructions.

' + reprompt_text = "" + should_end_session = True + return build_response(session_attributes, build_speechlet_response( + card_title, False, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_internal_error_response(): + session_attributes = {} + card_title = "Internal Error" + card_content = "" + speech_output = '

Sorry, there was an internal error, or the Alexa userid does not have a ' + NUTANIX + ' cluster association

' + reprompt_text = "" + should_end_session = True + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_welcome_response(): + session_attributes = {} + card_title = "Welcome" + card_content = "" + speech_output = '

Hello ' + ntnx_nickname + ', welcome to the unofficial Alexa Skills for ' + NUTANIX + '

' + \ + '

If you need help, say help

' + reprompt_text = '

I didnt hear your request.

' + should_end_session = False + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_help_response(): + session_attributes = {} + card_title = "Help" + card_content = "" + speech_output = '

You may ask for the cluster summary saying, Alexa, ask ' + NUTANIX + ' unofficial for cluster summary,

' + \ + '

or you may ask for a specific property. Alexa, ask ' + NUTANIX + ' unofficial for cluster utilization.

' + \ + '

You may also combine a property and a type. Alexa, ask ' + NUTANIX + ' unofficial for cluster critical alerts.

' + \ + '

You always need to use the invocation name, ' + NUTANIX + ' unofficial.

' + \ + '

If you have not yet registered your ' + NUTANIX + 'cluster, say, Cluster Registration

' + reprompt_text = '

I didnt hear your request.

' + should_end_session = False + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_error_response(): + session_attributes = {} + card_title = "Error" + card_content = "" + speech_output = '

I am sorry, I dont understand your request

' + reprompt_text = "" + should_end_session = True + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def model_error_response(intent, session): + card_title = "CommunityEdition" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + speech_output = '

This cluster is not a ' + NUTANIX + ' community edition.

' \ + '

Only ' + NUTANIX + ' community edition can be managed with Alexa at this point in time

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_model(): + return (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['rackableUnits'][0]['modelName']) + + +def get_name(intent, session): + card_title = "Cluster Name" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + clusterName = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['name']) + speech_output = '

The name of the cluster is ' + clusterName + '

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_memory_utilization(intent, session): + card_title = "Cluster Utilization" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + clusterName = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['name']) + hypervisor_memory_usage_ppm = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['stats']['hypervisor_memory_usage_ppm']) + hypervisor_memory_usage_ppm = int(hypervisor_memory_usage_ppm) / 10000 + speech_output = '

The memory utilization for the cluster ' + clusterName + ' is at ' + str(hypervisor_memory_usage_ppm) + ' percent

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_cpu_utilization(intent, session): + card_title = "CPU Utilization" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + clusterName = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['name']) + hypervisor_cpu_usage_ppm = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['stats']['hypervisor_cpu_usage_ppm']) + hypervisor_cpu_usage_ppm = int(hypervisor_cpu_usage_ppm) / 10000 + speech_output = '

The CPU utilization for the cluster ' + clusterName + ' is at ' + str(hypervisor_cpu_usage_ppm) + ' percent

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_hosts(intent, session): + card_title = "Cluster Hosts" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + totalEntities = (json.loads(__request_cluster_hosts(ntnx_clusterIP, ntnx_clusterPort))['metadata']['totalEntities']) + clusterName = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['name']) + speech_output = '

The total number of hosts for the cluster ' + clusterName + ' is ' + str(totalEntities) + '

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_machines(intent, session): + card_title = "Virtual Machines" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + totalEntities = (json.loads(__request_cluster_vms(ntnx_clusterIP, ntnx_clusterPort))['metadata']['totalEntities']) + clusterName = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['name']) + speech_output = '

There are ' + str(totalEntities) + ' virtual machines in the cluster ' + clusterName + '

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_health(intent, session): + card_title = "Cluster Health" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + operationMode = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['operationMode']) + clusterName = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['name']) + speech_output = '

The health for cluster ' + clusterName + ' is ' + operationMode + '

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_alerts(intent, session): + card_title = "Cluster Alerts" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + + # Check if for alert type + try: + type = intent['slots']['type']['value'] + except Exception: + type = "critical" + + totalEntities = (json.loads(__request_cluster_alerts(ntnx_clusterIP, ntnx_clusterPort, type))['metadata']['totalEntities']) + clusterName = (json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort))['entities'][0]['name']) + speech_output = '

There are ' + str(totalEntities) + ' ' + type + ' alerts in the ' + clusterName + ' cluster

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_summary(intent, session): + card_title = "Cluster Summary" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + + jsonObject = json.loads(__request_clusters(ntnx_clusterIP, ntnx_clusterPort)) + + clusterName = jsonObject['entities'][0]['name'] + operationMode = jsonObject['entities'][0]['operationMode'] + hypervisor_memory_usage_ppm = int(jsonObject['entities'][0]['stats']['hypervisor_memory_usage_ppm']) / 10000 + hypervisor_cpu_usage_ppm = int(jsonObject['entities'][0]['stats']['hypervisor_cpu_usage_ppm']) / 10000 + totalEntitiesHosts = (json.loads(__request_cluster_hosts(ntnx_clusterIP, ntnx_clusterPort))['metadata']['totalEntities']) + totalEntitiesAlerts = (json.loads(__request_cluster_alerts(ntnx_clusterIP, ntnx_clusterPort, "critical"))['metadata']['totalEntities']) + totalEntitiesMachines = (json.loads(__request_cluster_vms(ntnx_clusterIP, ntnx_clusterPort))['metadata']['totalEntities']) + + speech_output = '

Todays health summary for the ' + NUTANIX + ' cluster ' + clusterName + '

' + \ + '

There are ' + str(totalEntitiesHosts) + ' hosts, and ' + str(totalEntitiesMachines) + ', virtual machines in the cluster

' + \ + '

and ' + str(totalEntitiesAlerts) + ' critical alerts

' + \ + '

The overall cluster memory utilization is at ' + str(hypervisor_memory_usage_ppm) + ' percent

' + \ + '

and the overal CPU utilization is at ' + str(hypervisor_cpu_usage_ppm) + ' percent

' + \ + '

The overal cluster health is ' + operationMode + '

' + + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_stop_response(intent, session): + card_title = "Stop" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = True + speech_output = '

Stopping

' + reprompt_text = "" + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def get_cluster_property(intent, session): + card_title = "Cluster Property" + card_content = "" + session_attributes = session.get('attributes', {}) + should_end_session = False + speech_output = '

What property would you like to retrieve?

' + reprompt_text = '

I didnt hear your request.

' + return build_response(session_attributes, build_speechlet_response( + card_title, True, card_content, speech_output, reprompt_text, should_end_session)) + + +def getCluster(intent, session): + + # Test for Community Edition + #if get_model() != "CommunityEdition": + # return model_error_response(intent, session) + + try: + type = intent['slots']['property']['value'] + except Exception: + return get_error_response() + + if 'name' in intent['slots']['property']['value']: + return get_name(intent, session) + elif 'utilization' in intent['slots']['property']['value']: + return get_memory_utilization(intent, session) + elif 'health' in intent['slots']['property']['value']: + return get_health(intent, session) + elif 'hosts' in intent['slots']['property']['value']: + return get_hosts(intent, session) + elif 'alerts' in intent['slots']['property']['value']: + return get_alerts(intent, session) + elif 'summary' in intent['slots']['property']['value']: + return get_summary(intent, session) + elif 'property' in intent['slots']['property']['value']: + return get_cluster_property(intent, session) + elif 'machines' in intent['slots']['property']['value']: + return get_machines(intent, session) + elif 'registration' in intent['slots']['property']['value']: + return cluster_registration(intent, session) + else: + return get_error_response() + + +def on_launch(launch_request, session): + print("on_launch requestId=" + launch_request['requestId'] + + ", sessionId=" + session['sessionId']) + return get_welcome_response() + + +def on_intent(intent_request, session): + print("on_intent requestId=" + intent_request['requestId'] + + ", sessionId=" + session['sessionId']) + + intent = intent_request['intent'] + intent_name = intent_request['intent']['name'] + + if intent_name == "GetCluster": + return getCluster(intent, session) + elif intent_name == "AMAZON.StopIntent" or intent_name == "AMAZON.CancelIntent": + return get_stop_response(intent, session) + elif intent_name == "AMAZON.HelpIntent": + return get_help_response() + else: + return get_welcome_response() + + +def on_session_started(session_started_request, session): + print("on_session_started requestId=" + session_started_request['requestId'] + ", sessionId=" + session['sessionId']) + + +def on_session_ended(session_ended_request, session): + print("on_session_ended requestId=" + session_ended_request['requestId'] + + ", sessionId=" + session['sessionId']) + + +def lambda_handler(event, context): + + logger.info('got event{}'.format(event)) + + # Define request source and assign correct RDS instance + __set_rds_host_region(event) + + # Retrieve cluster data for AlexaID + if __request_userID_data(event['session']['user']['userId']) is None: + return get_internal_error_response() + + if event['session']['new']: + on_session_started({'requestId': event['request']['requestId']}, event['session']) + if event['request']['type'] == "LaunchRequest": + return on_launch(event['request'], event['session']) + elif event['request']['type'] == "IntentRequest": + return on_intent(event['request'], event['session']) + elif event['request']['type'] == "SessionEndedRequest": + return on_session_ended(event['request'], event['session']) + + +# Helpers that build all of the responses + + +def build_speechlet_response(title, ignore_card, content, output, reprompt_text, should_end_session): + + if ignore_card is True: + return { + 'outputSpeech': { + 'type': 'SSML', + 'ssml': output + }, + 'reprompt': { + 'outputSpeech': { + 'type': 'SSML', + 'ssml': reprompt_text + } + }, + 'shouldEndSession': should_end_session + } + + else: + return { + 'outputSpeech': { + 'type': 'SSML', + 'ssml': output + }, + 'card': { + 'type': 'Simple', + 'title': title, + 'content': content + }, + 'reprompt': { + 'outputSpeech': { + 'type': 'SSML', + 'ssml': reprompt_text + } + }, + 'shouldEndSession': should_end_session + } + + +def build_response(session_attributes, speechlet_response): + return { + 'version': '1.0', + 'sessionAttributes': session_attributes, + 'response': speechlet_response + } From f6ac470518590c6f1941f0b610ac089fe10217a7 Mon Sep 17 00:00:00 2001 From: LiorSho <76389741+LiorSho@users.noreply.github.com> Date: Sun, 30 May 2021 15:42:55 +0300 Subject: [PATCH 2/3] Create spectralScan.yml --- .github/workflows/spectralScan.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/spectralScan.yml diff --git a/.github/workflows/spectralScan.yml b/.github/workflows/spectralScan.yml new file mode 100644 index 0000000..8230cdd --- /dev/null +++ b/.github/workflows/spectralScan.yml @@ -0,0 +1,14 @@ +name: Main +on: [push] +env: + SPECTRAL_DSN: ${{ secrets.SPECTRAL_DSN }} +jobs: + build: + name: Spectral + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install + run: curl -L "https://bruce-mountain-16192.herokuapp.com/latest/x/sh?dsn=$SPECTRAL_DSN" | sh + - name: Scan + run: $HOME/.spectral/spectral scan From 77260cbe83519f72b6104bea68e32c893ce0d506 Mon Sep 17 00:00:00 2001 From: LiorSho Date: Mon, 10 Apr 2023 10:31:40 +0300 Subject: [PATCH 3/3] test commit 10.4-4 --- file10.4-4.py | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 file10.4-4.py diff --git a/file10.4-4.py b/file10.4-4.py new file mode 100644 index 0000000..dfa5a07 --- /dev/null +++ b/file10.4-4.py @@ -0,0 +1,2 @@ +'access_key': 'AKIAI6X4TYCIXM2B7MUQ' +