Documentation forSolarWinds Service Desk

Warranty sync scripts

On this page

Introduction

Administrators can sync warranty data from non-supported computers via API.

CSV template example

warranties.csv

Sync script examples

The scripts below are not supported by SolarWinds in any way. They are provided only as examples.

Python 3.6+

Requirements

  • Python 3.6+

  • Pip (included natively in python installer)

  • Python Requests module

  • CSV of Warranty information (use SolarWinds template)

  • Native Samanage Email & Password login (single sign on credentials are not supported)

    • This can be verified here: https://app.samanage.com/login?native=true or https://appeu.samanage.com/login?native=true

    • A new password can be requested here https://app.samanage.com/password/new or https://appeu.samanage.com/password/new

Instructions

  1. Download and install Python 3.6 and pip

  2. Install the python module Requests:

    pip install requests

  3. Compile your warranty information into the above warranties.csv template

  4. From the script directory use the command:

    • US datacenter: python sync_warranties.py warranties.csv email@domain.com password

    • EU datacenter: python sync_warranties.py warranties.csv email@domain.com password eu

Notes

  • Dates are parsed explicitly using the format 01/31/2000. If you wish to use a different date format this can be modified here:

    warranty['Start Date'] = datetime.strptime(warranty['Start Date'], '%m/%d/%Y')

    warranty['End Date'] = datetime.strptime(warranty['End Date'], '%m/%d/%Y')

    For more information on date formatting visit the Python docs
  • All warranties included in the CSV will be uploaded. Exclude any expired warranties if you do not wish to import.

Python code

import csv
import sys
import requests
import json
from datetime import datetime

# Initialize CSV
input_file = sys.argv[1]
warranties = []
csv_file = csv.DictReader(open(input_file))
for line in csv_file:
	warranties.append(line)

# API Controller
class Samanage:
	def __init__(self, argv):
		self.email =  sys.argv[2]
		self.password = sys.argv[3]
		# Check for EU data center, or default to US
		if len(sys.argv) >= 5:
			if str(sys.argv[4]).lower() == 'eu':
				self.dc = sys.argv[4]
			elif str(sys.argv[4]).lower() == 'us':
				self.dc = ''
			else:
				print('Invalid Datacenter:', sys.argv[4])
				quit()
		else:
			self.dc = ''
		self.base_url = 'https://api' + self.dc + '.samanage.com/'
		self.initialize()

	# Validate API credentials
	def initialize(self):
		path = 'api.json?per_page=100'
		api_call = requests.get(self.base_url + path, auth=(self.email, self.password))
		if api_call.status_code > 201:
			print("Invalid User/Password")
			print("Please enter 'python sync_warranties.py warranties.csv email@address password")
			quit()

	# Sync warranty based on serial number and CSV data
	def sync_warranty(self, serial_number, warranty):
		path = 'hardwares.json?serial_number[]=' + str(serial_number)
		api_call = requests.get(self.base_url + path, auth=(self.email, self.password))
		hardware = api_call.json()
		# Sync if exactly 1 asset found AND serial matches exactly
		if (len(hardware) == 1) and (hardware[0]['serial_number'] == serial_number):
			print("Updating ",hardware[0]['name'], 'Start: ',warranty['Start Date'], ' End: ', warranty['End Date'],' --- ',hardware[0]['href'].replace('.json',''))
			self.create_warranty(hardware[0]['id'], warranty)
		else:
			print('Serial Number: ', str(serial_number), 'Not Found or multiple matches: https://app.samanage.com/' + path)

	# Determine status based on start & end dates
	def set_status(self, warranty):
		if warranty['End Date'] < datetime.now():
			return 'Expired'
		elif warranty['End Date'] > datetime.now() and warranty['Start Date'] < datetime.now():
			return 'Active'
		elif warranty['Start Date'] > datetime.now():
			return 'Future'

	# Convert dates & send Warranty to Samanage
	def create_warranty(self, hardware_id, warranty):
		path = 'hardwares/' + str(hardware_id) + '/warranties.json'
		warranty['Start Date'] = datetime.strptime(warranty['Start Date'], '%m/%d/%Y')
		warranty['End Date'] = datetime.strptime(warranty['End Date'], '%m/%d/%Y')
		status = self.set_status(warranty)
		warranty_json = {
		'warranty':{
			'service':warranty['Service'],
			'provider':warranty['Provider'],
			'start_date':str(warranty['Start Date']),
			'end_date':str(warranty['End Date']),
			'status': status
			}
		}
		api_request = requests.Session()
		headers = {'Content-Type':'application/json','Accept':'application/vnd.samanage.v2.0'}
		api_request.headers.update(headers)
		api_call = api_request.post(self.base_url + path, auth=(self.email, self.password), json=warranty_json)

