Plugin example. Adding a new S3 storage

In the ispmanager panel, you can create a custom plugin that will allow you to:

  • add your provider's new S3 storage for backup;
  • automate the backup configuration process. 

Plugin configuration

  1. Log in to the panel with a superuser account.
  2. Navigate to the File Manager section.
  3. Create and edit an XML file and a handler file.
  4. Go to the Backup copies section.
  5. In the toolbar, click Backup settings.
  6. In Storage Type, select the New Storage option.
    It is not necessary to fill in the empty fields of the settings form.

  7. Follow the link on the banner:

    After clicking the link, the server address provides information for accessing the new storage and makes a backward transition to the panel. The form fields in the panel are filled in automatically.

    Details

  8. Save the changes.

XML file

  1. Go to the /usr/local/mgr5/etc/xml directory.
  2. Create a file with a name of the following kind:  ispmgr_mod_<plugin name>.xml.
  3. Edit the XML file according to the example:
    <?xml version="1.0" encoding="UTF-8"?>
    <mgrdata>
      <handler name="plugin.py" type="xml">
    	<event name="backup2.settings" before="yes"/>
    	<event name="backup2.settings" after="yes"/>
      </handler>
      <metadata name="backup2.settings" type="form" eqdist="1">
    	<form progress="yes">
      	<page name="banners">
        	<field name="token_new_info" noname="yes" fullwith="yes" base="yes">
          	<textdata type="banner" name="token_new_info" status="info"/>
        	</field>
      	</page>
      	<page name="storage">
        	<field name="storage_type" base="yes">
          	<select name="storage_type" setvalues="yes">
            	<if value="stype_new" hide="localstorage"/>
            	<if value="stype_new" hide="dropboxstorage"/>
            	<if value="stype_new" hide="yandexstorage"/>
            	<if value="stype_new" hide="ftpstorage"/>
            	<if value="stype_new" hide="warn_ftp_space_no_control"/>
            	<if value="stype_new" hide="sftpstorage"/>
            	<if value="stype_new" hide="googledrivestorage"/>
            	<if value="stype_new" hide="token_amazon"/>
            	<if value="stype_new" hide="token_dropbox_info"/>
            	<if value="stype_new" hide="token_googledrive_info"/>
            	<if value="stype_new" hide="token_amazon_info"/>
            	<if value="stype_local" hide="token_new_info"/>
            	<if value="stype_dropbox" hide="token_new_info"/>
            	<if value="stype_googledrive" hide="token_new_info"/>
            	<if value="stype_yandex" hide="token_new_info"/>
            	<if value="stype_amazon" hide="token_new_info"/>
            	<if value="stype_s3" hide="token_new_info"/>
            	<if value="stype_ftp" hide="token_new_info"/>
            	<if value="stype_sftp" hide="token_new_info"/>
          	</select>
        	</field>
      	</page>
    	</form>
      </metadata>
       <lang name="en">
    	<messages name="backup2.settings">
      	<msg name="stype_new">New storage</msg>
      	<msg name="token_new_info">To receive parameters for connecting to the storage follow the &lt;a href="__url__" target="_self"&gt;link&lt;/a&gt;. Necessary fields will be filled automatically.</msg>
    	</messages>
      </lang>
    </mgrdata>
  4. Save the changes.

Replace the values with your own if necessary.

Details

Handler file

  1. Go to the /usr/local/mgr5/addon directory.
  2. Create a handler file with the name that was specified in the XML file. The default name is plugin.py.
  3. Edit the plugin file according to the example:
    #!/usr/bin/env python
    
    from sys import stdin
    import os
    import subprocess
    import xml.etree.ElementTree as etree
    
    def GetEndpoint():
    #Getting panel's ip address
      output = subprocess.check_output("/usr/local/mgr5/sbin/mgrctl -m ispmgr ihttpd out=xml", shell=True, encoding="utf8")
      ip = etree.fromstring(output).find(".//elem/port").text
      return "https://example.com/endpoint?ip=" + ip
    
    #Filling the form with values
    def Get(root):
    #Finding a selection form element
      select = root.find(".//slist[@name='storage_type']")
      if select is not None:
    #Adding an element
        elem = etree.Element("msg")
        elem.text = "stype_new"
    #Placing an element after the Local storage element
        select.insert(1, elem)
    #Generating a message with a link
        msg = root.find(".//messages/msg[@name='token_new_info']")
        if msg is not None:
          text = msg.text
          msg.text = text.replace("__url__", GetEndpoint())
    
    #Handling of clicking the “Save” button
    def Set(root):
    #Changing the parameter to make the setting work for S3 compatible storage
      param = root.find(".//storage_type")
      if param is not None and param.text == "stype_new":
        param.text = "stype_s3"
    
    if __name__ == "__main__":
    #Getting the value of the parameter passed by the panel from environment variables
      func = os.getenv('PARAM_func')
    #Checking if the right function is called
      if func == 'backup2.settings':
    #Reading xml passed from panel from stdin
        root = etree.parse(stdin).getroot()
    #Checking whether the handler is called before or after the action
        type = os.getenv("EVENT_TYPE")
    #Checking that the “Save” button is clicked
        if os.getenv('PARAM_sok') == 'ok' and type == 'before':
          Set(root)
        elif type == 'after':
          Get(root)
    #Writing the xml in stdout
        etree.dump(root)
      quit(0)
    Replace the link https://example.com/endpoint in the script with the address of your service that will send parameters for connecting to the S3 storage.

    Make sure that the values in the XML file match the values in the handler file. The stype_new and token_new_info parameter names must match for the XML file and the handler file. If the values have been changed, the names must be the same in both files.

    We recommend to use the provided handler file, though you can write your own similar handler file by changing its name in the contents of the XML file.

  4. Save the changes.

In this article