예제 #1
0
    def createListLayoutCode(self, listMetadata, index, listView):
        baseListItemMetadata = listMetadata.mListItemMetadatas[0]
        #        document = XmlUtil.createDocument()
        rootView = RectView(baseListItemMetadata.bound, None)
        for rectView in baseListItemMetadata.baseViews:
            rootView.addChild(rectView)

        for rectView in baseListItemMetadata.additionalViews:
            rootView.addChild(rectView)

        rootView.mChildren.sort(
            key=cmp_to_key(RectUtil.getTopBottomComparator()))
        rootView.mChildren.sort(
            key=cmp_to_key(RectUtil.getLeftRightComparator()))

        rootElement = XmlUtil.createRoot(self.mDipCalculator,
                                         FRAMELAYOUT_ELEMENT, rootView,
                                         self.mColorWriter)
        _map = {}
        self.addChildrenLayout(rootElement, rootView, listView.x, listView.y,
                               _map)

        rectViews = RectUtil.toRects(rootView)
        rectViews.remove(rootView)
        XmlUtil.writeDocument(
            rootView, self.mOutProjectFolder + Constants.DEFAULT_LAYOUT_PATH +
            "/" + Constants.DEFAULT_LAYOUT_LIST_PREFIX + index + ".xml")
def configSettings():
    mdsdCfgstr = readPublicConfig('mdsdCfg')
    if not mdsdCfgstr :
        with open (os.path.join(WorkDir, './mdsdConfig.xml.template'),"r") as defaulCfg:
            mdsdCfgstr = defaulCfg.read()
    else:
        mdsdCfgstr = base64.b64decode(mdsdCfgstr)
    mdsdCfg = ET.ElementTree()
    mdsdCfg._setroot(XmlUtil.createElement(mdsdCfgstr))

    # update deployment id
    deployment_id = get_deployment_id()
    XmlUtil.setXmlValue(mdsdCfg, "Management/Identity/IdentityComponent", "", deployment_id, ["name", "DeploymentId"])

    try:
        resourceId = getResourceId()
        if resourceId:
            createPortalSettings(mdsdCfg,escape(resourceId))
            instanceID=""
            if resourceId.find("providers/Microsoft.Compute/virtualMachineScaleSets") >=0:
                instanceID = readUUID();
            config(mdsdCfg,"instanceID",instanceID,"Events/DerivedEvents/DerivedEvent/LADQuery")

    except Exception, e:
        hutil.error("Failed to create portal config  error:{0} {1}".format(e,traceback.format_exc()))
    def _set_event_volume(self, lad_cfg):
        """
        Set event volume in mdsd config. Check if desired event volume is specified,
        first in ladCfg then in public config. If in neither then default to Medium.
        :param lad_cfg: 'ladCfg' Json object to look up for the event volume setting.
        :return: None. The mdsd config XML tree's eventVolume attribute is directly updated.
        :rtype: str
        """
        assert self._mdsd_config_xml_tree is not None

        event_volume = LadUtil.getEventVolumeFromLadCfg(lad_cfg)
        if event_volume:
            self._logger_log("Event volume found in ladCfg: " + event_volume)
        else:
            event_volume = self._ext_settings.read_public_config("eventVolume")
            if event_volume:
                self._logger_log("Event volume found in public config: " +
                                 event_volume)
            else:
                event_volume = "Medium"
                self._logger_log(
                    "Event volume not found in config. Using default value: " +
                    event_volume)
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, "Management",
                            "eventVolume", event_volume)
예제 #4
0
    def _update_account_settings(self, account, token, endpoint):
        """
        Update the MDSD configuration Account element with Azure table storage properties.
        Exactly one of (key, token) must be provided.
        :param account: Storage account to which LAD should write data
        :param token: SAS token to access the storage account
        :param endpoint: Identifies the Azure instance (public or specific sovereign cloud) where the storage account is
        """
        assert token, "Token must be given."
        assert self._mdsd_config_xml_tree is not None

        token = self._encrypt_secret_with_cert(token)
        assert token, "Could not encrypt token"
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree,
                            'Accounts/SharedAccessSignature', "account",
                            account, ['isDefault', 'true'])
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree,
                            'Accounts/SharedAccessSignature', "key", token,
                            ['isDefault', 'true'])
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree,
                            'Accounts/SharedAccessSignature', "decryptKeyPath",
                            self._pkey_path, ['isDefault', 'true'])
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree,
                            'Accounts/SharedAccessSignature', "tableEndpoint",
                            endpoint, ['isDefault', 'true'])
        XmlUtil.removeElement(self._mdsd_config_xml_tree, 'Accounts',
                              'Account')
    def _update_perf_counters_settings(self, omi_queries, for_app_insights=False):
        """
        Update the mdsd XML tree with the OMI queries provided.
        :param omi_queries: List of dictionaries specifying OMI queries and destination tables. E.g.:
         [
             {"query":"SELECT PercentAvailableMemory, AvailableMemory, UsedMemory, PercentUsedSwap FROM SCX_MemoryStatisticalInformation","table":"LinuxMemory"},
             {"query":"SELECT PercentProcessorTime, PercentIOWaitTime, PercentIdleTime FROM SCX_ProcessorStatisticalInformation WHERE Name='_TOTAL'","table":"LinuxCpu"},
             {"query":"SELECT AverageWriteTime,AverageReadTime,ReadBytesPerSecond,WriteBytesPerSecond FROM  SCX_DiskDriveStatisticalInformation WHERE Name='_TOTAL'","table":"LinuxDisk"}
         ]
        :param for_app_insights: Indicates whether we are updating perf counters settings for AppInsights.
                                AppInsights requires specific names, so we need this.
        :return: None. The mdsd XML tree member is updated accordingly.
        """
        assert self._mdsd_config_xml_tree is not None

        if not omi_queries:
            return

        mdsd_omi_query_schema = """
<OMIQuery cqlQuery="" dontUsePerNDayTable="true" eventName="" omiNamespace="" priority="High" sampleRateInSeconds="" />
"""

        for omi_query in omi_queries:
            mdsd_omi_query_element = XmlUtil.createElement(mdsd_omi_query_schema)
            mdsd_omi_query_element.set('cqlQuery', omi_query['query'])
            mdsd_omi_query_element.set('eventName', omi_query['table'])
            namespace = omi_query['namespace'] if 'namespace' in omi_query else 'root/scx'
            mdsd_omi_query_element.set('omiNamespace', namespace)
            if for_app_insights:
                AIUtil.updateOMIQueryElement(mdsd_omi_query_element)
            XmlUtil.addElement(xml=self._mdsd_config_xml_tree, path='Events/OMI', el=mdsd_omi_query_element, addOnlyOnce=True)
 def _add_element_from_element(self, path, xml_elem, add_only_once=True):
     """
     Add an XML fragment to the mdsd config document in accordance with path
     :param str path: Where to add the fragment
     :param ElementTree xml_elem: An ElementTree object XML fragment that should be added to the path.
     :param bool add_only_once: Indicates whether to perform the addition only to the first match of the path.
     """
     XmlUtil.addElement(xml=self._mdsd_config_xml_tree, path=path, el=xml_elem, addOnlyOnce=add_only_once)
 def _add_element_from_element(self, path, xml_elem, add_only_once=True):
     """
     Add an XML fragment to the mdsd config document in accordance with path
     :param str path: Where to add the fragment
     :param ElementTree xml_elem: An ElementTree object XML fragment that should be added to the path.
     :param bool add_only_once: Indicates whether to perform the addition only to the first match of the path.
     """
     XmlUtil.addElement(xml=self._mdsd_config_xml_tree, path=path, el=xml_elem, addOnlyOnce=add_only_once)
 def _add_element_from_string(self, path, xml_string, add_only_once=True):
     """
     Add an XML fragment to the mdsd config document in accordance with path
     :param str path: Where to add the fragment
     :param str xml_string: A string containing the XML element to add
     :param bool add_only_once: Indicates whether to perform the addition only to the first match of the path.
     """
     XmlUtil.addElement(xml=self._mdsd_config_xml_tree, path=path, el=ET.fromstring(xml_string),
                        addOnlyOnce=add_only_once)
 def _add_element_from_string(self, path, xml_string, add_only_once=True):
     """
     Add an XML fragment to the mdsd config document in accordance with path
     :param str path: Where to add the fragment
     :param str xml_string: A string containing the XML element to add
     :param bool add_only_once: Indicates whether to perform the addition only to the first match of the path.
     """
     XmlUtil.addElement(xml=self._mdsd_config_xml_tree, path=path, el=ET.fromstring(xml_string),
                        addOnlyOnce=add_only_once)
