Skip to content

Commit

Permalink
new_template.py
Browse files Browse the repository at this point in the history
- added comments to all functions
- Updated file handling to use OS module
- Updated file handling to use with instead of a naked call
- Removed baseuri
- Made the template name optional
- Added additional user output
- Updated docs
- Addresses dell#184 for new_template.py

library code:
- added post functionality

readme.md
- Updated the readme with tips for writing your own code and added a note about feedback

Signed-off-by: Grant Curell <[email protected]>
  • Loading branch information
grantcurell committed Feb 15, 2021
1 parent 73a024c commit 63ab832
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 4 deletions.
187 changes: 187 additions & 0 deletions Core/Python/new_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#
# Python script to get the list of virtual addresses in an Identity Pool
#
# _author_ = Trevor Squillario <[email protected]>
# _author_ = Grant Curell <[email protected]>
#
# Copyright (c) 2021 Dell EMC Corporation
#
# 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.
#

"""
#### Synopsis
Script to manage templates in OpenManage Enterprise
#### Description
This script uses the OME REST API to create a template from file
For authentication X-Auth is used over Basic Authentication
Note that the credentials entered are not stored to disk.
#### Example
python new_template.py --ip 192.168.1.93 --password password --template-file gelante.xml
python new_template.py --ip 192.168.1.93 --password password --template-file gelante.xml --template-name 格蘭特是最好的
"""
import argparse
import json
import sys
from argparse import RawTextHelpFormatter
from os import path
from pprint import pprint

try:
import urllib3
import requests
except ModuleNotFoundError:
print("This program requires urllib3 and requests. To install them on most systems run `pip install requests"
"urllib3`")
sys.exit(0)


def authenticate(ome_ip_address: str, ome_username: str, ome_password: str) -> dict:
"""
Authenticates with OME and creates a session
Args:
ome_ip_address: IP address of the OME server
ome_username: Username for OME
ome_password: OME password
Returns: A dictionary of HTTP headers
Raises:
Exception: A generic exception in the event of a failure to connect
"""

authenticated_headers = {'content-type': 'application/json'}
session_url = 'https://%s/api/SessionService/Sessions' % ome_ip_address
user_details = {'UserName': ome_username,
'Password': ome_password,
'SessionType': 'API'}
try:
session_info = requests.post(session_url, verify=False,
data=json.dumps(user_details),
headers=authenticated_headers)
except requests.exceptions.ConnectionError:
print("Failed to connect to OME. This typically indicates a network connectivity problem. Can you ping OME?")
sys.exit(0)

if session_info.status_code == 201:
authenticated_headers['X-Auth-Token'] = session_info.headers['X-Auth-Token']
return authenticated_headers

print("There was a problem authenticating with OME. Are you sure you have the right username, password, "
"and IP?")
raise Exception("There was a problem authenticating with OME. Are you sure you have the right username, "
"password, and IP?")


def post_data(url: str, authenticated_headers: dict, payload: dict, error_message: str) -> dict:
"""
Posts data to OME and returns the results
Args:
url: The URL to which you want to post
authenticated_headers: Headers used for authentication to the OME server
payload: A payload to post to the OME server
error_message: If the POST fails this is the message which will be displayed to the user
Returns: A dictionary with the results of the post request or an empty dictionary in the event of a failure. If the
result is a 204 - No Content (which indicates success but there is no data) then it will return a
dictionary with the value {'status_code': 204}
"""
response = requests.post(url, headers=authenticated_headers, verify=False, data=json.dumps(payload))

if response.status_code == 204:
return {'status_code': 204}
if response.status_code != 400:
return json.loads(response.content)
else:
print(error_message + " Error was:")
pprint(json.loads(response.content))
return {}


def import_template(ome_ip_address, authenticated_headers, template_name, filename):
"""
Imports a template from file
Args:
ome_ip_address: IP address of the OME server
authenticated_headers: Headers used for authentication to the OME server
template_name: The name of the template as you would like it to appear in OME
filename: The filename of the template you would like to push
Returns: True if the template pushed successfully and false otherwise
"""
url = "https://%s/api/TemplateService/Actions/TemplateService.Import" % ome_ip_address

with open(filename, "r") as template_file:

payload = {
"Name": template_name,
"Type": 2,
"ViewTypeId": 2,
"Content": template_file.read()
}

print("POSTing the data to OME and beginning the template import.")

if post_data(url, authenticated_headers, payload, "There was a problem posting the template."):
print("Template import successful!")
return True
else:
print("Could not create template. Exiting.")
return False


if __name__ == '__main__':
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=RawTextHelpFormatter)
parser.add_argument("--ip", "-i", required=True, help="OME Appliance IP")
parser.add_argument("--user", "-u", required=False,
help="Username for OME Appliance", default="admin")
parser.add_argument("--password", "-p", required=True,
help="Password for OME Appliance")
parser.add_argument("--template-file", "-f", required=True,
help="Path of Template File to Import")
parser.add_argument("--template-name", "-n", required=False,
help="The name of the template you would like to use. If it is not provided it defaults to the"
" name of the file provided with the extension dropped.")

args = parser.parse_args()

try:
headers = authenticate(args.ip, args.user, args.password)

if not headers:
sys.exit(0)

if path.isfile(args.template_file):
if args.template_name:
import_template(args.ip, headers, args.template_name, args.template_file)
else:
import_template(args.ip,
headers,
path.basename(path.splitext(args.template_file)[0]),
args.template_file)
else:
print("Error: It looks like %s does not exist! Are you sure the path is correct?" % args.template_file)
sys.exit(0)