# Initialize API Connector
api_controller = Samanage(sys.argv)
# For each Warranty, sync add warranty info
for warranty in warranties:
	api_controller.sync_warranty(warranty['Serial Number'], warranty)

Ruby 2.3+

Instructions

Compile your warranty information into the above warranties.csv template

  • US datacenter: ruby sync_warranties.rb warranties.csv API_TOKEN

  • EU datacenter: ruby sync_warranties.rb warranties.csv API_TOKEN eu

Notes

  • Dates are parsed explicitly using the format 01/31/2000. If you wish to use a different date format you can modify it here:

    start_date = Date.strptime(warranty['Start Date'], "%m/%d/%Y")end_date = Date.strptime(warranty['End Date'], '%m/%d/%Y')
  • All warranties included in the CSV will be uploaded. Exclude any expired warranties if you do not wish to import.

Ruby code

# frozen_string_literal: true

require "samanage"
require "csv"
require "date"
# require 'ap'

api_token = ARGV[0]
input = ARGV[1]
datacenter = ARGV[2]
@samanage = Samanage::Api.new(token: api_token, datacenter: datacenter)
csv_rows = CSV.read(input, headers: true, encoding: "ISO-8859-1")
OUTPUT_HEADERS = csv_rows.headers << "Error"
DEFAULT_FILENAME = "Errors-#{input.split('.').first}-#{DateTime.now.strftime("%b-%d-%Y-%l%M")}.csv"

def log_to_csv(message:, filename: DEFAULT_FILENAME, headers: OUTPUT_HEADERS)
  CSV.open(filename, "a+", write_headers: true, force_quotes: true) do |csv|
    csv << OUTPUT_HEADERS if csv.count.eql? 0
    csv << message
  end
end


def set_status(start_date, end_date)
  if end_date < Date.today
    "Expired"
  elsif (start_date..end_date).include?(Date.today)
    "Active"
  else
    "Future"
  end
end


def sync_warranty(warranty:)
  hardware = @samanage.find_hardwares_by_serial(serial_number: warranty["Serial Number"])[:data]
  puts "#{hardware}"
  hardware_id = hardware.select { |h| h.dig("serial_number") == warranty["Serial Number"] }.first.to_h.dig("id")
  puts "hardware_id: #{hardware_id}"
  start_date = Date.strptime(warranty["Start Date"], "%m/%d/%Y")
  end_date = Date.strptime(warranty["End Date"], "%m/%d/%Y")
  status = set_status(start_date, end_date)
  if hardware_id
    warranty = {
      warranty: {
        service: warranty["Service"],
        provider: warranty["Provider"],
        start_date: start_date,
        end_date: end_date,
        status: status,
      }
    }
    puts warranty.inspect
    @samanage.execute(http_method: "post", path: "hardwares/#{hardware_id}/warranties.json", payload: warranty)
  else
    puts "Hardware serial: #{warranty['Serial Number']} not found"
  end
rescue Samanage::Error, Samanage::InvalidRequest => e
  warranty["Error"] = "#{e.class}: #{e}"
  log_to_csv(message: warranty.values)
end


csv_rows.map { |row| sync_warranty(warranty: row.to_h) }