예제 #10
0
def getResourceId():
    ladCfg = readPublicConfig('ladCfg')
    resourceId = LadUtil.getResourceIdFromLadCfg(ladCfg)
    if not resourceId:
        encodedXmlCfg = readPublicConfig('xmlCfg').strip()
        if encodedXmlCfg:
            xmlCfg = base64.b64decode(encodedXmlCfg)
            resourceId = XmlUtil.getXmlValue(XmlUtil.createElement(xmlCfg),'diagnosticMonitorConfiguration/metrics','resourceId')
# Azure portal uses xmlCfg which contains WadCfg which is pascal case, Currently we will support both casing and deprecate one later
            if not resourceId:
                resourceId = XmlUtil.getXmlValue(XmlUtil.createElement(xmlCfg),'DiagnosticMonitorConfiguration/Metrics','resourceId')
    return resourceId
예제 #11
0
    def anotateIntenal(self, root, elementDataMap):
        top = int(
            XmlUtil.getDipValue(root, Constants.ATTRIBUTE_LAYOUT_MARGIN_TOP))
        left = int(
            XmlUtil.getDipValue(root, Constants.ATTRIBUTE_LAYOUT_MARGIN_LEFT))
        width = int(XmlUtil.getDipValue(root,
                                        Constants.ATTRIBUTE_LAYOUT_WIDTH))
        height = int(
            XmlUtil.getDipValue(root, Constants.ATTRIBUTE_LAYOUT_HEIGHT))

        data = ElementData(top, left, width, height)
        elementDataMap[root] = data
def setEventVolume(mdsdCfg,ladCfg):
    eventVolume = LadUtil.getEventVolumeFromLadCfg(ladCfg)
    if eventVolume:
        hutil.log("Event volume found in ladCfg: " + eventVolume)
    else:
        eventVolume = readPublicConfig("eventVolume")
        if eventVolume:
            hutil.log("Event volume found in public config: " + eventVolume)
        else:
            eventVolume = "Medium"
            hutil.log("Event volume not found in config. Using default value: " + eventVolume)
            
    XmlUtil.setXmlValue(mdsdCfg,"Management","eventVolume",eventVolume)
예제 #13
0
def createPerfSettngs(tree, perfs, forAI=False):
    if not perfs:
        return
    for perf in perfs:
        perfElement = XmlUtil.createElement(perfSchema)
        perfElement.set("cqlQuery", perf["query"])
        perfElement.set("eventName", perf["table"])
        namespace = "root/scx"
        if perf.has_key("namespace"):
            namespace = perf["namespace"]
        perfElement.set("omiNamespace", namespace)
        if forAI:
            AIUtil.updateOMIQueryElement(perfElement)
        XmlUtil.addElement(tree, "Events/OMI", perfElement, ["omitag", "perf"])
예제 #14
0
def createEventFileSettings(tree, files):
    fileid = 0
    sysconfig = """
$ModLoad imfile

                """
    if not files:
        return
    for file in files:
        fileid = fileid + 1
        eventSourceElement = XmlUtil.createElement(eventSourceSchema)
        XmlUtil.setXmlValue(eventSourceElement, 'RouteEvent', 'eventName',
                            file["table"])
        eventSourceElement.set('source', 'ladfile' + str(fileid))
        XmlUtil.addElement(tree, 'Events/MdsdEvents', eventSourceElement)

        sourceElement = XmlUtil.createElement(sourceSchema)
        sourceElement.set('name', 'ladfile' + str(fileid))
        XmlUtil.addElement(tree, 'Sources', sourceElement)

        syslog_config = syslogEventSourceConfig.replace('#FILE#', file['file'])
        syslog_config = syslog_config.replace('#STATFILE#',
                                              file['file'].replace("/", "-"))
        syslog_config = syslog_config.replace('#FILETAG#',
                                              'ladfile' + str(fileid))
        sysconfig += syslog_config
    return sysconfig
 def _add_derived_event(self, interval, source, event_name, store_type, add_lad_query=False):
     """
     Add a <DerivedEvent> element to the configuration
     :param str interval: Interval at which this DerivedEvent should be run 
     :param str source: Local table from which this DerivedEvent should pull
     :param str event_name: Destination table to which this DerivedEvent should push
     :param str store_type: The storage type of the destination table, e.g. Local, Central, JsonBlob
     :param bool add_lad_query: True if a <LadQuery> subelement should be added to this <DerivedEvent> element
     """
     derived_event = mxt.derived_event.format(interval=interval, source=source, target=event_name, type=store_type)
     element = ET.fromstring(derived_event)
     if add_lad_query:
         XmlUtil.addElement(element, ".", ET.fromstring(mxt.lad_query))
     self._add_element_from_element('Events/DerivedEvents', element)
예제 #16
0
 def _add_derived_event(self, interval, source, event_name, store_type, add_lad_query=False):
     """
     Add a <DerivedEvent> element to the configuration
     :param str interval: Interval at which this DerivedEvent should be run 
     :param str source: Local table from which this DerivedEvent should pull
     :param str event_name: Destination table to which this DerivedEvent should push
     :param str store_type: The storage type of the destination table, e.g. Local, Central, JsonBlob
     :param bool add_lad_query: True if a <LadQuery> subelement should be added to this <DerivedEvent> element
     """
     derived_event = mxt.derived_event.format(interval=interval, source=source, target=event_name, type=store_type)
     element = ET.fromstring(derived_event)
     if add_lad_query:
         XmlUtil.addElement(element, ".", ET.fromstring(mxt.lad_query))
     self._add_element_from_element('Events/DerivedEvents', element)
def createPerfSettngs(tree,perfs,forAI=False):
    if not perfs:
        return
    for perf in perfs:
        perfElement = XmlUtil.createElement(perfSchema)
        perfElement.set('cqlQuery',perf['query'])
        perfElement.set('eventName',perf['table'])
        namespace="root/scx"
        if perf.has_key('namespace'):
           namespace=perf['namespace']
        perfElement.set('omiNamespace',namespace)
        if forAI:
            AIUtil.updateOMIQueryElement(perfElement)
        XmlUtil.addElement(tree,'Events/OMI',perfElement,["omitag","perf"])
    def _set_xml_attr(self, key, value, xml_path, selector=[]):
        """
        Set XML attribute on the element specified with xml_path.
        :param key: The attribute name to set on the XML element.
        :param value: The default value to be set, if there's no public config for that attribute.
        :param xml_path: The path of the XML element(s) to which the attribute is applied.
        :param selector: Selector for finding the actual XML element (see XmlUtil.setXmlValue)
        :return: None. Change is directly applied to mdsd_config_xml_tree XML member object.
        """
        assert self._mdsd_config_xml_tree is not None

        v = self._ext_settings.read_public_config(key)
        if not v:
            v = value
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, xml_path, key, v, selector)
예제 #19
0
    def _set_xml_attr(self, key, value, xml_path, selector=[]):
        """
        Set XML attribute on the element specified with xml_path.
        :param key: The attribute name to set on the XML element.
        :param value: The default value to be set, if there's no public config for that attribute.
        :param xml_path: The path of the XML element(s) to which the attribute is applied.
        :param selector: Selector for finding the actual XML element (see XmlUtil.setXmlValue)
        :return: None. Change is directly applied to mdsd_config_xml_tree XML member object.
        """
        assert self._mdsd_config_xml_tree is not None

        v = self._ext_settings.read_public_config(key)
        if not v:
            v = value
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, xml_path, key, v, selector)
예제 #20
0
 def generate_omi_query_xml_elem(omi_query, sink=()):
     """
     Helper for generating OMI event XML element
     :param omi_query: Python dictionary object for the raw OMI query specified as a LAD 3.0 perfCfg array item
     :param sink: (name, type) tuple for this OMI query. Not specified implies default XTable sink
     :return: An XML element object for this OMI event that should be added to the mdsd XML cfg tree
     """
     omi_xml_schema = """
     <OMIQuery cqlQuery="" dontUsePerNDayTable="true" eventName="" omiNamespace="" priority="High" sampleRateInSeconds="" storeType="" />
     """ if sink else """
     <OMIQuery cqlQuery="" dontUsePerNDayTable="true" eventName="" omiNamespace="" priority="High" sampleRateInSeconds="" />
     """
     xml_elem = XmlUtil.createElement(omi_xml_schema)
     xml_elem.set('cqlQuery', omi_query['query'])
     xml_elem.set('eventName', sink[0] if sink else omi_query['table'])
     # Default OMI namespace is 'root/scx'
     xml_elem.set(
         'omiNamespace', omi_query['namespace']
         if 'namespace' in omi_query else 'root/scx')
     # Default query frequency is 300 seconds
     xml_elem.set(
         'sampleRateInSeconds',
         str(omi_query['frequency'])
         if 'frequency' in omi_query else '300')
     if sink:
         xml_elem.set('storeType',
                      'local' if sink[1] == 'EventHub' else sink[1])
     return xml_elem