except Exception as error:
print("Unexpected error:", str(error))
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,22 @@ Some older scripts may not carry this requirement. You can tell if a script requ
### PS5.1 Support

Currently we do not have any plans to backport new scripts or provide cross compatibility. If there is enough community interest we will raise the priority. If PS5.1 is a hard requirement for you please leave a comment on [this ticket](https://github.com/dell/OpenManage-Enterprise/issues/181).

## We Love Feedback

We build, revise, or add features to scripts mostly based on user feedback. If there is something you want to see and it's applicable to a wide audience please open an issue on [our issues page](https://github.com/dell/OpenManage-Enterprise/issues) or feel free to leave a comment on an existing issue. This helps tremendously in determining what kind of functionality the community is looking for.
## Script Documentation

For a listing of each script and its accompanying documentation see our [Example API Documentation](docs/API.md)

## Writing Your Own Code

All scripts are self contained. We deliberately do not use an internal library. To write your own code simply copy one of our scripts and modify it as you please. We have cookie cutter code for common tasks available in the links below:

[Python Common Code](docs/python_library_code.md)
<br>
[PowerShell Common Code](docs/powershell_library_code.md)

## Contributing to this Repository

For more information on contributing to the repository see [the contribution guide](docs/CONTRIBUTING.md).
Expand All @@ -35,10 +47,6 @@ looking for there!
If you have scripts you made that you think could be helpful but don't have time to work them over to meet the
contributor guidelines, feel free to pull request them to the devel branch!

## Requests

If there is a script you would like feel free to put a request [on our issues](https://github.com/dell/OpenManage-Enterprise/issues). This repository is maintained in our free time, but we're happy to take a look at things the community needs. The more descriptive you can be about exactly what you want the better. Screenshots of exactly the functionality you are looking for are fantastic!

## Problems

If you run into problems with a script you can post [on our issues](https://github.com/dell/OpenManage-Enterprise/issues). If possible, provide the exact command you ran to generate the problem, any OME configurations required to recreate it, or if it's a code problem you already found - a good description of where the problem is.
Expand Down
25 changes: 25 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ You can find a current copy of the OME API documentation [here](https://dl.dell.

<li><a href="#new-static-group">New Static Group</a></li>

<li><a href="#new-template">New Template</a></li>

<li><a href="#set-power-state">Set Power State</a></li>

</ul>
Expand Down Expand Up @@ -610,6 +612,29 @@ PS C:\>$cred = Get-Credential
```


---
### New Template

#### Available Scripts

- [new_template.py](../Core/Python/new_template.py)


#### Synopsis
Script to manage templates in OpenManage Enterprise

#### Description
This script uses the OME REST API to create a template from file

For authentication X-Auth is used over Basic Authentication
Note that the credentials entered are not stored to disk.

#### Example
python new_template.py --ip 192.168.1.93 --password password --template-file gelante.xml
python new_template.py --ip 192.168.1.93 --password password --template-file gelante.xml --template-name 格蘭特第一實驗



---
### Set Power State

Expand Down
2 changes: 2 additions & 0 deletions docs/categories.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ deploy:
new_static_group:
- new_static_group.py
- New-StaticGroup.ps1
new_template:
- new_template.py
set_power_state:
- set_power_state.py
- Set-PowerState.ps1
Expand Down
33 changes: 33 additions & 0 deletions docs/python_library_code.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
- [Python Library Code](#python-library-code)
- [Authenticating to an OME Instance](#authenticating-to-an-ome-instance)
- [Interact with an API Resource](#interact-with-an-api-resource)
- [GET from an API resource](#get-from-an-api-resource)
- [POST to an API resource](#post-to-an-api-resource)
- [Resolve a device to its ID](#resolve-a-device-to-its-id)
- [Helpful device ID pattern](#helpful-device-id-pattern)
- [Get Group ID by Name](#get-group-id-by-name)
Expand Down Expand Up @@ -56,6 +58,7 @@ def authenticate(ome_ip_address: str, ome_username: str, ome_password: str) -> d

## Interact with an API Resource

### GET from an API resource
This is used to perform any sort of interaction with a REST API resource. It includes the ability to pass in odata filters. Anytime you need to POST or GET an API resource we recommend you use this function.

```python
Expand Down Expand Up @@ -147,6 +150,36 @@ def get_data(authenticated_headers: dict, url: str, odata_filter: str = None, ma
return data
```

### POST to an API resource

```python
def post_data(url: str, authenticated_headers: dict, payload: dict, error_message: str) -> dict:
"""
Posts data to OME and returns the results
Args:
url: The URL to which you want to post
authenticated_headers: Headers used for authentication to the OME server
payload: A payload to post to the OME server
error_message: If the POST fails this is the message which will be displayed to the user
Returns: A dictionary with the results of the post request or an empty dictionary in the event of a failure. If the
result is a 204 - No Content (which indicates success but there is no data) then it will return a
dictionary with the value {'status_code': 204}
"""
response = requests.post(url, headers=authenticated_headers, verify=False, data=json.dumps(payload))

if response.status_code == 204:
return {'status_code': 204}
if response.status_code != 400:
return json.loads(response.content)
else:
print(error_message + " Error was:")
pprint(json.loads(response.content))
return {}
```

## Resolve a device to its ID

Use this function to resolve a service tag, idrac IP, or an OME device name to its OME device ID. Most API resources require you to use the device ID to take action. Use this function to resolve any of the above to the OME device ID.
Expand Down

0 comments on commit 63ab832

Please sign in to comment.