Documentation forService 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 script only works for non-ESM accounts. Please use the provided Ruby script for ESM support.

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.

  • SolarWinds recommends using the Ruby script for ESM accounts.

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) }