예제 #21
0
    def createDocument(self):
        #        self.writeHierarchyLog("Un Categorized")
        self.pruneBasic(self.mRootView)
        #        self.writeHierarchyLog("Categorized")

        #        self.pruneToCreateGroupText(self.mRootView)

        #        self.pruneToCreateListItemsHasDrawable(self.mRootView, self.mDrawableMap.values(), 0)

        #        self.pruneToCreateListItemsHasViewsSameSize(self.mRootView, self.mDrawableMap.values(), self.mDefaultAlignThreshold)

        for i in range(len(self.mListViews)):
            listMetadata = self.mListViews[i]
            self.updateListContent(listMetadata, i)

        _map = {}

        #        self.updateColorBackground(self.mRootView)

        rootElement = XmlUtil.createRoot(self.mDipCalculator,
                                         LayoutHelper.FRAMELAYOUT_ELEMENT,
                                         self.mRootView, self.mColorWriter)
        self.addChildrenLayout(rootElement, self.mRootView, 0, 0, _map)

        return rootElement
    def _update_and_get_file_monitoring_settings(self, files):
        """
        Update mdsd config's file monitoring config. Also creates/returns rsyslog imfile config.
        All the operations are based on the input param files, which is a Json-deserialized dictionary
        corresponding the following Json array example:
        [
            {"file":"/var/log/a.log", "table":"aLog"},
            {"file":"/var/log/b.log", "table":"bLog"}
        ]
        :param files: Array of dictionaries deserialized from the 'fileCfg' Json config (example as above)
        :return: rsyslog omfile module config file content
        """
        assert self._mdsd_config_xml_tree is not None

        if not files:
            return ''

        file_id = 0
        imfile_config = """
$ModLoad imfile

"""

        mdsd_event_source_schema = """
<MdsdEventSource source="ladfile">
    <RouteEvent dontUsePerNDayTable="true" eventName="" priority="High"/>
</MdsdEventSource>
"""

        mdsd_source_schema = """
<Source name="ladfile1" schema="ladfile" />
"""
        imfile_per_file_config_template = """
$InputFileName #FILE#
$InputFileTag #FILETAG#
$InputFileFacility local6
$InputFileStateFile syslog-stat#STATFILE#
$InputFileSeverity debug
$InputRunFileMonitor
"""

        for item in files:
            file_id += 1
            mdsd_event_source_element = XmlUtil.createElement(mdsd_event_source_schema)
            XmlUtil.setXmlValue(mdsd_event_source_element, 'RouteEvent', 'eventName', item["table"])
            mdsd_event_source_element.set('source', 'ladfile'+str(file_id))
            XmlUtil.addElement(self._mdsd_config_xml_tree, 'Events/MdsdEvents', mdsd_event_source_element)

            mdsd_source_element = XmlUtil.createElement(mdsd_source_schema)
            mdsd_source_element.set('name', 'ladfile'+str(file_id))
            XmlUtil.addElement(self._mdsd_config_xml_tree, 'Sources', mdsd_source_element)

            imfile_per_file_config = imfile_per_file_config_template.replace('#FILE#', item['file'])
            imfile_per_file_config = imfile_per_file_config.replace('#STATFILE#', item['file'].replace("/","-"))
            imfile_per_file_config = imfile_per_file_config.replace('#FILETAG#', 'ladfile'+str(file_id))
            imfile_config += imfile_per_file_config
        return imfile_config
 def get_resource_id(self):
     """
     Try to get resourceId from LadCfg. If not present, try to fetch from xmlCfg.
     """
     lad_cfg = self.read_public_config('ladCfg')
     resource_id = LadUtil.getResourceIdFromLadCfg(lad_cfg)
     if not resource_id:
         encoded_xml_cfg = self.read_public_config('xmlCfg').strip()
         if encoded_xml_cfg:
             xml_cfg = base64.b64decode(encoded_xml_cfg)
             resource_id = XmlUtil.getXmlValue(XmlUtil.createElement(xml_cfg),
                                               'diagnosticMonitorConfiguration/metrics', 'resourceId')
             # Azure portal uses xmlCfg which contains WadCfg which is pascal case
             # Currently we will support both casing and deprecate one later
             if not resource_id:
                 resource_id = XmlUtil.getXmlValue(XmlUtil.createElement(xml_cfg),
                                                   'DiagnosticMonitorConfiguration/Metrics', 'resourceId')
     return resource_id
예제 #24
0
def setEventVolume(mdsdCfg, ladCfg):
    """
    Set event volume in mdsd config. Check if desired event volume is specified, first in ladCfg then in public config.
    :param mdsdCfg: The XML document holding the mdsd config
    :param ladCfg: The ladCfg part of the public config
    :return: The event volume. If not set anywhere in public config, return "Medium"
    :rtype: str
    """
    eventVolume = LadUtil.getEventVolumeFromLadCfg(ladCfg)
    if eventVolume:
        hutil.log("Event volume found in ladCfg: " + eventVolume)
    else:
        eventVolume = readPublicConfig("eventVolume")
        if eventVolume:
            hutil.log("Event volume found in public config: " + eventVolume)
        else:
            eventVolume = "Medium"
            hutil.log("Event volume not found in config. Using default value: " + eventVolume)

    XmlUtil.setXmlValue(mdsdCfg, "Management", "eventVolume", eventVolume)
    def _set_event_volume(self, lad_cfg):
        """
        Set event volume in mdsd config. Check if desired event volume is specified,
        first in ladCfg then in public config. If in neither then default to Medium.
        :param lad_cfg: 'ladCfg' Json object to look up for the event volume setting.
        :return: None. The mdsd config XML tree's eventVolume attribute is directly updated.
        :rtype: str
        """
        assert self._mdsd_config_xml_tree is not None

        event_volume = LadUtil.getEventVolumeFromLadCfg(lad_cfg)
        if event_volume:
            self._logger_log("Event volume found in ladCfg: " + event_volume)
        else:
            event_volume = self._ext_settings.read_public_config("eventVolume")
            if event_volume:
                self._logger_log("Event volume found in public config: " + event_volume)
            else:
                event_volume = "Medium"
                self._logger_log("Event volume not found in config. Using default value: " + event_volume)
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, "Management", "eventVolume", event_volume)
예제 #26
0
def UpdateXML(doc):
    """
    Add to the mdsd XML the minimal set of OMI queries which will retrieve the metrics requested via AddMetric(). This
    provider doesn't need any configuration external to mdsd; if it did, that would be generated here as well.

    :param doc: XML document object to be updated
    :return: None
    """
    global _metrics, _eventNames, _omiClassName
    for group in _metrics:
        (class_name, condition_clause, sample_rate) = group
        if not condition_clause:
            condition_clause = default_condition(class_name)
        columns = []
        mappings = []
        for metric in _metrics[group]:
            omi_name = metric.counter_name()
            scale = _scaling[class_name][omi_name]
            columns.append(omi_name)
            mappings.append('<MapName name="{0}" {1}>{2}</MapName>'.format(omi_name, scale, metric.label()))
        column_string = ','.join(columns)
        if condition_clause:
            cql_query = quoteattr("SELECT {0} FROM {1} WHERE {2}".format(column_string,
                                                                         _omiClassName[class_name], condition_clause))
        else:
            cql_query = quoteattr("SELECT {0} FROM {1}".format(column_string, _omiClassName[class_name]))
        query = '''
<OMIQuery cqlQuery={qry} eventName={evname} omiNamespace="root/scx" sampleRateInSeconds="{rate}" storeType="local">
  <Unpivot columnName="CounterName" columnValue="Value" columns={columns}>
    {mappings}
  </Unpivot>
</OMIQuery>'''.format(
            qry=cql_query,
            evname=quoteattr(_eventNames[group]),
            columns=quoteattr(column_string),
            rate=sample_rate,
            mappings='\n    '.join(mappings)
        )
        XmlUtil.addElement(doc, 'Events/OMI', ET.fromstring(query))
    return
