<commit_before>/*
 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
 *
 * net-agent.js
 */

var async = require('async');
var NAPI = require('sdc-clients').NAPI;

var ANTI_SPOOF_FIELDS = ['allow_dhcp_spoofing', 'allow_ip_spoofing',
    'allow_mac_spoofing', 'allow_restricted_traffic',
    'allow_unfiltered_promisc'];


function NapiClient(options) {
    this.options = options;
    this.log = options.log;

    this.client = new NAPI({
        url: options.url,
        log: options.log,
        userAgent: options.userAgent
    });
}


/*
 * Updates each of the VM NICs
 *
 * - vm: VM object
 * - nics: the NICs that need to be updated
 *
 * Calls out to NAPI to verify the current NIC data and for each NIC it can do
 * one of the following things:
 *
 * 1. NIC was removed from the VM or VM provision has failed (destroy)
 * 2. NIC doesn't exist and needs to be added (create)
 * 3. NIC exists and has to be udpated (update)
 * 4. NIC exists and but has not changed, no need to do anything (noop)
 */
NapiClient.prototype.updateNics = function (vm, nics, callback) {
    var self = this;
    var log = this.log;

    async.forEachSeries(nics, eachNic, callback);

    function eachNic(nic, cb) {
        self.getNic(nic.mac, onGetNic);

        function onGetNic(err, napiNic) {
            if (err) {
                if (err.name === 'ResourceNotFoundError') {
                    napiNic = undefined;
                } else {
                    cb(err);
                    return;
                }
            }

            if (nic.destroyed) {
                self.deleteNic(vm, nic, cb);
                return;
            }

            nic.status = (vm.state === 'running' ? 'running' : 'stopped');

            if (!napiNic) {
                self.createNic(vm, nic, cb);
            } else if (_nicChanged(nic, napiNic)) {
                self.updateNic(vm, nic, napiNic, cb);
            } else {
                log.info('NIC (mac=%s, ip=%s, status=%s) unchanged for VM %s',
                    nic.mac, nic.ip, nic.status, vm.uuid);
                cb();
            }
        }
    }
};


NapiClient.prototype.getNic = function (mac, callback) {
    return this.client.getNic(mac, callback);
};


NapiClient.prototype.createNic = function (vm, newNic, callback) {
    var log = this.log;
    var nic = _createNicPayload(vm, newNic);

    this.client.createNic(nic.mac, nic, function (err) {
        if (err) {
            log.error(err, 'Could not add NIC %s for VM %s',
                nic.mac, vm.uuid);
            return callback(err);
        }

        log.info('NIC (mac=%s, ip=%s, status=%s) added for VM %s',
            nic.mac, nic.ip, nic.status, vm.uuid);
        return callback();
    });
};


NapiClient.prototype.updateNic = function (vm, newNic, napiNic, callback) {
    var log = this.log;
    var nic = _createNicPayload(vm, newNic);

    for (var i = 0; i < ANTI_SPOOF_FIELDS.length; i++) {
        var field = ANTI_SPOOF_FIELDS[i];
        if (napiNic.hasOwnProperty(field) && !newNic.hasOwnProperty(field)) {
            nic[field] = false;
        }
    }

    this.client.updateNic(nic.mac, nic, function (err) {
        if (err) {
            log.error(err, 'Could not udpate NIC %s for VM %s',
                nic.mac, vm.uuid);
            return callback(err);
        }

        log.info('NIC (mac=%s, ip=%s, status=%s) updated for VM %s',
            nic.mac, nic.ip, nic.status, vm.uuid);
        return callback();
    });
};


NapiClient.prototype.deleteNic = function (vm, nic, callback) {
    var log = this.log;

    this.client.deleteNic(nic.mac, function (err) {
        if (err) {
            if (err.name === 'ResourceNotFoundError') {
                log.info('NIC (mac=%s, ip=%s) already gone for VM %s',
                    nic.mac, nic.ip, vm.uuid);
                return callback();
            } else {
                log.error(err, 'Could not delete NIC %s for VM %s',
                    nic.mac, vm.uuid);
                return callback(err);
            }
        }

        log.info('NIC (mac=%s, ip=%s) deleted for VM %s',
            nic.mac, nic.ip, vm.uuid);
        return callback();
    });
};



/*
 * Some helper functions for NapiClient
 */

function _nicChanged(cur, old) {
    var fields = [ 'vlan_id', 'nic_tag', 'primary', 'ip', 'netmask',
        'status' ].concat(ANTI_SPOOF_FIELDS);
    var field;
    var diff = false;

    for (var i = 0; i < fields.length; i++) {
        field = fields[i];
        if (cur[field] !== old[field]) {
            diff = true;
            break;
        }
    }

    return diff;
}


function _clone(obj) {
    if (null === obj || 'object' != typeof (obj)) {
        return obj;
    }

    var copy = obj.constructor();

    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) {
            copy[attr] = obj[attr];
        }<commit_msg>AGENT-769: net-agent must use 'state' and not 'status' for NIC objects<commit_after>/*
 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
 *
 * net-agent.js
 */

