Skip to content

Commit

Permalink
Fixes #5796: Make syslog transport configurable from web interface
Browse files Browse the repository at this point in the history
  • Loading branch information
VinceMacBuche committed Jun 11, 2015
1 parent 6a1dd0a commit 57021de
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
###############################################################################
# Copyright 2015 Normation SAS
###############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# In accordance with the terms of section 7 (7. Additional Terms.) of
# the GNU Affero GPL v3, the copyright holders add the following
# Additional permissions:
# Notwithstanding to the terms of section 5 (5. Conveying Modified Source
# Versions) and 6 (6. Conveying Non-Source Forms.) of the GNU Affero GPL v3
# licence, when you create a Related Module, this Related Module is
# not considered as a part of the work and may be distributed under the
# license agreement of your choice.
# A "Related Module" means a set of sources files including their
# documentation that, without modification of the Source Code, enables
# supplementary functions or services in addition to those offered by
# the Software.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/agpl.html>.
#
###############################################################################

# Create the syslog protocotl portperty with value 'TCP', a different value from new rudder installation
# By doing so, we keep the same behavior as before

dn: propertyName=rudder_syslog_protocol,ou=Application Properties,cn=rudder-
configuration
objectClass: property
objectClass: top
propertyName: rudder_syslog_protocol
propertyValue: TCP
11 changes: 11 additions & 0 deletions rudder-core/src/main/resources/ldap/bootstrap.ldif
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,14 @@ description: Default inform message put in header of managed files by Rudder
overridable: TRUE
parameterValue: ### Managed by Rudder, edit with care ###

dn: ou=Application Properties,cn=rudder-configuration
objectClass: organizationalUnit
objectClass: top
ou: Application Properties

dn: propertyName=rudder_syslog_protocol,ou=Application Properties,cn=rudder-
configuration
objectClass: property
objectClass: top
propertyName: rudder_syslog_protocol
propertyValue: UDP
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,11 @@ final case object ModifyAgentRunStartMinuteEventType extends ModifyGlobalPropert
val propertyName = "Agent run start minute"
}

final case object ModifyRudderSyslogProtocolEventType extends ModifyGlobalPropertyEventType {
def serialize = "RudderSyslogProtocolModified"
val propertyName = "Rudder syslog protocol"
}

/**
* List of event generating a modification of promises
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ object ModifyGlobalPropertyEventLogsFilter {
ModifyAgentRunSplaytimeEventType ::
ModifyAgentRunStartHourEventType ::
ModifyAgentRunStartMinuteEventType ::
ModifyRudderSyslogProtocolEventType ::
Nil

final val eventList : List[EventLogFilter] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,15 @@ class AgentRunIntervalServiceImpl(

}

sealed trait SyslogProtocol {
def value : String
}

object SyslogTCP extends SyslogProtocol {
val value = "TCP"
}

object SyslogUDP extends SyslogProtocol {
val value = "UDP"
}

Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import com.normation.rudder.reports.ComplianceMode
import com.normation.rudder.reports.FullCompliance
import com.normation.rudder.reports.ChangesOnly
import com.normation.rudder.reports.AgentRunInterval
import com.normation.rudder.reports.SyslogProtocol

trait SystemVariableService {
def getGlobalSystemVariables(): Box[Map[String, Variable]]
Expand Down Expand Up @@ -101,6 +102,7 @@ class SystemVariableServiceImpl(
, getCfengineOutputsTtl : () => Box[Int]
, getStoreAllCentralizedLogsInFile: () => Box[Boolean]
, getSendMetrics : () => Box[Option[Boolean]]
, getSyslogProtocol : () => Box[SyslogProtocol]
) extends SystemVariableService with Loggable {

val varToolsFolder = systemVariableSpecService.get("TOOLS_FOLDER").toVariable().copyWithSavedValue(toolsFolder)
Expand Down Expand Up @@ -136,6 +138,7 @@ class SystemVariableServiceImpl(
val skipIdentify = getProp("SKIPIDENTIFY", getSkipIdentify)
val modifiedFilesTtl = getProp("MODIFIED_FILES_TTL", getModifiedFilesTtl)
val cfengineOutputsTtl = getProp("CFENGINE_OUTPUTS_TTL", getCfengineOutputsTtl)
val reportProtocol = getProp("RUDDER_SYSLOG_PROTOCOL", getSyslogProtocol)

val sendMetricsValue = if (getSendMetrics().getOrElse(None).getOrElse(false)) {
"yes"
Expand Down Expand Up @@ -177,6 +180,7 @@ class SystemVariableServiceImpl(
cfengineOutputsTtl ::
storeAllCentralizedLogsInFile ::
varSendMetrics ::
reportProtocol ::
Nil
vars.map(v => (v.spec.name,v)).toMap
}
Expand Down
2 changes: 2 additions & 0 deletions rudder-web/src/main/resources/eventLogTypeNames.properties
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@ rudder.log.eventType.names.AgentRunIntervalModified=Property 'Agent run interval
rudder.log.eventType.names.AgentRunSplaytimeModified=Property 'Agent run splaytime' modified
rudder.log.eventType.names.AgentRunStartHourModified=Property 'Agent run start hour' modified
rudder.log.eventType.names.AgentRunStartMinuteModified=Property 'Agent run start minute' modified
rudder.log.eventType.names.RudderSyslogProtocolModified=Property 'Rudder syslog protocol' modified


Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,7 @@ object RudderConfig extends Loggable {
, configService.cfengine_outputs_ttl _
, configService.rudder_store_all_centralized_logs_in_file _
, configService.send_server_metrics _
, configService.rudder_syslog_protocol _
)
private[this] lazy val rudderCf3PromisesFileWriterService = new RudderCf3PromisesFileWriterServiceImpl(
techniqueRepositoryImpl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ import com.normation.rudder.domain.eventlog.ModifyAgentRunIntervalEventType
import com.normation.rudder.domain.eventlog.ModifyAgentRunStartHourEventType
import com.normation.rudder.domain.eventlog.ModifyAgentRunStartMinuteEventType
import com.normation.rudder.domain.eventlog.ModifyAgentRunSplaytimeEventType
import com.normation.rudder.reports._
import com.normation.rudder.domain.eventlog.ModifyRudderSyslogProtocolEventType

/**
* A service that Read mutable (runtime) configuration properties
Expand Down Expand Up @@ -133,6 +135,11 @@ trait ReadConfigService {
*/
def send_server_metrics(): Box[Option[Boolean]]