예제 #27
0
def createPortalSettings(tree, resourceId):
    portal_config = ET.ElementTree()
    portal_config.parse(os.path.join(WorkDir, "portal.xml.template"))
    XmlUtil.setXmlValue(portal_config, "./DerivedEvents/DerivedEvent/LADQuery",
                        "partitionKey", resourceId)
    XmlUtil.addElement(tree, 'Events', portal_config._root.getchildren()[0])
    XmlUtil.addElement(tree, 'Events', portal_config._root.getchildren()[1])
예제 #28
0
def UpdateXML(doc):
    """
    Add to the mdsd XML the minimal set of OMI queries which will retrieve the metrics requested via AddMetric(). This
    provider doesn't need any configuration external to mdsd; if it did, that would be generated here as well.

    :param doc: XML document object to be updated
    :return: None
    """
    global _metrics, _eventNames, _omiClassName
    for group in _metrics:
        (class_name, condition_clause, sample_rate) = group
        if not condition_clause:
            condition_clause = default_condition(class_name)
        columns = []
        mappings = []
        for metric in _metrics[group]:
            omi_name = metric.counter_name()
            scale = _scaling[class_name][omi_name]
            columns.append(omi_name)
            mappings.append('<MapName name="{0}" {1}>{2}</MapName>'.format(
                omi_name, scale, metric.label()))
        column_string = ','.join(columns)
        if condition_clause:
            cql_query = quoteattr("SELECT {0} FROM {1} WHERE {2}".format(
                column_string, _omiClassName[class_name], condition_clause))
        else:
            cql_query = quoteattr("SELECT {0} FROM {1}".format(
                column_string, _omiClassName[class_name]))
        query = '''
<OMIQuery cqlQuery={qry} eventName={evname} omiNamespace="root/scx" sampleRateInSeconds="{rate}" storeType="local">
  <Unpivot columnName="CounterName" columnValue="Value" columns={columns}>
    {mappings}
  </Unpivot>
</OMIQuery>'''.format(qry=cql_query,
                      evname=quoteattr(_eventNames[group]),
                      columns=quoteattr(column_string),
                      rate=sample_rate,
                      mappings='\n    '.join(mappings))
        XmlUtil.addElement(doc, 'Events/OMI', ET.fromstring(query))
    return
def createAccountSettings(tree,account,key,endpoint,aikey=None):
    XmlUtil.setXmlValue(tree,'Accounts/Account',"account",account,['isDefault','true'])
    XmlUtil.setXmlValue(tree,'Accounts/Account',"key",key,['isDefault','true'])
    XmlUtil.setXmlValue(tree,'Accounts/Account',"tableEndpoint",endpoint,['isDefault','true'])
    
    if aikey:
        AIUtil.createAccountElement(tree,aikey)
    def _update_account_settings(self, account, token, endpoint):
        """
        Update the MDSD configuration Account element with Azure table storage properties.
        Exactly one of (key, token) must be provided.
        :param account: Storage account to which LAD should write data
        :param token: SAS token to access the storage account
        :param endpoint: Identifies the Azure instance (public or specific sovereign cloud) where the storage account is
        """
        assert token, "Token must be given."
        assert self._mdsd_config_xml_tree is not None

        token = self._encrypt_secret_with_cert(token)
        assert token, "Could not encrypt token"
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                            "account", account, ['isDefault', 'true'])
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                            "key", token, ['isDefault', 'true'])
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                            "decryptKeyPath", self._pkey_path, ['isDefault', 'true'])
        XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                            "tableEndpoint", endpoint, ['isDefault', 'true'])
        XmlUtil.removeElement(self._mdsd_config_xml_tree, 'Accounts', 'Account')
예제 #31
0
    def updateMargin(root, attributeLayoutPaddingName, attributeLayoutMarginName) :
#		@SuppressWarnings("unchecked")
        elements = [elem for elem in root.iter()]
        
        if (len(elements) == 0) :
            return
		
		# Check if all children have margin dip value
        for node in elements:
            element = Element (node)
            if (not XmlUtil.hasDipValue(element, attributeLayoutMarginName)) :
                return
			
		

        paddingValue = 0
        if (XmlUtil.hasDipValue(root, attributeLayoutPaddingName)) :
            paddingValue = XmlUtil.getDipValue(root, attributeLayoutPaddingName)
		
		# find min margin
        minMargin = sys.maxint
        for node in elements:
            element = Element(node)
            minMargin = min(minMargin, XmlUtil.getDipValue(element,attributeLayoutMarginName))
		
		# we add more margin to the parent
        paddingValue += paddingValue + minMargin

        if (paddingValue == 0) :
            return
		

        root.addAttribute(attributeLayoutPaddingName, paddingValue + Constants.UNIT_DIP)

		# we subtract margin from children
        for node in elements:
            element = Element(node)
            root.set(attributeLayoutMarginName, XmlUtil.getDipValue(element, attributeLayoutMarginName) - minMargin + Constants.UNIT_DIP)
예제 #32
0
def generateProject(rectViews, projectFolder, templateFolder, canvas_width,  projectName="SketchToUI"):
    CANVAS_WIDTH = canvas_width
    dipCalulator = SketchDipCalculator(CANVAS_WIDTH, CANVAS_HEIGHT)
    
    mOutProjectFolder =  os.path.join(projectFolder,projectName )
    
    rawRects = jsonToRect(rectViews,dipCalulator)
    
#    return 
    rootView = createHierachy(rawRects, CANVAS_WIDTH,CANVAS_HEIGHT)
    
    mProjectName = generateProjectName(projectName)


    
    SketchProjectGenerator.setup(projectFolder, templateFolder)
   
    
#    mDrawableWriter = DrawableWriter(file_extension, mOutProjectFolder)
    creator = SketchLayoutCreator(rootView, mProjectName, mOutProjectFolder,dipCalulator)

# create layout
    layoutDocument = creator.createDocument()
    layoutFilter = SketchLayoutFilter()
#
    anotateMap = layoutFilter.anotate(layoutDocument)

    layoutFilter = SketchRelativeLayoutFilter()
    layoutFilter.doFilter(layoutDocument, anotateMap)
    layoutFilter = SketchLayoutFilter()
    layoutFilter.doFilter(layoutDocument, anotateMap)
    mainXmlPath = os.path.join(mOutProjectFolder,"app", "src","main", "res", "layout", "activity_main.xml")

# write to xml
    XmlUtil.writeDocumentxml(layoutDocument,mainXmlPath)

# write style
#    styleWriter = creator.mStyleWriter
#    styleDocument = styleWriter.mRoot
#    styleDocumentPath = os.path.join(mOutProjectFolder, "app", "src","main","res","values","styles.xml")
#    XmlUtil.writeDocumentxml(styleDocument, styleDocumentPath)
#
#write to color file    
    colorWriter = creator.mColorWriter
    colorDocument = colorWriter.mRoot
    colorDocumentPath = os.path.join(mOutProjectFolder, "app", "src","main","res","values","colors.xml")
    XmlUtil.writeDocumentxml(colorDocument, colorDocumentPath)

# write to string file
    stringWriter = creator.mWriter
    resourceDocument = stringWriter.mRoot
    stringDocumentPath = os.path.join(mOutProjectFolder, "app", "src","main","res","values","strings.xml")
    XmlUtil.writeDocumentxml(resourceDocument, stringDocumentPath)
    SketchProjectGenerator.prepareProject(projectFolder, projectName)

    return 