var async = require('async');
var NAPI = require('sdc-clients').NAPI;

var ANTI_SPOOF_FIELDS = ['allow_dhcp_spoofing', 'allow_ip_spoofing',
    'allow_mac_spoofing', 'allow_restricted_traffic',
    'allow_unfiltered_promisc'];


function NapiClient(options) {
    this.options = options;
    this.log = options.log;

    this.client = new NAPI({
        url: options.url,
        log: options.log,
        userAgent: options.userAgent
    });
}


/*
 * Updates each of the VM NICs
 *
 * - vm: VM object
 * - nics: the NICs that need to be updated
 *
 * Calls out to NAPI to verify the current NIC data and for each NIC it can do
 * one of the following things:
 *
 * 1. NIC was removed from the VM or VM provision has failed (destroy)
 * 2. NIC doesn't exist and needs to be added (create)
 * 3. NIC exists and has to be udpated (update)
 * 4. NIC exists and but has not changed, no need to do anything (noop)
 */
NapiClient.prototype.updateNics = function (vm, nics, callback) {
    var self = this;
    var log = this.log;

    async.forEachSeries(nics, eachNic, callback);

    function eachNic(nic, cb) {
        self.getNic(nic.mac, onGetNic);

        function onGetNic(err, napiNic) {
            if (err) {
                if (err.name === 'ResourceNotFoundError') {
                    napiNic = undefined;
                } else {
                    cb(err);
                    return;
                }
            }

            if (nic.destroyed) {
                self.deleteNic(vm, nic, cb);
                return;
            }

            nic.state = (vm.state === 'running' ? 'running' : 'stopped');

            if (!napiNic) {
                self.createNic(vm, nic, cb);
            } else if (_nicChanged(nic, napiNic)) {
                self.updateNic(vm, nic, napiNic, cb);
            } else {
                log.info('NIC (mac=%s, ip=%s, state=%s) unchanged for VM %s',
                    nic.mac, nic.ip, nic.state, vm.uuid);
                cb();
            }
        }
    }
};


NapiClient.prototype.getNic = function (mac, callback) {
    return this.client.getNic(mac, callback);
};


NapiClient.prototype.createNic = function (vm, newNic, callback) {
    var log = this.log;
    var nic = _createNicPayload(vm, newNic);

    this.client.createNic(nic.mac, nic, function (err) {
        if (err) {
            log.error(err, 'Could not add NIC %s for VM %s',
                nic.mac, vm.uuid);
            return callback(err);
        }

        log.info('NIC (mac=%s, ip=%s, state=%s) added for VM %s',
            nic.mac, nic.ip, nic.state, vm.uuid);
        return callback();
    });
};


NapiClient.prototype.updateNic = function (vm, newNic, napiNic, callback) {
    var log = this.log;
    var nic = _createNicPayload(vm, newNic);

    for (var i = 0; i < ANTI_SPOOF_FIELDS.length; i++) {
        var field = ANTI_SPOOF_FIELDS[i];
        if (napiNic.hasOwnProperty(field) && !newNic.hasOwnProperty(field)) {
            nic[field] = false;
        }
    }

    this.client.updateNic(nic.mac, nic, function (err) {
        if (err) {
            log.error(err, 'Could not udpate NIC %s for VM %s',
                nic.mac, vm.uuid);
            return callback(err);
        }

        log.info('NIC (mac=%s, ip=%s, state=%s) updated for VM %s',
            nic.mac, nic.ip, nic.state, vm.uuid);
        return callback();
    });
};


NapiClient.prototype.deleteNic = function (vm, nic, callback) {
    var log = this.log;

    this.client.deleteNic(nic.mac, function (err) {
        if (err) {
            if (err.name === 'ResourceNotFoundError') {
                log.info('NIC (mac=%s, ip=%s) already gone for VM %s',
                    nic.mac, nic.ip, vm.uuid);
                return callback();
            } else {
                log.error(err, 'Could not delete NIC %s for VM %s',
                    nic.mac, vm.uuid);
                return callback(err);
            }
        }

        log.info('NIC (mac=%s, ip=%s) deleted for VM %s',
            nic.mac, nic.ip, vm.uuid);
        return callback();
    });
};



/*
 * Some helper functions for NapiClient
 */

function _nicChanged(cur, old) {
    var fields = [ 'vlan_id', 'nic_tag', 'primary', 'ip', 'netmask',
        'state' ].concat(ANTI_SPOOF_FIELDS);
    var field;
    var diff = false;

    for (var i = 0; i < fields.length; i++) {
        field = fields[i];
        if (cur[field] !== old[field]) {
            diff = true;
            break;
        }
    }

    return diff;
}


function _clone(obj) {
    if (null === obj || 'object' != typeof (obj)) {
        return obj;
    }

    var copy = obj.constructor();

    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) {
            copy[attr] = obj[attr];
        }
{'fraction_non_alphanumeric': 0.13671118360689163, 'fraction_numerical': 0.002344785401162198, 'mean_word_length': 1.8625620075868106, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2596349', 'n_tokens_mistral': 3320, 'n_tokens_neox': 3127, 'n_words': 854}