Forum Discussion

yamashin55's avatar
Jun 27, 2020

How to update data-group using iRules LX

I created the following code with iRules LX.

The code does not work properly.

 

The log is output up to "console.log('getDataGroup start');".

 

Does anyone know how to check if icontrol is successfully connecting to BIG-IP?

List() of iControl doesn't seem to work properly.

 

 

iRule

---------------------------------------------

when ACCESS_POLICY_AGENT_EVENT {
    switch [ACCESS::policy agent_id] {
        ....
        ....
 
 
        "add_user" {
            set ilx_handle [ILX::init "f5_mfa_plugin" "f5_mfa_extension"]
            set user [ACCESS::session data get session.logon.last.username]
            set sec [ACCESS::session data get session.custom.otp.secret]
            log local0.info "INFO: f5_mfa.tcl - user:$user secret:$sec"
            if {[catch {set result [ILX::call $ilx_handle -timeout 10000 addUser $user $sec]} result]} {
                log local0.error "ERROR: f5_mfa.tcl - Client - [IP::client_addr], ILX failure: $result"
                return
            }
            log local0.info "user:$result"
        }
    }
}

 

iRuleLX: index.js

---------------------------------------------

var f5 = require('f5-nodejs');
var User = require('./f5_user').User;
var ilx = new f5.ILXServer();
ilx.listen();
ilx.addMethod('addUser', function(req,res) {
  console.log("START: addMethod", req.params()[0], req.params()[1]);
  var user = new User(req.params()[0]);
  user.secret = req.params()[1];
  user.add(function(response) {
    res.reply(response);
  });
});

 

 

iRuleLX: user.js

---------------------------------------------

var dg = require('./f5_data_group');
 
 
exports.User = function(name) {
	var self = this;
 
 
	self.name = name;
	self.enrolled = false;
	self.secret = "";
 
 
	this.methods = {};
 
 
	/**
	* add a user to the data group
	*
	* @return {Boolean} user added
	*/
	this.add = function(callback){
	    console.log('user.add start');
		if(typeof this.secret === undefined) {
			console.error('you have to set a secret before calling add');
			callback(false);
		}
		console.log(self.name, self.secret);
		dg.put(self.name, self.secret, function(status) {
			if(status) {
				self.enrolled = true;
			}
			callback(true);
		});
	};
 
 
};

 

 

iRuleLX: f5_data_group.js

---------------------------------------------

var iControl = require('icontrol');
var util = require('util');
 
 
// set API connection and authentication
var bigip = new iControl({
  host: '127.0.0.1',
  proto: 'https',
  port: '443',
  username: 'admin',
  pass: 'admin',
  strict: 'true',
  debug: 'true'
});
 
 
var dgPath = '/ltm/data-group/internal/~Common~token_keys';
var exports = module.exports = {};
 
 
//ignore self signed certificate
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
bigip.strict = false;
 
 
 
 
/**
 * return dta group
 *
 * @param {Function} callback
 */
exports.getDataGroup = function(callback) {
  console.log('getDataGroup start');
  bigip.list(dgPath, function(err, res) {
    callback(res);
  });
};
 
 
/**
 * add key:data pair to the data group
 *
 * @param {String} key
 * @param {String} data
 * @param {Function} callback
 */
exports.put = function (key, data, callback) {
  console.log('put data-group key:', key, 'data:', data);
  exports.getDataGroup(function(res) {
      // add new user to the object stack
      // make sure the data group isn't empty
      if (typeof res.records !== 'undefined') {
        // make sure user doesn't already exist
        var isset = false;
        for(var record in res.records) {
          if(res.records[record].name == key) {
            // user exists, update secret
            res.records[record].data = data;
            isset = true;
            break;
          }
        }
        if(!isset) {
          // user doesn't exist, add them
          res.records.push({"name": key, "data": data});
        }
      } else {
        res.records = [{"name": key, "data": data}];
      }
      // populate the arguments for the http post
      args = {
        data: { records: res.records },
        header: { "Content-Type": "application/json" }
      };
      bigip.modify(dgPath, args, function(err, res) {
        callback(data);
      });
    });
};