예제 #33
0
    def createDocument(self):
        _map = {}
        # create root element
        rootElement = XmlUtil.createSketchRoot(
            self.mDipCalculator, LayoutHelper.FRAMELAYOUT_ELEMENT,
            self.mRootView, self.mColorWriter)
        #  To fix the style color
        color = ColorUtil.cColortoInt(CColor.Black)
        self.mColorWriter.addResource(selectColorMode(color))
        color = ColorUtil.cColortoInt(CColor.Cyan)
        self.mColorWriter.addResource(selectColorMode(color))

        # add childeren to the layout
        self.addChildrenLayout(rootElement, self.mRootView, 0, 0, _map)

        return rootElement
    def _add_portal_settings(self, resource_id):
        """
        Update mdsd_config_xml_tree for Azure Portal metric collection setting.
        It's basically applying the resource_id as the partitionKey attribute of LADQuery elements.

        :param resource_id: ARM rerousce ID to provide as partitionKey in LADQuery elements
        :return: None
        """
        assert self._mdsd_config_xml_tree is not None

        portal_config = ET.ElementTree()
        portal_config.parse(os.path.join(self._ext_dir, 'portal.xml.template'))
        XmlUtil.setXmlValue(portal_config, './DerivedEvents/DerivedEvent/LADQuery', 'partitionKey', resource_id)
        XmlUtil.addElement(self._mdsd_config_xml_tree, 'Events', portal_config._root.getchildren()[0])
        XmlUtil.addElement(self._mdsd_config_xml_tree, 'Events', portal_config._root.getchildren()[1])
 def generate_omi_query_xml_elem(omi_query, sink=()):
     """
     Helper for generating OMI event XML element
     :param omi_query: Python dictionary object for the raw OMI query specified as a LAD 3.0 perfCfg array item
     :param sink: (name, type) tuple for this OMI query. Not specified implies default XTable sink
     :return: An XML element object for this OMI event that should be added to the mdsd XML cfg tree
     """
     omi_xml_schema = """
     <OMIQuery cqlQuery="" dontUsePerNDayTable="true" eventName="" omiNamespace="" priority="High" sampleRateInSeconds="" storeType="" />
     """ if sink else """
     <OMIQuery cqlQuery="" dontUsePerNDayTable="true" eventName="" omiNamespace="" priority="High" sampleRateInSeconds="" />
     """
     xml_elem = XmlUtil.createElement(omi_xml_schema)
     xml_elem.set('cqlQuery', omi_query['query'])
     xml_elem.set('eventName', sink[0] if sink else omi_query['table'])
     # Default OMI namespace is 'root/scx'
     xml_elem.set('omiNamespace', omi_query['namespace'] if 'namespace' in omi_query else 'root/scx')
     # Default query frequency is 300 seconds
     xml_elem.set('sampleRateInSeconds', str(omi_query['frequency']) if 'frequency' in omi_query else '300')
     if sink:
         xml_elem.set('storeType', 'local' if sink[1] == 'EventHub' else sink[1])
     return xml_elem
예제 #36
0
def createEventFileSettings(tree, files):
    fileid = 0
    sysconfig = """
$ModLoad imfile

                """
    if not files:
        return
    for file in files:
        fileid = fileid + 1
        eventSourceElement = XmlUtil.createElement(eventSourceSchema)
        XmlUtil.setXmlValue(eventSourceElement, "RouteEvent", "eventName", file["table"])
        eventSourceElement.set("source", "ladfile" + str(fileid))
        XmlUtil.addElement(tree, "Events/MdsdEvents", eventSourceElement)

        sourceElement = XmlUtil.createElement(sourceSchema)
        sourceElement.set("name", "ladfile" + str(fileid))
        XmlUtil.addElement(tree, "Sources", sourceElement)

        syslog_config = syslogEventSourceConfig.replace("#FILE#", file["file"])
        syslog_config = syslog_config.replace("#STATFILE#", file["file"].replace("/", "-"))
        syslog_config = syslog_config.replace("#FILETAG#", "ladfile" + str(fileid))
        sysconfig += syslog_config
    return sysconfig
예제 #37
0
def createEventFileSettings(tree,files):
    fileid = 0;
    sysconfig = """
$ModLoad imfile

                """
    if not files:
        return
    for file in files:
        fileid=fileid+1
        eventSourceElement = XmlUtil.createElement(eventSourceSchema)
        XmlUtil.setXmlValue(eventSourceElement,'RouteEvent','eventName',file["table"])
        eventSourceElement.set('source','ladfile'+str(fileid))
        XmlUtil.addElement(tree,'Events/MdsdEvents',eventSourceElement)

        sourceElement = XmlUtil.createElement(sourceSchema)
        sourceElement.set('name','ladfile'+str(fileid))
        XmlUtil.addElement(tree,'Sources',sourceElement)

        syslog_config = syslogEventSourceConfig.replace('#FILE#',file['file'])
        syslog_config = syslog_config.replace('#STATFILE#',file['file'].replace("/","-"))
        syslog_config = syslog_config.replace('#FILETAG#','ladfile'+str(fileid))
        sysconfig+=syslog_config
    return sysconfig
    def generate_all_configs(self):
        """
        Generates configs for all components required by LAD.
        Generates XML cfg file for mdsd, from JSON config settings (public & private).
        Also generates rsyslog/syslog-ng configs corresponding to 'syslogEvents' or 'syslogCfg' setting.
        Also generates fluentd's syslog/tail src configs and out_mdsd configs.
        The rsyslog/syslog-ng and fluentd configs are not yet saved to files. They are available through
        the corresponding getter methods of this class (get_fluentd_*_config(), get_*syslog*_config()).

        Returns (True, '') if config was valid and proper xmlCfg.xml was generated.
        Returns (False, '...') if config was invalid and the error message.
        """

        # 1. Add DeploymentId (if available) to identity columns
        if self._deployment_id:
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, "Management/Identity/IdentityComponent", "",
                                self._deployment_id, ["name", "DeploymentId"])
        # 2. Use ladCfg to generate OMIQuery and LADQuery elements
        lad_cfg = self._ladCfg()
        if lad_cfg:
            try:
                self._update_metric_collection_settings(lad_cfg)
                resource_id = self._ext_settings.get_resource_id()
                if resource_id:
                    XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Events/DerivedEvents/DerivedEvent/LADQuery',
                                        'partitionKey', escape_nonalphanumerics(resource_id))
                    lad_query_instance_id = ""
                    uuid_for_instance_id = self._fetch_uuid()
                    if resource_id.find("providers/Microsoft.Compute/virtualMachineScaleSets") >= 0:
                        lad_query_instance_id = uuid_for_instance_id
                    self._set_xml_attr("instanceID", lad_query_instance_id, "Events/DerivedEvents/DerivedEvent/LADQuery")
                    # Set JsonBlob sink-related elements
                    self._add_obo_field(name='resourceId', value=resource_id)
                    self._add_obo_field(name='agentIdentityHash', value=uuid_for_instance_id)

            except Exception as e:
                self._logger_error("Failed to create portal config  error:{0} {1}".format(e, traceback.format_exc()))
                return False, 'Failed to create portal config from ladCfg (see extension error logs for more details)'

        # 3. Generate config for perfCfg. Need to distinguish between non-AppInsights scenario and AppInsights scenario,
        #    so check if Application Insights key is present and pass it to the actual helper
        #    function (self._apply_perf_cfg()).
        try:
            self._apply_perf_cfg()
        except Exception as e:
            self._logger_error("Failed check for Application Insights key in LAD configuration with exception:{0}\n"
                               "Stacktrace: {1}".format(e, traceback.format_exc()))
            return False, 'Failed to update perf counter config (see extension error logs for more details)'

        # 4. Generate omsagent (fluentd) configs, rsyslog/syslog-ng config, and update corresponding mdsd config XML
        try:
            syslogEvents_setting = self._ext_settings.get_syslogEvents_setting()
            fileLogs_setting = self._ext_settings.get_fileLogs_setting()
            lad_logging_config_helper = LadLoggingConfig(syslogEvents_setting, fileLogs_setting, self._sink_configs,
                                                         self._pkey_path, self._cert_path, self._encrypt_secret)
            mdsd_syslog_config = lad_logging_config_helper.get_mdsd_syslog_config()
            mdsd_filelog_config = lad_logging_config_helper.get_mdsd_filelog_config()
            copy_source_mdsdevent_eh_url_elems(self._mdsd_config_xml_tree, mdsd_syslog_config)
            copy_source_mdsdevent_eh_url_elems(self._mdsd_config_xml_tree, mdsd_filelog_config)
            self._fluentd_syslog_src_config = lad_logging_config_helper.get_fluentd_syslog_src_config()
            self._fluentd_tail_src_config = lad_logging_config_helper.get_fluentd_filelog_src_config()
            self._fluentd_out_mdsd_config = lad_logging_config_helper.get_fluentd_out_mdsd_config()
            self._rsyslog_config = lad_logging_config_helper.get_rsyslog_config()
            self._syslog_ng_config = lad_logging_config_helper.get_syslog_ng_config()
        except Exception as e:
            self._logger_error("Failed to create omsagent (fluentd), rsyslog/syslog-ng configs or to update "
                               "corresponding mdsd config XML. Error: {0}\nStacktrace: {1}"
                               .format(e, traceback.format_exc()))
            return False, 'Failed to generate configs for fluentd, syslog, and mdsd ' \
                          '(see extension error logs for more details)'

        # 5. Before starting to update the storage account settings, log extension's entire settings
        #    with secrets redacted, for diagnostic purpose.
        self._ext_settings.log_ext_settings_with_secrets_redacted(self._logger_log, self._logger_error)

        # 6. Actually update the storage account settings on mdsd config XML tree (based on extension's
        #    protectedSettings).
        account = self._ext_settings.read_protected_config('storageAccountName').strip()
        if not account:
            return False, "Must specify storageAccountName"
        if self._ext_settings.read_protected_config('storageAccountKey'):
            return False, "The storageAccountKey protected setting is not supported and must not be used"
        token = self._ext_settings.read_protected_config('storageAccountSasToken').strip()
        if not token or token == '?':
            return False, "Must specify storageAccountSasToken"
        if '?' == token[0]:
            token = token[1:]
        endpoint = get_storage_endpoint_with_account(account,
                                                     self._ext_settings.read_protected_config('storageAccountEndPoint'))
        self._update_account_settings(account, token, endpoint)

        # 7. Update mdsd config XML's eventVolume attribute based on the logic specified in the helper.
        self._set_event_volume(lad_cfg)

        # 8. Finally generate mdsd config XML file out of the constructed XML tree object.
        self._mdsd_config_xml_tree.write(os.path.join(self._ext_dir, 'xmlCfg.xml'))

        return True, ""