/**
* Report protocol
*/
def rudder_syslog_protocol(): Box[SyslogProtocol]

}

/**
Expand Down Expand Up @@ -201,6 +208,11 @@ trait UpdateConfigService {

def set_rudder_compliance_heartbeatPeriod(frequency : Int, actor: EventActor, reason: Option[String]) : Box[Unit]

/**
* Report protocol
*/
def set_rudder_syslog_protocol(value : SyslogProtocol, actor : EventActor, reason: Option[String]): Box[Unit]

}

class LDAPBasedConfigService(configFile: Config, repos: ConfigRepository, workflowUpdate: AsyncWorkflowInfo) extends ReadConfigService with UpdateConfigService with Loggable {
Expand Down Expand Up @@ -229,6 +241,7 @@ class LDAPBasedConfigService(configFile: Config, repos: ConfigRepository, workfl
send.server.metrics=none
rudder.compliance.mode=${FullCompliance.name}
rudder.compliance.heartbeatPeriod=1
rudder.syslog.protocol=UDP
"""

val configWithFallback = configFile.withFallback(ConfigFactory.parseString(defaultConfig))
Expand Down Expand Up @@ -270,6 +283,10 @@ class LDAPBasedConfigService(configFile: Config, repos: ConfigRepository, workfl
case _ => Some(false)
}

private[this] implicit def toSyslogProtocol(p: RudderWebProperty): SyslogProtocol = p.value.toLowerCase match {
case "TCP" => SyslogTCP
case _ => SyslogUDP
}
private[this] implicit def toString(p: RudderWebProperty): String = p.value

private[this] implicit def toUnit(p: Box[RudderWebProperty]) : Box[Unit] = p.map( _ => ())
Expand Down Expand Up @@ -392,4 +409,14 @@ class LDAPBasedConfigService(configFile: Config, repos: ConfigRepository, workfl
save("send_server_metrics",newVal,Some(info))
}


/**
* Report protocol
*/
def rudder_syslog_protocol(): Box[SyslogProtocol] = get("rudder_syslog_protocol")
def set_rudder_syslog_protocol(protocol : SyslogProtocol, actor : EventActor, reason: Option[String]): Box[Unit] = {
val info = ModifyGlobalPropertyInfo(ModifyRudderSyslogProtocolEventType,actor,reason)
save("rudder_syslog_protocol", protocol.value, Some(info))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ import com.normation.rudder.reports.ChangesOnly
import com.normation.rudder.web.components.AgentScheduleEditForm
import com.normation.rudder.reports.AgentRunInterval
import com.normation.rudder.web.components.ComplianceModeEditForm
import com.normation.rudder.reports.SyslogUDP
import com.normation.rudder.reports.SyslogTCP
import com.normation.rudder.reports.SyslogProtocol


/**
Expand Down Expand Up @@ -83,6 +86,7 @@ class PropertiesManagement extends DispatchSnippet with Loggable {
case "cfengineGlobalProps" => cfengineGlobalProps
case "loggingConfiguration" => loggingConfiguration
case "sendMetricsConfiguration" => sendMetricsConfiguration
case "networkProtocolSection" => networkProtocolSection
}


Expand Down Expand Up @@ -469,6 +473,63 @@ class PropertiesManagement extends DispatchSnippet with Loggable {
) apply (xml ++ Script(Run("correctButtons();") & check()))
}

def networkProtocolSection = { xml : NodeSeq =>
// initial values, updated on successfull submit
def networkForm(initValue : SyslogProtocol) = {
var initReportsProtocol = initValue
var reportProtocol = initValue
def check = {
val noChange = initReportsProtocol == reportProtocol
S.notice("updateNetworkProtocol","")
Run(s"""$$("#networkProtocolSubmit").button( "option", "disabled",${noChange});""")
}

def submit = {
val actor = CurrentUser.getActor
configService.set_rudder_syslog_protocol(reportProtocol,actor,None) match {
case Full(_) =>
// Update the initial value of the form
initReportsProtocol = reportProtocol
startNewPolicyGeneration
S.notice("updateNetworkProtocol","Network protocol options correctly updated")
check
case eb:EmptyBox =>
S.error("updateNetworkProtocol","Error when saving network protocol options")
Noop
}
}

val checkboxInitValue = initReportsProtocol == SyslogUDP

( "#reportProtocol" #> {
SHtml.ajaxCheckbox(
checkboxInitValue
, (newValue : Boolean) => {
reportProtocol = if (newValue) SyslogUDP else SyslogTCP
check
}
, ("id","reportProtocol")
)
} &
"#networkProtocolSubmit " #> {
SHtml.ajaxSubmit("Save changes", submit _)
}
)(xml ++ Script(Run("correctButtons();") & check))

}

configService.rudder_syslog_protocol match {
case Full(value) =>
networkForm(value)
case eb: EmptyBox =>
// We could not read current protocol, try repairing by setting protocol to UDP and warn user
val actor = CurrentUser.getActor
configService.set_rudder_syslog_protocol(SyslogUDP,actor,Some("Property automatically reset to 'UDP' due to an error"))
S.error("updateNetworkProtocol","Error when fetching 'Syslog protocol' property, Setting it to UDP")
networkForm(SyslogUDP)
}
}

val agentScheduleEditForm = new AgentScheduleEditForm(
getSchedule
, saveSchedule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,31 @@ <h3>Security</h3>
</div>
</div>
<hr class="spacer" />
<div class="deca">
<h3>Protocol</h3>
<div class="lift:administration.PropertiesManagement.networkProtocolSection" id="networkProtocolForm">
<form class="lift:form.ajax">
<div class="wbBaseField">
<label for="reportProtocol" class="threeCol textight" style="font-weight:bold;width: 50%;">
<span >Use TCP in place of UDP (default) for syslog communication between node and servers:
<img src="/images/icInfo.png" style="padding-left:15px; margin:0; float:none" tooltipid="reportProtocolTooltip" title="" class="tooltipable" />
</span>
<div class="tooltipContent" id="reportProtocolTooltip">
Rudder uses syslog to transfer report messages from nodes to relay and
servers.By default, Rudder configure syslog to use UDP so that the syslog never
stall an a non responsive connection, which could also stale other services
on the node which use syslog. On the other hand, using TCP allows to minimize the loss in reports and the resulting compliance errors.
</div>
</label>
<input id="reportProtocol" type="text"/>
</div>
<hr class="spacer"/>
<input type="submit" value="[save]" id="networkProtocolSubmit"/>
<lift:Msg id="updateNetworkProtocol">[messages]</lift:Msg>
</form>
</div>
</div>
<hr class="spacer" />


</div>
Expand Down

0 comments on commit 57021de

Please sign in to comment.