refstack result update script bugfix

fixed codeflow and RESTful API call errors.
Change-Id: I8cfe07b972588fda453dec4ef3651e500badc986
This commit is contained in:
Megan Guiney 2017-08-31 19:43:04 -07:00 committed by Megan
parent 5f94bbe0d8
commit 0ad6143874
2 changed files with 207 additions and 102 deletions

View File

@ -1,48 +1,76 @@
#!/usr/bin/python
#!/usr/bin/env python
# Copyright (c) 2017 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Test result update & verify script for the local refstack database.
"""
import os
import argparse
import datetime
import requests
import os
from collections import namedtuple
import json
def getData(entry):
guidelines = ["2015.03", "2015.04", "2015.05", "2015.07", "2016.01",
"2016.08", "2017.01"]
components = ["Platform", "Compute", "Storage"]
"""Extract and reformat data from a product data csv"""
guidelines = ['2015.03', '2015.04', '2015.05', '2015.07', '2016.01',
'2016.08', '2017.01', '2017.09']
components = ['platform', 'compute', 'storage', 'object']
if len(entry) < 10:
return None, None, None
if entry[9] != "" and entry[9] != " ":
refstackLink = entry[9]
testId = refstackLink.split("/")[-1]
refstackLink = entry[9].strip()
guideline = entry[4].strip()
target = entry[5].lower().strip()
if refstackLink:
testId = refstackLink.split('/')[-1]
else:
refstackLink = None
testId = None
if entry[4] != "" and entry[4] != " " and entry[4] in guidelines:
guideline = entry[4]
else:
if guideline not in guidelines:
guideline = None
if entry[5] != "" and entry[5] != " " and entry[5] in components:
target = entry[5].lower()
if target == "storage":
target = "object"
else:
if target not in components:
target = None
elif target == "storage":
target = "object"
return testId, guideline, target
def linkChk(link, token):
print("checking result with a test ID of: " + link.split("/")[-1])
"""Check existence of and access to api result link"""
print("now checking result: " + link)
if not link:
return False
try:
if " " in link:
return False
response = requests.get(
link, headers={'Authorization': 'Bearer ' + token})
headers = {'Authorization': 'Bearer ' + token}
response = requests.get(link, headers)
if response.status_code == 200:
return json.loads(response.text)
elif response.status_code == 401 or response.status_code == 403:
print("Authentication Failed. link check response code: " +
str(response.status_code))
return False
elif response.status_code == 400:
print("Malformed Request. link response code: " +
str(response.status_code))
return False
else:
print("Link check response_status_code=" +
str(response.status_code))
@ -52,50 +80,98 @@ def linkChk(link, token):
return False
def updateResult(apiLink, target, guideline, token, results_log):
success = True
with open(results_log, 'a') as logfile:
logfile.write(str(datetime.datetime.now()) + ",")
response = requests.post(apiLink + '/meta/shared', headers={
'Authorization': 'Bearer ' + token}, data='true')
if response.status_code != 201:
print("Update shared status response_status_code=" +
str(response.status_code))
logfile.write(apiLink + ",0,")
success = False
def updateField(header, apiLink, raw_data):
"""Update a given metadata field"""
valid_keytype = ['shared', 'guideline', 'target']
keytype = raw_data.type
keyval = raw_data.value
if keytype not in valid_keytype or not keyval:
updresult = "%s keypair does not exist" % (keytype)
return updresult, False
link = apiLink.strip() + '/meta/' + keytype
response = requests.post(link, data=keyval, headers=header)
if response.status_code != 201:
print('update response status code=%d' %
response.status_code)
print('update response text=' + response.text)
updresult = ("%s field update failed. reason: %s" %
(keytype, response.text.replace(',', ' ')))
return updresult, False
else:
updresult = "%s field update successful," % (keytype)
return updresult, True
def updateResult(apiLink, target, guideline, token, record):
"""Update metadata for result and verify if all updates are a success"""
MetadataField = namedtuple('MetadataField', ['type', 'value'])
success = []
header = {'Authorization': 'Bearer ' + token}
with open(record, 'a') as r:
r.write(str(datetime.datetime.now()) + "," + apiLink + ",")
# update the shared field
data = MetadataField('shared', 'true')
shared_result, shared_status = updateField(header, apiLink, data)
r.write(shared_result)
success.append(shared_status)
# update the target field
data = MetadataField('target', target)
target_result, target_status = updateField(header, apiLink, data)
r.write(target_result)
success.append(target_status)
# update the guideline field
data = MetadataField('guideline', guideline + '.json')
gl_result, gl_status = updateField(header, apiLink, data)
r.write(gl_result)
success.append(gl_status)
if not all(success):
r.write('unable to verify.\n')
return False
# if there were no update failures, we can verify the result
# this is the operation most likely to fail, so extra checks are
# in order
print('Test Result updated successfully. Attempting verification.')
try:
response = requests.put(apiLink,
json={'verification_status': 1},
headers=header)
except Exception as ex:
print('Exception raised while verifying test result: %s' %
(str(ex)))
r.write('verification failed: %s\n' % (str(ex)))
return False
updated = verification_chk(apiLink, header)
if response.status_code not in (200, 201):
print('verification failure status code=%d' %
response.status_code)
print('verification failure detail=%s' %
response.text)
r.write('verification unsuccessful: detail: %s\n' %
(response.text))
return False
elif not updated:
print("verification_status field failed to update")
r.write('verification status update failed. detail: %s\n' %
(response.text))
return False
else:
logfile.write(apiLink + ",1,")
if ".json" not in guideline:
guideline = str(guideline) + ".json"
response = requests.post(apiLink + '/meta/guideline', headers={
'Authorization': 'Bearer ' + token}, data=guideline)
if response.status_code != 201:
print("Update guideline response_status_code=" +
str(response.status_code))
logfile.write(guideline + ",0,")
success = False
print('Test result verified!\n')
r.write('Test result successfully verified\n')
return True
def verification_chk(link, header):
try:
response = requests.get(link, header)
status = int(response.json()['verification_status'])
if status == 1:
return True
else:
logfile.write(guideline + ",1,")
response = requests.post(apiLink + '/meta/target', headers={
'Authorization': 'Bearer ' + token}, data=target)
if response.status_code != 201:
print("Update target response_status_code=" +
str(response.status_code))
logfile.write(target + ",0,")
success = False
else:
logfile.write(target + ",1,")
if success:
print("test result updated. Verifying.")
response = requests.put(apiLink, headers={
'Authorization': 'Bearer ' + token},
json={'verification_status': 1})
if response.status_code != 201:
success = False
else:
print("Test result verified.")
logfile.write(str(int(success)) + '\n')
return success
return False
except Exception as ex:
print('Exception raised while ensuring update of ' +
'verification status: ' + str(ex))
return False
def main():
@ -111,12 +187,13 @@ def main():
help="the base URL of the endpoint. ex: http://examplerefstack.com/v1")
parser.add_argument("--token", "-t", metavar="t", type=str,
action="store", required=True, help="API auth token")
parser.add_argument("--logfile", "-l", metavar="l", type=str,
parser.add_argument("--record", "-r", metavar="r", type=str,
action="store", default="verification_results.csv",
help="name of logfile to output data into")
help="name of file to output update & verification " +
" run record data into")
result = parser.parse_args()
infile = result.file
logfile = result.logfile
record = result.record
endpoint = result.endpoint
token = result.token
with open(infile) as f:
@ -124,30 +201,28 @@ def main():
linect = linect + 1
entry = line.split(",")
testId, guideline, target = getData(entry)
if testId is None or guideline is None or target is None:
if None in (testId, guideline, target):
print(
"entry found at line " + str(linect) +
" cannot be updated and verified: entry incomplete.")
" cannot be updated and verified: entry incomplete.\n")
else:
apiLink = os.path.join(endpoint, 'results', testId)
testResult = linkChk(apiLink, token)
if testResult:
if testResult.get('verification_status'):
print(
"Result has already been verified; nothing to do.")
print("Result has been verified.\n")
else:
print(
"Result link is valid. Updating result with ID " +
testId)
"Result link is valid. Updating...")
success = updateResult(apiLink, target, guideline,
token, logfile)
token, record)
if not success:
print("update of the results with the ID " +
testId + " failed. please recheck your " +
"spreadsheet and try again")
"spreadsheet and try again\n")
else:
print("the test result " + testId +
" cannot be verified due to a broken result link.")
print("the test result " + testId + " cannot be " +
"verified due to a link verification failure\n")
main()

View File

@ -7,29 +7,51 @@ successful in the usage of the script update-rs-db.py.
The script can be run using the following formatting:
"./update-rs-db.py --file /tmp/datasource.csv --endpoint
http://example.com:8000/v1 --token <my-token>"
http://example.com:8000/v1 --token <my-token>". In order to
successfully update and verify results, you will need admin rights
for the refstack server in question. Instructions on how to get
these for your local install can be found at https://github.com/openstack/refstack/blob/master/doc/source/refstack.rst#optional-configure-foundation-organization-and-group
This script updates RefStack tests as verified given a specific
spreadsheet. The columns in this spreadsheet are, in this order:
- Company Name
- Product Name
- Type (Distribution, Public, or Private)
- Region
- Guideline
- Component (Compute, Platform, or Object)
- Reported Release
- Passed Release
- Federated identity (yes/no)
- Refstack Link
- Zendesk Link
- Marketplace Link
- License Date
- Update Product (yes/no)
- Contacts
- Notes
- License Link
- Active (1 or 0)
- Public (1 or 0)
* Company Name
* Product Name
* Type (Distribution, Public, or Private)
* Region
* Guideline
* Component (Compute, Platform, or Object)
* Reported Release
* Passed Release
* Federated identity (yes/no)
* Refstack Link
* Zendesk Link
* Marketplace Link
* License Date
* Update Product (yes/no)
* Contacts
* Notes
* License Link
* Active (1 or 0)
* Public (1 or 0)
The data is pulled from a csv file. The default csv name is toadd.csv,
but using the -f flag, we can use csv of a different filename.
@ -60,11 +82,19 @@ The status of each of these steps will be output to "verification_status.csv"
by default. A '1' will denote that the resource was successfully updated while
a '0' will denote that the resource was not successfully updated. The order of
fields of this file are as follows:
- Date modified
- API link
- Shared update status
- Guideline
- Guideline update success status
- Target
- Target update success status
- Verification update success status
* Date modified
* API link
* Shared update status
* Guideline
* Guideline update success status
* Target
* Target update success statu
* Verification update success status