def createAccountElement(mdsdCfg, aikey):
    aiAccountElement = XmlUtil.createElement("<Account moniker=\"appinsights\" appInsightsKey=\"" + aikey + "\"/>");
    XmlUtil.addElement(mdsdCfg,'Accounts',aiAccountElement)
def config(xmltree,key,value,xmlpath,selector=[]):
    v = readPublicConfig(key)
    if not v:
        v = value
    XmlUtil.setXmlValue(xmltree,xmlpath,key,v,selector)
def createSyslogRouteEventElement(mdsdCfg):
    aiSyslogRouteEvent = XmlUtil.createElement("<RouteEvent eventName=\"aiSyslogRouteEvent\" priority=\"High\" account=\"appinsights\" storeType=\"appinsights\"/>");
    XmlUtil.addElement(mdsdCfg,'Events/MdsdEvents/MdsdEventSource',aiSyslogRouteEvent,['source','syslog'])
예제 #42
0
    def addChildrenLayout(self, element, rectView, parentLeft, parentTop,
                          rectViewElementInfoMap):
        # Setting background
        if (self.useTransparentBackground(rectView)):
            XmlUtil.addBackgroundColor(element,
                                       ColorUtil.toInt(0, 255, 255, 255),
                                       self.mColorWriter)
#        elif (RectViewTypes.isContanerView(rectView)) :
# We always want to genenate background regard less of the respect
# ratioand Environment.get().getValue(Environment.KEY_KEEP_ASPECT_RATIO) == Boolean.TRUE
# We will not do this if ratio is between input image and output is the same
#            bound = ImageUtil.getImageFromRect(self.mImage, rectView)
#            # We remove children here using 4 layer channel So we have to make sure that when we save it we will not Adding anymore layer
#            newImageBackground = ImageUtil.removeChildren(bound, rectView)
#            drawableId = self.mDrawableWriter.addResourceDirectly(newImageBackground, rectView)
#            XmlUtil.addBackroundImage(element, drawableId)

        else:
            XmlUtil.addBackgroundColor(element, rectView.mColor,
                                       self.mColorWriter)

        for childRectView in rectView.mChildren:
            _id = ""
            # list view has it own index
            if (childRectView.mType == RectViewTypes.VIEW_TYPE_LIST):
                _id = childRectView.mListInfo.xmlId
            else:
                _id = self.getId(LayoutHelper.FRAMELAYOUT_ELEMENT,
                                 childRectView)

            marginLeft = childRectView.x - parentLeft
            marginTop = childRectView.y - parentTop
            childElement = None
            if (self.useTransparentBackground(childRectView)):
                childElement = XmlUtil.addElement(
                    self.mDipCalculator, element,
                    self.getElementTypeForRect(childRectView), childRectView,
                    marginLeft, marginTop, _id)
            else:
                childElement = XmlUtil.addElement(
                    self.mDipCalculator, element,
                    self.getElementTypeForRect(childRectView), childRectView,
                    marginLeft, marginTop, _id, self.mColorWriter)

            rectViewElementInfoMap[childRectView] = ElementInfo(
                childElement, _id)
            self.addChildrenLayout(childElement, childRectView,
                                   childRectView.x, childRectView.y,
                                   rectViewElementInfoMap)

        # image view
        if (rectView.mType == RectViewTypes.VIEW_TYPE_IMAGE):
            drawableId = self.interestedIcons.get(rectView.mImageInfo.iconInfo)
            element.tag = Constants.ELEMENT_IMAGE_VIEW
            XmlUtil.addImageDrawable(element, drawableId)
            # override attributes
            XmlUtil.removeAttribute(element, Constants.ATTRIBUTE_BACKGROUND)
            _id = self.getId(Constants.ELEMENT_IMAGE_VIEW, rectView)
            XmlUtil.addId(element, _id)
            XmlUtil.addScaleType(element, "fitXY")
            rectViewElementInfoMap[rectView] = ElementInfo(element, _id)
        elif (rectView.mType == RectViewTypes.VIEW_TYPE_TEXT):

            textWrapper = rectView.mTextInfo.textWrapper
            stringId = self.mWriter.addResource(textWrapper.text)
            rectView.mTextInfo._id = stringId
            element.tag = Constants.ELEMENT_TEXT_VIEW
            if (Environment.getValue(
                    Environment.KEY_TEXT_WIDTH_WRAP_CONTENT) == True):
                XmlUtil.addSize(self.mDipCalculator, element,
                                Constants.ATTRIBUTE_WRAP_CONTENT,
                                rectView.height)
            else:
                XmlUtil.addSize(self.mDipCalculator, element, rectView.width,
                                rectView.height)

            XmlUtil.addBackgroundColor(element, rectView.mColor,
                                       self.mColorWriter)
            element.set(Constants.ATTRIBUTE_TEXT,
                        XmlUtil.getReferenceResourceId(stringId))
            _id = self.getId(Constants.ELEMENT_TEXT_VIEW, rectView)
            XmlUtil.addId(element, _id)
            textAttributes = textWrapper.getTextAttributes(
                self.mOcr, rectView.height)
            XmlUtil.addTextColor(element, rectView.textColor,
                                 self.mColorWriter)
            stypeId = self.mStyleWriter.addResource(textAttributes)
            element.set(Constants.ATTRIBUTE_STYLE,
                        XmlUtil.getReferenceStyleId(stypeId))
            rectViewElementInfoMap[rectView] = ElementInfo(element, _id)
예제 #43
0
def createPortalSettings(tree,resourceId):
    portal_config = ET.ElementTree()
    portal_config.parse(os.path.join(WorkDir, "portal.xml.template"))
    XmlUtil.setXmlValue(portal_config,"./DerivedEvents/DerivedEvent/LADQuery","partitionKey",resourceId)
    XmlUtil.addElement(tree,'Events',portal_config._root.getchildren()[0])
    XmlUtil.addElement(tree,'Events',portal_config._root.getchildren()[1])
예제 #44
0
def configSettings():
    '''
    Generates XML cfg file for mdsd, from JSON config settings (public & private).
    Returns (True, '') if config was valid and proper xmlCfg.xml was generated.
    Returns (False, '...') if config was invalid and the error message.
    '''
    mdsdCfgstr = readPublicConfig('mdsdCfg')
    if not mdsdCfgstr:
        with open(os.path.join(WorkDir, './mdsdConfig.xml.template'),"r") as defaulCfg:
            mdsdCfgstr = defaulCfg.read()
    else:
        mdsdCfgstr = base64.b64decode(mdsdCfgstr)
    mdsdCfg = ET.ElementTree()
    mdsdCfg._setroot(XmlUtil.createElement(mdsdCfgstr))

    # update deployment id
    deployment_id = get_deployment_id()
    XmlUtil.setXmlValue(mdsdCfg, "Management/Identity/IdentityComponent", "", deployment_id, ["name", "DeploymentId"])

    try:
        resourceId = getResourceId()
        if resourceId:
            createPortalSettings(mdsdCfg,escape(resourceId))
            instanceID=""
            if resourceId.find("providers/Microsoft.Compute/virtualMachineScaleSets") >=0:
                instanceID = readUUID()
            config(mdsdCfg,"instanceID",instanceID,"Events/DerivedEvents/DerivedEvent/LADQuery")

    except Exception as e:
        hutil.error("Failed to create portal config  error:{0} {1}".format(e,traceback.format_exc()))
    
    # Check if Application Insights key is present in ladCfg
    ladCfg = readPublicConfig('ladCfg')
    try:
        aikey = AIUtil.tryGetAiKey(ladCfg)
        if aikey:
            hutil.log("Application Insights key found.")
        else:
            hutil.log("Application Insights key not found.")
    except Exception as e:
        hutil.error("Failed check for Application Insights key in LAD configuration with exception:{0} {1}".format(e,traceback.format_exc()))

    generatePerformanceCounterConfiguration(mdsdCfg,aikey != None)

    syslogCfg = getSyslogCfg()
    fileCfg = getFileCfg() 
    #fileCfg = [{"file":"/var/log/waagent.log","table":"waagent"},{"file":"/var/log/waagent2.log","table":"waagent3"}]
    try:
        if fileCfg:
           syslogCfg = createEventFileSettings(mdsdCfg,fileCfg)+syslogCfg

        with open(omfileconfig,'w') as hfile:
                hfile.write(syslogCfg)
    except Exception as e:
        hutil.error("Failed to create syslog_file config  error:{0} {1}".format(e,traceback.format_exc()))

    account = readPrivateConfig('storageAccountName')
    if not account:
        return False, "Empty storageAccountName"
    key = readPrivateConfig('storageAccountKey')
    if not key:
        return False, "Empty storageAccountKey"
    endpoint = readPrivateConfig('endpoint')
    if not endpoint:
        endpoint = 'table.core.windows.net'
    endpoint = 'https://'+account+"."+endpoint

    createAccountSettings(mdsdCfg,account,key,endpoint,aikey)

    # Check and add new syslog RouteEvent for Application Insights.
    if aikey:
        AIUtil.createSyslogRouteEventElement(mdsdCfg)

    setEventVolume(mdsdCfg,ladCfg)

    config(mdsdCfg,"sampleRateInSeconds","60","Events/OMI/OMIQuery")

    mdsdCfg.write(os.path.join(WorkDir, './xmlCfg.xml'))

    return True, ""
    def _update_account_settings(self, account, key, token, endpoint, aikey=None):
        """
        Update the MDSD configuration Account element with Azure table storage properties.
        Exactly one of (key, token) must be provided. If an aikey is passed, then add a new Account element for Application
        Insights with the application insights key.
        :param account: Storage account to which LAD should write data
        :param key: Shared key secret for the storage account, if present
        :param token: SAS token to access the storage account, if present
        :param endpoint: Identifies the Azure instance (public or specific sovereign cloud) where the storage account is
        :param aikey: Key for accessing AI, if present
        """
        assert key or token, "Either key or token must be given."
        assert self._mdsd_config_xml_tree is not None

        handler_cert_path, handler_pkey_path = self._get_handler_cert_pkey_paths(self._ext_settings.get_handler_settings())
        if key:
            key = self._encrypt_secret_with_cert(handler_cert_path, key)
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/Account',
                                "account", account, ['isDefault', 'true'])
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/Account',
                                "key", key, ['isDefault', 'true'])
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/Account',
                                "decryptKeyPath", handler_pkey_path, ['isDefault', 'true'])
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/Account',
                                "tableEndpoint", endpoint, ['isDefault', 'true'])
            XmlUtil.removeElement(self._mdsd_config_xml_tree, 'Accounts', 'SharedAccessSignature')
        else:  # token
            token = self._encrypt_secret_with_cert(handler_cert_path, token)
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                                "account", account, ['isDefault', 'true'])
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                                "key", token, ['isDefault', 'true'])
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                                "decryptKeyPath", handler_pkey_path, ['isDefault', 'true'])
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, 'Accounts/SharedAccessSignature',
                                "tableEndpoint", endpoint, ['isDefault', 'true'])
            XmlUtil.removeElement(self._mdsd_config_xml_tree, 'Accounts', 'Account')

        if aikey:
            AIUtil.createAccountElement(self._mdsd_config_xml_tree, aikey)
    def generate_all_configs(self):
        """
        Generates configs for all components required by LAD.
        Generates XML cfg file for mdsd, from JSON config settings (public & private).
        Also generates rsyslog/syslog-ng configs corresponding to 'syslogEvents' or 'syslogCfg' setting.
        Also generates fluentd's syslog/tail src configs and out_mdsd configs.
        The rsyslog/syslog-ng and fluentd configs are not yet saved to files. They are available through
        the corresponding getter methods of this class (get_fluentd_*_config(), get_*syslog*_config()).

        Returns (True, '') if config was valid and proper xmlCfg.xml was generated.
        Returns (False, '...') if config was invalid and the error message.
        """

        # 1. Add DeploymentId (if available) to identity columns
        if self._deployment_id:
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree,
                                "Management/Identity/IdentityComponent", "",
                                self._deployment_id, ["name", "DeploymentId"])

        # 2. Generate telegraf, MetricsExtension, omsagent (fluentd) configs, rsyslog/syslog-ng config, and update corresponding mdsd config XML
        try:
            lad_cfg = self._ladCfg()
            if not lad_cfg:
                return False, 'Unable to find Ladcfg element. Failed to generate configs for fluentd, syslog, and mdsd ' \
                          '(see extension error logs for more details)'

            syslogEvents_setting = self._ext_settings.get_syslogEvents_setting(
            )
            fileLogs_setting = self._ext_settings.get_fileLogs_setting()
            lad_logging_config_helper = LadLoggingConfig(
                syslogEvents_setting, fileLogs_setting, self._sink_configs,
                self._pkey_path, self._cert_path, self._encrypt_secret)
            mdsd_syslog_config = lad_logging_config_helper.get_mdsd_syslog_config(
                self._ext_settings.read_protected_config(
                    'disableStorageAccount') == True)
            mdsd_filelog_config = lad_logging_config_helper.get_mdsd_filelog_config(
            )
            copy_source_mdsdevent_eh_url_elems(self._mdsd_config_xml_tree,
                                               mdsd_syslog_config)
            copy_source_mdsdevent_eh_url_elems(self._mdsd_config_xml_tree,
                                               mdsd_filelog_config)
            self._fluentd_syslog_src_config = lad_logging_config_helper.get_fluentd_syslog_src_config(
            )
            self._fluentd_tail_src_config = lad_logging_config_helper.get_fluentd_filelog_src_config(
            )
            self._fluentd_out_mdsd_config = lad_logging_config_helper.get_fluentd_out_mdsd_config(
            )
            self._rsyslog_config = lad_logging_config_helper.get_rsyslog_config(
            )
            self._syslog_ng_config = lad_logging_config_helper.get_syslog_ng_config(
            )
            parsed_perf_settings = lad_logging_config_helper.parse_lad_perf_settings(
                lad_cfg)
            self._telegraf_config, self._telegraf_namespaces = telhandler.handle_config(
                parsed_perf_settings, self._telegraf_me_url,
                self._telegraf_mdsd_url, True)

            #Handle the EH, JsonBlob and AzMonSink logic
            self._update_metric_collection_settings(lad_cfg,
                                                    self._telegraf_namespaces)
            mdsd_telegraf_config = lad_logging_config_helper.get_mdsd_telegraf_config(
                self._telegraf_namespaces)
            copy_source_mdsdevent_eh_url_elems(self._mdsd_config_xml_tree,
                                               mdsd_telegraf_config)

            resource_id = self._ext_settings.get_resource_id()
            if resource_id:
                # Set JsonBlob sink-related elements
                uuid_for_instance_id = self._fetch_uuid()
                self._add_obo_field(name='resourceId', value=resource_id)
                self._add_obo_field(name='agentIdentityHash',
                                    value=uuid_for_instance_id)

                XmlUtil.setXmlValue(
                    self._mdsd_config_xml_tree,
                    'Events/DerivedEvents/DerivedEvent/LADQuery',
                    'partitionKey', escape_nonalphanumerics(resource_id))
                lad_query_instance_id = ""
                if resource_id.find(
                        "providers/Microsoft.Compute/virtualMachineScaleSets"
                ) >= 0:
                    lad_query_instance_id = uuid_for_instance_id
                self._set_xml_attr(
                    "instanceID", lad_query_instance_id,
                    "Events/DerivedEvents/DerivedEvent/LADQuery")
            else:
                return False, 'Unable to find resource id in the config. Failed to generate configs for Metrics in mdsd ' \
                        '(see extension error logs for more details)'

            #Only enable Metrics if AzMonSink is in the config
            if self._enable_metrics_extension:
                me_handler.setup_me(True)

        except Exception as e:
            self._logger_error(
                "Failed to create omsagent (fluentd), rsyslog/syslog-ng configs, telegraf config or to update "
                "corresponding mdsd config XML. Error: {0}\nStacktrace: {1}".
                format(e, traceback.format_exc()))
            return False, 'Failed to generate configs for fluentd, syslog, and mdsd; see extension.log for more details.'

        # 3. Before starting to update the storage account settings, log extension's entire settings
        #    with secrets redacted, for diagnostic purpose.
        self._ext_settings.log_ext_settings_with_secrets_redacted(
            self._logger_log, self._logger_error)

        # 4. Actually update the storage account settings on mdsd config XML tree (based on extension's
        #    protectedSettings).
        account = self._ext_settings.read_protected_config(
            'storageAccountName').strip()
        if not account:
            return False, "Configuration Error: Must specify storageAccountName in protected settings. For information on protected settings, " \
                          "visit https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/diagnostics-linux#protected-settings."
        if self._ext_settings.read_protected_config('storageAccountKey'):
            return False, "Configuration Error: The storageAccountKey protected setting is deprecated in LAD 3.0 and cannot be used. " \
                          "Instead, use the storageAccountSasToken setting. For documentation of this setting and instructions for generating " \
                          "a SAS token, visit https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/diagnostics-linux#protected-settings."
        token = self._ext_settings.read_protected_config(
            'storageAccountSasToken').strip()
        if not token or token == '?':
            return False, "Configuration Error: Must specify storageAccountSasToken in the protected settings. For documentation of this setting and instructions " \
                          "for generating a SAS token, visit https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/diagnostics-linux#protected-settings."
        if '?' == token[0]:
            token = token[1:]
        endpoints = get_storage_endpoints_with_account(
            account,
            self._ext_settings.read_protected_config('storageAccountEndPoint'))
        self._update_account_settings(account, token, endpoints)

        # 5. Update mdsd config XML's eventVolume attribute based on the logic specified in the helper.
        self._set_event_volume(lad_cfg)

        # 6. Finally generate mdsd config XML file out of the constructed XML tree object.
        self._mdsd_config_xml_tree.write(
            os.path.join(self._ext_dir, 'xmlCfg.xml'))

        return True, ""
    def generate_mdsd_rsyslog_configs(self):
        """
        Generates XML cfg file for mdsd, from JSON config settings (public & private).
        Also generates rsyslog imfile conf file from the 'fileCfg' setting.
        Returns (True, '') if config was valid and proper xmlCfg.xml was generated.
        Returns (False, '...') if config was invalid and the error message.
        """

        # 1. Get the mdsd config XML tree base.
        #    - 1st priority is from the extension setting's 'mdsdCfg' value.
        #      Note that we have never used this option.
        #    - 2nd priority is to use the provided XML template stored in <ext_dir>/mdsdConfig.xml.template.
        mdsd_cfg_str = self._ext_settings.get_mdsd_cfg()
        if not mdsd_cfg_str:
            with open(os.path.join(self._ext_dir, './mdsdConfig.xml.template'), "r") as f:
                mdsd_cfg_str = f.read()
        self._mdsd_config_xml_tree = ET.ElementTree()
        self._mdsd_config_xml_tree._setroot(XmlUtil.createElement(mdsd_cfg_str))

        # 2. Add DeploymentId (if available) to identity columns
        if self._deployment_id:
            XmlUtil.setXmlValue(self._mdsd_config_xml_tree, "Management/Identity/IdentityComponent", "",
                                self._deployment_id, ["name", "DeploymentId"])
        # 2.1. Apply resourceId attribute to LADQuery elements
        try:
            resource_id = self._ext_settings.get_resource_id()
            if resource_id:
                escaped_resource_id_str = escape_nonalphanumerics(resource_id)
                self._add_portal_settings(escaped_resource_id_str)
                instanceID = ""
                if resource_id.find("providers/Microsoft.Compute/virtualMachineScaleSets") >= 0:
                    instanceID = read_uuid(self._run_command)
                self._set_xml_attr("instanceID", instanceID, "Events/DerivedEvents/DerivedEvent/LADQuery")
        except Exception as e:
            self._logger_error("Failed to create portal config  error:{0} {1}".format(e, traceback.format_exc()))

        # 3. Update perf counter config. Need to distinguish between non-AppInsights scenario and AppInsights scenario,
        #    so check if Application Insights key is present in ladCfg first, and pass it to the actual helper
        #    function (self._apply_perf_cfgs()).
        lad_cfg = self._ext_settings.read_public_config('ladCfg')
        do_ai = False
        aikey = None
        try:
            aikey = AIUtil.tryGetAiKey(lad_cfg)
            if aikey:
                self._logger_log("Application Insights key found.")
                do_ai = True
            else:
                self._logger_log("Application Insights key not found.")
        except Exception as e:
            self._logger_error("Failed check for Application Insights key in LAD configuration with exception:{0}\n"
                               "Stacktrace: {1}".format(e, traceback.format_exc()))
        self._apply_perf_cfgs(do_ai)

        # 4. Generate rsyslog imfile config. It's unclear why non-imfile config stuff (self._get_syslog_config())
        #    is appended to imfileconfig as well. That part has never been used, as far as I remember, and will
        #    definitely need to change later.
        syslog_cfg = self._ext_settings.get_syslog_config()
        file_cfg = self._ext_settings.get_file_monitoring_config()
        # fileCfg = [{"file":"/var/log/waagent.log","table":"waagent"},{"file":"/var/log/waagent2.log","table":"waagent3"}]
        try:
            if file_cfg:
                syslog_cfg = self._update_and_get_file_monitoring_settings(file_cfg) + syslog_cfg
            with open(self._imfile_config_filename, 'w') as imfile_config_file:
                imfile_config_file.write(syslog_cfg)
        except Exception as e:
            self._logger_error("Failed to create rsyslog imfile config. Error:{0}\n"
                         "Stacktrace: {1}".format(e, traceback.format_exc()))

        # 5. Before starting to update the storage account settings, log extension's protected settings'
        #    keys only (except well-known values), for diagnostic purpose. This is mainly to make sure that
        #    the extension's Json settings include a correctly entered 'storageEndpoint'.
        self._ext_settings.log_protected_settings_keys(self._logger_log, self._logger_error)

        # 6. Actually update the storage account settings on mdsd config XML tree (based on extension's
        #    protectedSettings).
        account = self._ext_settings.read_protected_config('storageAccountName')
        if not account:
            return False, "Empty storageAccountName"
        key = self._ext_settings.read_protected_config('storageAccountKey')
        token = self._ext_settings.read_protected_config('storageAccountSasToken')
        if not key and not token:
            return False, "Neither storageAccountKey nor storageAccountSasToken is given"
        if key and token:
            return False, "Either storageAccountKey or storageAccountSasToken (but not both) should be given"
        endpoint = get_storage_endpoint_with_account(account,
                                                     self._ext_settings.read_protected_config('storageAccountEndPoint'))
        self._update_account_settings(account, key, token, endpoint, aikey)

        # 7. Check and add new syslog RouteEvent for Application Insights.
        if aikey:
            AIUtil.createSyslogRouteEventElement(self._mdsd_config_xml_tree)

        # 8. Update mdsd config XML's eventVolume attribute based on the logic specified in the helper.
        self._set_event_volume(lad_cfg)

        # 9. Update mdsd config XML's sampleRateInSeconds attribute with default '60'
        self._set_xml_attr("sampleRateInSeconds", "60", "Events/OMI/OMIQuery")

        # 10. Finally generate mdsd config XML file out of the constructed XML tree object.
        self._mdsd_config_xml_tree.write(os.path.join(self._ext_dir, './xmlCfg.xml'))

        return True, ""