From 06736db1c3ac00d505d29f77f1565c6f9dcd6016 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Thu, 11 Dec 2025 09:15:40 +0100 Subject: [PATCH 01/25] Removing old test code for testing due to errors --- examples/go-bigip_example.go | 78 ------------------------------------ net_test.go | 13 +++--- 2 files changed, 7 insertions(+), 84 deletions(-) delete mode 100644 examples/go-bigip_example.go diff --git a/examples/go-bigip_example.go b/examples/go-bigip_example.go deleted file mode 100644 index 56e815d..0000000 --- a/examples/go-bigip_example.go +++ /dev/null @@ -1,78 +0,0 @@ -package bigip - -import ( - "fmt" - "github.com/f5devcentral/go-bigip" -) - -func main() { - // Connect to the BIG-IP system. - f5 := bigip.NewSession("ltm.company.com", "admin", "secret", nil) - - // Get a list of all VLAN's, and print their names to the console. - vlans, err := f5.Vlans() - if err != nil { - fmt.Println(err) - } - - for _, vlan := range vlans.Vlans { - fmt.Println(vlan.Name) - } - - // Create a VLAN - f5.CreateVlan("vlan1138", 1138) - f5.CreateVlan("vlan421", 421) - - // Add an untagged interface to a VLAN. - f5.AddInterfaceToVlan("vlan1138", "1.2", false) - - // Delete a VLAN. - f5.DeleteVlan("vlan1138") - - // Create a couple of nodes. - f5.CreateNode("web-server-1", "192.168.1.50") - f5.CreateNode("web-server-2", "192.168.1.51") - f5.CreateNode("ssl-web-server-1", "10.2.2.50") - f5.CreateNode("ssl-web-server-2", "10.2.2.51") - - // Create a pool, and add members to it. When adding a member, you must - // specify the port in the format of :. - f5.CreatePool("web_farm_80_pool") - f5.AddPoolMember("web_farm_80_pool", "web-server-1:80") - f5.AddPoolMember("web_farm_80_pool", "web-server-2:80") - f5.CreatePool("ssl_443_pool") - f5.AddPoolMember("ssl_443_pool", "ssl-web-server-1:443") - f5.AddPoolMember("ssl_443_pool", "ssl-web-server-2:443") - - // Create a monitor, and assign it to a pool. - f5.CreateMonitor("web_http_monitor", "http", 5, 16, "GET /\r\n", "200 OK", "http") - f5.AddMonitorToPool("web_http_monitor", "web_farm_80_pool") - - // Create a virtual server, with the above pool. The third field is the subnet - // mask, and that can either be in CIDR notation or decimal. For any/all destinations - // and ports, use '0' for the mask and/or port. - f5.CreateVirtualServer("web_farm_VS", "0.0.0.0", "0.0.0.0", "web_farm_80_pool", 80) - f5.CreateVirtualServer("ssl_web_farm_VS", "10.1.1.0", "24", "ssl_443_pool", 443) - - // Remove a pool member. - f5.DeletePoolMember("web_farm_80_pool", "web-server-2:80") - - // Create a trunk, with LACP enabled. - f5.CreateTrunk("Aggregated", "1.2, 1.4, 1.6", true) - - // Disable a virtual address. - f5.VirtualAddressStatus("web_farm_VS", "disable") - - // Disable a pool member. - f5.PoolMemberStatus("ssl_443_pool", "ssl-web-server-1:443", "disable") - - // Create a self IP. - f5.CreateSelfIP("vlan1138", "10.10.10.1/24", "vlan1138") - f5.CreateSelfIP("vlan421", "10.10.20.1/25", "vlan421") - - // Add a static route. - f5.CreateRoute("servers", "10.1.1.0/24", "10.50.1.5") - - // Create a route domain. - f5.CreateRouteDomain("vlans", 10, true, "vlan1138, vlan421") -} diff --git a/net_test.go b/net_test.go index dfdb432..bf493e8 100644 --- a/net_test.go +++ b/net_test.go @@ -247,12 +247,13 @@ func (s *NetTestSuite) TestVlans() { assert.Equal(s.T(), 0, vlans.Vlans[0].SFlow.PollInterval) } -func (s *NetTestSuite) TestCreateVLan() { - err := s.Client.CreateVlan("name", 1) - - assert.Nil(s.T(), err) - assertRestCall(s, "POST", "/mgmt/tm/net/vlan", `{"name":"name", "tag":1, "sflow":{}}`) -} +// Bad CreateVlan format - probably old code remanentes +//func (s *NetTestSuite) TestCreateVLan() { +// err := s.Client.CreateVlan("name", 1) +// +// assert.Nil(s.T(), err) +// assertRestCall(s, "POST", "/mgmt/tm/net/vlan", `{"name":"name", "tag":1, "sflow":{}}`) +//} func (s *NetTestSuite) TestDeleteVLan() { err := s.Client.DeleteVlan("name") From d993bf10e643436d100d3f6c16df688fa1d42739 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Thu, 11 Dec 2025 14:21:33 +0100 Subject: [PATCH 02/25] Implementing DB Variable support --- db_vars.go | 2631 +++++++++++++++++++++++++++++++ examples/db_vars/main.go | 41 + examples/db_vars/test_db_var.go | 85 + 3 files changed, 2757 insertions(+) create mode 100644 db_vars.go create mode 100644 examples/db_vars/main.go create mode 100644 examples/db_vars/test_db_var.go diff --git a/db_vars.go b/db_vars.go new file mode 100644 index 0000000..5ed94dd --- /dev/null +++ b/db_vars.go @@ -0,0 +1,2631 @@ +package bigip + +import ( + "fmt" +) + +const ( + uriDb = "db" +) + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// System DB Variables ///////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +var DefaultDBValues = map[string]interface{}{ + "acceleration.log.color": "no_color", + "acceleration.log.level": "show_name", + "acceleration.wam_assembly.loglevel": "Notice", + "acceleration.wam_bigdb.loglevel": "Notice", + "acceleration.wam_cache.loglevel": "Notice", + "acceleration.wam_event.loglevel": "Notice", + "acceleration.wam_log.loglevel": "Notice", + "acceleration.wam_mstor.loglevel": "Notice", + "acceleration.wam_mtags.loglevel": "Notice", + "acceleration.wam_parse.loglevel": "Notice", + "acceleration.wam_plugin.loglevel": "Notice", + "acceleration.wam_proxy.loglevel": "Notice", + "access.max.euie_uri.cache.entries": "2048", + "adm.aipi.allow": "default", + "adm.aipi.minhits": "200", + "adm.block.enable": "0", + "adm.cloud.host": "none", + "adm.enable": "0", + "adm.fastl4.cor.log2scale": "3", + "adm.fastl4.rps.log2scale": "10", + "adm.health.sensitivity": "500", + "adm.learning.mode": "local", + "adm.log.level": "0", + "adm.logs.level": "info", + "adm.max.vs": "20", + "adm.mitigation.accelerated.signatures.drop.mode": "drop", + "adm.mitigation.attack.timeout": "300", + "adm.mitigation.greylist.expire.factor": "20", + "adm.mitigation.greylist.expire.time": "180", + "adm.mitigation.greylist.expire.time.jitter": "40", + "adm.mitigation.greylist.expire.timeout": "20", + "adm.mitigation.greylist.global.ratio": "5", + "adm.mitigation.max.score.drop.rate": "70", + "adm.mitigation.rate.period": "1000", + "adm.mitigation.vs.global.ratio": "95", + "adm.record.cloud": "0", + "adm.record.stats": "0", + "adm.record.traffic": "0", + "adm.signature.sampling": "1", + "adm.signatures.status": "none", + "adm.tls.fingerprints.key.mode": "disable", + "admdb.debug.max_capacity": "150", + "admdb.debug.max_files": "10000", + "admdb.debug.traffic.sample": "disable", + "admdb.debug.vs.delete.cleanup.timeout": "60", + "admdb.filter": "^vs.*", + "afm.acl.ipint.ignore_match": "disable", + "afm.activerules.disablesearchforall": "false", + "afm.allowtmcvirtuals": "false", + "afm.inbound_conn.enforce_policies": "true", + "afm.inlineruleeditor": "true", + "afm.portmisuse": "enable", + "afm.shun.insert.count": "0", + "ah.lookupip": "disable", + "alertd.lcdwarn": "enable", + "alertd.nokia.alarm": "disable", + "alertd.nokia.linktraps": "disable", + "antifraud.alertscore.componentsvalidation": "50", + "antifraud.alertscore.encryptionfailure": "50", + "antifraud.alertscore.referrerchecks": "50", + "antifraud.alertscore.userdefined": "50", + "antifraud.alertserverpath": "/rstats/", + "antifraud.autotransactions.parameternameintegrity": "disable", + "antifraud.bait.maxquerystringlength": "1024", + "antifraud.baitsignatures": "", + "antifraud.beforeloadfunction": "", + "antifraud.bigrequestsize": "102400", + "antifraud.bigresponsesize": "102400", + "antifraud.closefakeconnection": "enable", + "antifraud.cloudservice.forensicexepath": "/forensics.exe", + "antifraud.componentsvalidation.method": "post", + "antifraud.cssalertimageid": "", + "antifraud.customgarbagefunction": "", + "antifraud.disableserversidessl.alert": "true", + "antifraud.disableserversidessl.cloudservice": "true", + "antifraud.disableserversidessl.rules": "true", + "antifraud.domainavailabilityurls": "", + "antifraud.encryptionfieldprefix": "", + "antifraud.encryptionkeylifetime": "1", + "antifraud.externalsourcestargets": "", + "antifraud.fieldtypestosend": "", + "antifraud.fielsnamesnottosend": "", + "antifraud.forensic.hookedprocesses": "iexplore.exe", + "antifraud.forensic.selfpostpage": " Fornesics Report
Forensics scan in process.

Please wait...
", + "antifraud.forensic.showgui": "disable", + "antifraud.globalbuffersize": "51200", + "antifraud.htmlfieldobfuscation.seedlength": "4", + "antifraud.injectplainjson": "disable", + "antifraud.injectsecurechannelcontext": "disable", + "antifraud.injecttags": "body", + "antifraud.internalconfig.flag1": "disable", + "antifraud.internalconfig.flag2": "disable", + "antifraud.internalconfig.flag3": "disable", + "antifraud.internalconfig.number1": "0", + "antifraud.internalconfig.number2": "0", + "antifraud.internalconfig.number3": "0", + "antifraud.internalconfig.string1": "", + "antifraud.internalconfig.string2": "", + "antifraud.internalconfig.string3": "", + "antifraud.loadjavascriptasync": "disable", + "antifraud.maxalertrequestsize": "2048", + "antifraud.maxbigrequests": "1000", + "antifraud.maxbigresponses": "1000", + "antifraud.maxcookielen": "1000", + "antifraud.maxcookievaluelength": "4096", + "antifraud.maxheaderlength": "255", + "antifraud.maxhostheaderlength": "255", + "antifraud.maxloginresponsesearchlength": "102400", + "antifraud.maxparamsendinalertmsglength": "1024", + "antifraud.mobilesafe.alertserverpath": "/rstats/", + "antifraud.mobilesafe.entangledgarbage": "", + "antifraud.mobilesafe.urlalert": "/Alert", + "antifraud.mobilesafe.urlalertandroid": "/AndroidAlert", + "antifraud.mobilesafe.urlalertios": "/iOSAlert", + "antifraud.mobilesafe.urlconfigandroid": "/AndroidConfig", + "antifraud.mobilesafe.urlconfigios": "/iOSConfig", + "antifraud.mobilesafe.urlkeyandroid": "/AndroidKey", + "antifraud.mobilesafe.urlkeyios": "/iOSKey", + "antifraud.mobilesafe.urlprefix": "/MobileSafe", + "antifraud.paramvalueencmaxlength": "1024", + "antifraud.paramvaluemaxlength": "1024", + "antifraud.paramvalueusernamemaxlength": "650", + "antifraud.quirkssupport": "false", + "antifraud.ratdetection.counttosendalert": "10", + "antifraud.ratdetection.timetoresetcounter": "5000", + "antifraud.riskengine.reportlogins": "disable", + "antifraud.riskengine.reportrequests": "disable", + "antifraud.rsadecryption.synchronous": "false", + "antifraud.rsakeysize": "128", + "antifraud.securemsgenforceip": "true", + "antifraud.securemsglifetime": "86400", + "antifraud.securemsgroundtime": "3600", + "antifraud.snifferfunctions": "", + "antifraud.srcintegrity.dataviolationthreshold": "100", + "antifraud.srcintegrity.goldstandardconsistentreqthreshold": "100", + "antifraud.srcintegrity.goldstandardviolationsthreshold": "10", + "antifraud.srcintegrity.lowseverityalerts": "enable", + "antifraud.srcintegrity.maturedatathreshold": "50", + "antifraud.strippathparameters": "true", + "antifraud.unlimitedduration": "157680000", + "antifraud.uselastxff": "false", + "antifraud.userdaemon.persistenceintervalmin": "5", + "antifraud.userinspectioncookieduration": "1209600", + "antifraud.vbklipdetection.accountnumbers": "", + "antserver.reply.cache.enable": "enable", + "antserver.reply.cache.size": "64k", + "aom.logs.readinterval": "1", + "apm.aaa.maxlisteners": "16384", + "apm.ad.kdclockout": "0", + "apm.adserver.nonmicrosoft": "false", + "apm.apd.conncrtl": "true", + "apm.apd.connhwm": "1536", + "apm.apd.connlwm": "1520", + "apm.client.version": "", + "apm.epsec.version": "", + "apm.http.connectiontimeout": "10", + "apm.http.requesttimeout": "60", + "apm.ifmap.conncount": "10", + "apm.ipsession.interfacecheck": "disable", + "apm.ldap.autoescape": "enable", + "apm.ldap.cache.pagesize": "2048", + "apm.oauth.sqlcompressionlevel": "1", + "apm.paap.version": "", + "apm.rotatesessionid": "enable", + "apm.xframeoptions": "deny", + "apm.xframeoptions.allowfrom": "", + "appiq.config.innetwork": "false", + "appiq.hostport": "514", + "arp.addreciprocal": "enable", + "arp.gratuitousburst": "1", + "arp.gratuitousrate": "0", + "arp.maxentries": "8192", + "arp.priority": "normal", + "arp.proxyarpusesselfmac": "disable", + "arp.proxygratuitousreplies": "disable", + "arp.reaptimeout": "20", + "arp.retries": "6", + "arp.timeout": "300", + "arp.verifyreturnroute": "enable", + "arp.vlanpriority": "-1", + "asm.asm_malicious_sources_monitoring_interval": "10", + "asm.brute_force_bypass_non_qualified_url": "false", + "asm.brute_force_end_attack_verification_time": "120", + "asm.brute_force_max_tmstat_entries": "10", + "asm.brute_force_monitoring_interval": "10", + "asm.connlimit": "6000", + "asm.cookie_prefix": "TS", + "asm.cookie_revision_base": "0", + "asm.cookie_suffix_base": "0", + "asm.credential_stuffing_service": "enable", + "asm.cs_challenge_length": "4", + "asm.cs_qualified_urls": ",", + "asm.cshui_susp_event_bot_score": "20", + "asm.csrf_rerun_interval": "0", + "asm.fastl4_allow": "enable", + "asm.fictive_url": "/TSbd/", + "asm.http_security_headers": "enable", + "asm.ignore_bewaf": "false", + "asm.inject_apm_do_not_touch": "true", + "asm.inject_referrer_hook": "true", + "asm.mobile_ua": ",", + "asm.restrict_asm_logs_access": "false", + "asm.risk_engine.salt.restart": "0", + "asm.session_transactions_sampling_rate": "10", + "asm.strict_transport_policy": "disable", + "asm.strip_asm_cookies": "true", + "asm.time_to_free_idle_umus_in_sec": "0", + "asmconffailure.enabled": "true", + "asmconffailure.haaction.primary": "restart_all", + "asmconffailure.haaction.secondary": "go_offline", + "asymmetric.hostreplicate.droppkts": "true", + "asymmetric.pkt.metering.auto": "enable", + "asymmetric.pkt.metering.maxcpu": "70", + "asymmetric.pkt.metering.percentage": "20", + "asymmetric.reset.stats": "0", + "asymmetric.synchallenge.logging": "false", + "asymmetric.synchallenge.scrbtime": "120", + "asymmetric.synchallenge.trustedlist": "false", + "auto.discover.flow.count": "3", + "auto.discover.mvs.count": "1024", + "auto.discover.serverpkt.count": "3", + "auto.discover.vsservice.count": "10000", + "autoscale.samezoneonly": "false", + "avr.addrandomdelaybeforesnapshot": "disable", + "avr.alwaysuselastxff": "0", + "avr.asmsampling": "1", + "avr.collapseasmhttpstat": "false", + "avr.collapseasmhttpusername": "disable", + "avr.collectonlyhostnamefromuri": "disable", + "avr.cookieaddattributes": "", + "avr.cookieprefix": "f5avr", + "avr.cookiesuffix": "", + "avr.cspm.inject.location": "at_the_end", + "avr.cspmcachecookiename": "f5_cspm", + "avr.customheaderoverridexff": "1", + "avr.distributedreporting.maxtiersize": "8", + "avr.dosinput.hitcount_topping_interval": "360", + "avr.dosl7.classifiertimeout": "300", + "avr.dosl7.parse_path_info": "disable", + "avr.dosmaxentitiespertable": "4096", + "avr.dosvishealthcalc.maxbigipconcurrentconnections": "0", + "avr.dosvishealthcalc.maxbigipthroughput": "0", + "avr.ecmenabled": "false", + "avr.eventlogsreportrownumber": "10000", + "avr.general.bool": "0", + "avr.general.int": "0", + "avr.general.string": "", + "avr.gui.widgets.sync": "enable", + "avr.hsl.batchpauseinmillisec": "5", + "avr.hsl.batchsize": "100", + "avr.hslmessagesbetweensleep": "0", + "avr.hslsleepperiodinmicrosecond": "0", + "avr.includeserverinuri": "disable", + "avr.maxsubnets": "1024", + "avr.monpdloaderindicator": "disable", + "avr.offboxtcptimeout": "30000", + "avr.pemsampling": "1", + "avr.purple.collectors.dns": "enable", + "avr.purple.collectors.http_main": "enable", + "avr.purple.collectors.ssl_orchestrator_reporting": "enable", + "avr.purple.collectors.tcp_reporting": "enable", + "avr.purple.limit_entities_per_vip": "disable", + "avr.realtime.intervalseconds": "10", + "avr.requestcache": "enable", + "avr.riskengine.metaheadername": "X-F5-AVR-HTID", + "avr.rt.maxsessionspermodule": "100", + "avr.send.configuration.to.offbox": "false", + "avr.stats.adapters.defaultpollinginterval": "10", + "avr.stats.adapters.minimumpollinginterval": "5", + "avr.stats.aggregation": "medium", + "avr.stats.distributed.maxrowsnum": "1000", + "avr.stats.distributedfactor.largerowsnum": "2", + "avr.stats.distributedfactor.rowsnumthreshold": "5", + "avr.stats.distributedfactor.smallrowsnum": "5", + "avr.stats.internal.maxentitiespertable": "20000", + "avr.stats.reportrownumberlimit": "1000", + "avr.subnetprefixlength.ipv4": "24", + "avr.subnetprefixlength.ipv6": "64", + "avr.threads.alerts.stacksizekb": "1024", + "avr.threads.config.stacksizekb": "1024", + "avr.threads.loader.stacksizekb": "1024", + "avr.threads.reporter.stacksizekb": "1024", + "avr.trafficcapture.external.syslogseverity": "info", + "avr.trafficcapture.internal.enabled": "true", + "avr.trafficcapture.internal.maxentriesperfile": "10", + "avr.trafficcapture.internal.maxtransactions": "1000", + "avr.trafficcapture.maxtransactionspersecond": "1000", + "avr.trafficcapture.pollingqueueinterval": "100", + "avr.trafficclassificationsampling": "1", + "avr.update.vip.app.table": "false", + "avr.upgrade.enabled": "true", + "avr.watchdog.defaultmonitoringinterval": "30", + "avr.watchdog.enabled": "true", + "avr.watchdog.intervalfactor": "4", + "avr.watchdog.shouldcoredump": "false", + "bbr.filter": "0,0,00000000,0,0,0", + "bbr.queuelength": "4096", + "bbr.retrievelogs": "0,0,0,0", + "bcm56xxd.hgmaclearning": "enable", + "bcm56xxd.hgmfcsnumpolls": "5", + "bcm56xxd.hgmfcsrebootaction": "enable", + "bcm56xxd.hgmfcsthreshold": "0", + "bcm56xxd.hgvlan_check_disable": "disable", + "bcm56xxd.hsb.fcserrthreshold": "0", + "bcm56xxd.hybridfwdmode": "disable", + "bcm56xxd.l2xmsg.mode": "fifo", + "bcm56xxd.lossless.mode": "disable", + "bcm56xxd.rules.badpdu_drop": "disable", + "bcm56xxd.rules.lldp_drop": "disable", + "bcm56xxd.vwire.4kvlans": "disable", + "bd.loglevel": "none", + "big3d.crlfilecheckinterval": "10", + "big3d.minimum.tls.version": "TLSv1", + "big3d.renegotiation.interval": "86400", + "big3d.ssl.cipherlist": "AESGCM:AES:!ADH:!AECDH:!PSK:!aECDH:!DSS:!ECDSA:!AES128:-SHA1:AES256-SHA", + "big3d.ssl.crlvalidationdepth": "full", + "big3d.ssl.reverifyoncrlbecomingactive": "yes", + "big3d.ssl.reverifyoncrlexpiring": "yes", + "big3d.ssl.reverifyoncrlfileupdate": "yes", + "big3d.ssl.useexpiredcrls": "yes", + "big3d.ssl.usenotyetactivecrls": "yes", + "big3d.ssl.userevokedcerts": "never", + "bigd.adaptive.default_noise_floor": "100", + "bigd.adaptive.default_timespan": "300", + "bigd.adaptive.tmstat": "disable", + "bigd.dbgfile": "/var/run/bigdlog.pipe", + "bigd.debug": "disable", + "bigd.debug.timing": "disable", + "bigd.debug.timingstats": "disable", + "bigd.heartbeat.interval": "0", + "bigd.hostlookup": "false", + "bigd.ipv4externaddr": "disable", + "bigd.lognodestatuschange": "disable", + "bigd.mgmtroutecheck": "disable", + "bigd.numprocs": "0", + "bigd.overload.latency": "98", + "bigd.reportinitnodestate": "all", + "bigd.resettransparent": "true", + "bigd.reusesocket": "enable", + "bigd.simulatepings": "false", + "bigd.smoothpinginterval": "86400", + "bigd.stateupdateinterval": "0", + "bigd.tclmonitormaxworkerspercore": "25", + "bigd.tclmonitorpingqueue": "1000", + "bigd.tclmonitorprefix": "", + "bigd.tclmonitorworkermemorybufferlimit": "10", + "bigd.tclmonitorworkerpinglimit": "1000", + "bigd.tmm": "disable", + "bigpipe.displayhostnames": "false", + "bigpipe.displayservicenames": "true", + "bigpipe.hostnamelookup": "false", + "bigstart.childoutput": "console", + "bigstart.logging": "disable", + "boot.netreboot": "disable", + "boot.quiet": "enable", + "botd.inactivitytimeoutmin": "15", + "botd.maxopenincidents": "10000", + "botd.maxsamplerequests": "20", + "botdefense.always_add_p3p_header": "disable", + "botdefense.centralized_device_id_cookie_value_prefix": "dsc", + "botdefense.challenge_failure_reporting": "enable", + "botdefense.challenge_failure_text": "Oops....something went wrong.... your support id is: %DOSL7.challenge.support_id%.", + "botdefense.content_security_policy": "enable", + "botdefense.cshui_ajax_renewal_seconds": "120", + "botdefense.cshui_checked_trusted_events": "mousedown, mouseup, mousemove, keydown, keyup, touchstart, touchmove, touchend", + "botdefense.cshui_cscloud_enabled": "disable", + "botdefense.cshui_cscloud_timeout": "1000", + "botdefense.cshui_cscloud_url": "https://re.security.f5aas.com/re/", + "botdefense.cshui_max_distance_mouse_down": "60", + "botdefense.cshui_max_last_segment_length": "300", + "botdefense.cshui_min_human_keys_to_bypass_rapid_keys": "2", + "botdefense.cshui_min_key_duration_ms_bot": "18", + "botdefense.cshui_min_key_duration_ms_human": "25", + "botdefense.cshui_min_mouse_duration_ms_bot": "18", + "botdefense.cshui_min_touch_duration_ms_bot": "15", + "botdefense.disable_cache_upon_injection": "false", + "botdefense.dns_cache_expiry_sec": "300", + "botdefense.ignore_ip_counter_when_did": "false", + "botdefense.invalid_js_score": "99", + "botdefense.invalid_jsfree_score": "99", + "botdefense.ips_to_ignore_counters": ",", + "botdefense.max_js_verification_seconds": "30", + "botdefense.min_rootkit_functions": "10", + "botdefense.safari_redirect_no_cookie_mode": "enable", + "botdefense.support_http2_proxy": "disable", + "botdefense.suspicious_js_score": "49", + "botdefense.suspicious_jsfree_score": "49", + "bwc.dist": "enable", + "bwc.dynamic.proxybuffering": "enable", + "bwc.iflow.fairness": "disable", + "bwc.load.interval": "44", + "bwc.measure.factor": "2", + "bwc.measure.samplewindow": "3", + "bwc.measure.smoothwindow": "2", + "bwc.policy": "enable", + "bwc.recharge.interval": "439", + "bwc.static.proxybuffering": "enable", + "bwc.sweeper.interval": "10", + "bwc.tc": "enable", + "bwc.tc.maxburst": "200", + "bwc.tc.maxsurplus": "200", + "bwc.trace": "disable", + "bwc.trace.ctb": "0", + "bwc.trace.dist": "0", + "bwc.trace.measure": "0", + "bwc.trace.policy": "0", + "bwc.trace.probe": "0", + "bwc.trace.pubapi": "0", + "bwc.trace.refcnt": "0", + "bwc.trace.stb": "0", + "bwc.trace.stbema": "0", + "bwc.trace.tc": "0", + "capture.capture_clean_count": "2000", + "capture.capture_pause_after_sec": "10", + "capture.capture_resume_after_sec": "110", + "capture.delete_after_send": "enable", + "capture.dump_clean_disk_percent": "35", + "capture.dump_clean_size_mb": "5120", + "capture.dump_clean_time_sec": "0", + "capture.dump_size_limit_mb": "10240", + "capture.log_level": "info", + "capture.margin_sec": "2", + "capture.min_cpu_percent": "20", + "capture.min_disk_percent": "25", + "capture.premonitor.asm_brute_force_attack": "disable", + "capture.premonitor.asm_web_scraping_attack": "disable", + "capture.premonitor.dosl7_attack": "disable", + "capture.send": "disable", + "capture.send_limit_rate_mbsec": "0", + "capture.slice_max_size_mb": "10", + "capture.slice_sec": "2", + "capture.ssl_modify_ciphers": "enable", + "capture.tcpdump": "enable", + "capture.trigger.asm_brute_force_attack": "disable", + "capture.trigger.asm_web_scraping_attack": "disable", + "capture.trigger.dosl7_attack": "disable", + "cbrd.bigrequestsize": "1048576", + "cbrd.maxqueryresults": "100", + "cbrd.pendingtransactions": "5000", + "cbrd.requestsize": "10240", + "cbrd.umuthreshold": "90", + "ccdb.allow.edge.jpegxr": "false", + "cgnat.lsnlegacyeditor": "false", + "cloud.licensed.bewaf": "disable", + "cluster.blade.green.count": "0", + "cluster.mgmtipaddr": "::", + "cluster.primary": "false", + "cluster.primary.slot": "0", + "clusterd.communicateovertmmbp": "true", + "clusterd.peermembertimeout": "10", + "clustered.environment": "false", + "clustermbr.offlineondisable": "true", + "cmp.feature_disable": "0", + "cmp.hash.p8.port.bitshift": "0", + "cmp.hash.p8sp.ip.bitshift": "0", + "cmp.hash.tunnel": "outer", + "cmp.maxqueuedmsgs": "150000", + "cmp.optimize.throughput": "ipv4", + "compression.adaptive.allownullcompression": "disable", + "compression.adaptive.maxreduction": "10", + "compression.allowproviderselectiondeferral": "enable", + "compression.nitrox3.dispatchsize": "61170", + "compression.nitrox3.forcefixed": "true", + "compression.octeon.dispatchsize": "61170", + "compression.octeon.ratio": "4", + "compression.offload.ratio": "4", + "compression.providerbusy": "100", + "compression.qat.dispatchsize": "65535", + "compression.reselect.provider": "enable", + "compression.strategy": "speed", + "compression.tmm.maxcpu": "75", + "compression.tmm.ratio": "1", + "compression.zlibbombsensitivity.sizemb": "1024", + "compression.zlibinflateratio.threshold": "100", + "config.allow.rfc3927": "disable", + "config.auditing": "enable", + "config.auditing.forward.destination": "::", + "config.auditing.forward.multiple": "none", + "config.auditing.forward.sharedsecret": "", + "config.auditing.forward.tacacs.timeout.response": "5", + "config.auditing.forward.type": "none", + "config.auditing.truncate": "disable", + "configsync.allowmanagement": "disable", + "configsync.copyonswitch": "disable", + "configsync.heartbeattimeout": "3", + "configsync.hotfixversionmatch": "disabled", + "configsync.localconfigtime": "0", + "configsync.password": "unused", + "configsync.peeripaddr": "::", + "configsync.peertimeoutofsync": "false", + "configsync.timesyncthreshold": "3", + "configsync.username": "admin", + "connection.adaptivereaper.hiwater": "95", + "connection.adaptivereaper.lowater": "85", + "connection.adaptivereaper.neverreapprotectedflows": "disable", + "connection.autolasthop": "enable", + "connection.dsrsynfloodprotect": "disable", + "connection.globalflowpolicy": "/Common/default-eviction-policy", + "connection.syncookies.algorithm": "hardware", + "connection.syncookies.threshold": "16384", + "connection.synoffload.threshold": "4049", + "connection.vgl2transparent": "disable", + "connection.vlankeyed": "enable", + "connections.preestablished.threshold": "8192", + "cpu.logthreshold": "0", + "crypto.ha": "enable", + "crypto.ha.action": "go-offline-downlinks", + "crypto.hwacceleration": "enable", + "crypto.queue.timeout": "100", + "d68.acceleration.strategy": "throughput", + "dag.api.log.level": "Informational", + "dag.config": "default", + "dag.dagv2.hsbs": "", + "dag.dagv2.mirror.hsbs": "", + "dag.dagv2.mirror.pgs": "", + "dag.dagv2.pgs": "", + "dag.enabledagv2": "true", + "dag.hash.fold.bits": "8", + "dag.overridetablesize": "0", + "dag.roundrobin.udp.portlist": "0", + "dag.rrdag.redirect": "disable", + "dag.userconfigipv6prefixlen": "false", + "dagv2.pu.table.size.multiplier": "1", + "datastor.cache.size": "0", + "datastor.restrict.dev.size": "0", + "datastor.store.size": "0", + "datasync.core_dump_on_sigabrt": "disable", + "datasync.del_old_update_files": "enable", + "datasync.device_stats_interval_seconds": "60", + "datasync.error_retry_interval_seconds": "60", + "datasync.extract_update_files": "enable", + "datasync.generated_data_sync": "enable", + "datasync.gzip": "enable", + "datasync.gzip_fpm": "disable", + "datasync.hard_max_offline_seconds": "0", + "datasync.ignore_installed_updates.clntcap": "disable", + "datasync.ignore_installed_updates.fps_engine": "disable", + "datasync.ignore_installed_updates.fps_signatures": "disable", + "datasync.inline_scripts": "disable", + "datasync.keep_generated_dirs": "5", + "datasync.max_sync_bandwidth_kb_sec": "10000", + "datasync.min_disk_available_percent": "20", + "datasync.nice_when_online": "10", + "datasync.offline_gen_pause_seconds": "1", + "datasync.offline_until_devices_ack": "disable", + "datasync.process_interval_ms": "1000", + "datasync.read_loaded_update_files_interval_seconds": "300", + "datasync.read_new_update_files_interval_seconds": "60", + "datasync.rsync_interval_seconds": "3", + "datasync.save_config_after_change": "enable", + "datasync.soft_max_offline_seconds": "0", + "datasync.update_clntcap_from_factory": "enable", + "datasync.update_engine_from_factory": "enable", + "datasync.update_file_del_grace_factor": "3600", + "datasync.update_file_del_grace_offset": "10", + "datasync.update_file_gen_profile": "enable", + "datasync.update_file_gen_time": "7200", + "datasync.update_file_report": "disable", + "datasync.update_signatures_from_factory": "enable", + "datasync.use_mcp_for_update_files": "enable", + "ddm.bcm56xxd.enable": "disable", + "ddm.bcm56xxd.interval": "12", + "debug.afm.shun.notify_peers": "enable", + "debug.afm.shun.persistence": "disable", + "debug.doshwdropredirect.disables": "0", + "debug.hwdropredirect.interface": "", + "debug.register.maxtcpdumpsession": "1", + "debug.swdropredirect.interface": "", + "deduplication.dictionary.size": "32", + "device.request.timeoutfactor": "200", + "dhclient.mgmt": "enable", + "diameter.allowemptyorigin": "disable", + "diameter.endpoint.peertimeout": "10000", + "diameter.endpoint.reconnecttime": "30000", + "diameter.endpoint.watchdogtimeout": "30000", + "diameter.mblb.hopid_replace": "disable", + "diameter.message.maxlen": "65536", + "diameter.message.pending.high": "300000", + "diameter.message.pending.low": "100000", + "did.always_refresh": "disable", + "did.anchors_must_match_query": "enable", + "did.cookie_expire_sec": "1200", + "did.dids_delete_factor": "10", + "did.initial_sample_size": "50", + "did.learning_sampling_per_second": "1", + "did.local_storage_name": "TSPD_74", + "did.match_mode": "complex", + "did.max_allowed_same_requests": "2", + "did.max_allowed_same_requests_period": "10", + "did.max_device_ids": "250000", + "did.max_dids_query_rate": "100", + "did.max_ix_size_mb": "250", + "did.max_pending_queries": "500", + "did.mobile_simple_match_score": "85", + "did.similarity_period": "30", + "did.similarity_threshold": "5", + "did.solid_similarity_period": "1200", + "did.test_fp_requests": "disable", + "did.use_browser_local_storage": "enable", + "did.validation_interval_sec": "300", + "dns.action.queue.max": "16384", + "dns.actions.poll": "128", + "dns.cache": "disable", + "dns.configure": "do not change", + "dns.contexts.poll": "128", + "dns.dns64statsincludecache": "disable", + "dns.domainname": "", + "dns.ingress.queue.high": "262144", + "dns.ingress.queue.low": "196608", + "dns.maxudp": "4096", + "dns.nameservers": "0.0.0.0", + "dns.proxy.__iter__": "", + "dns.queuing": "enable", + "dns.responsematching": "disable", + "dns.udptruncate": "enable", + "dns.xfr.msgbuffermax": "131072", + "dnscache.ephemeralsnocache": "disable", + "dnscache.forcerecursionavailablebit": "disable", + "dnscache.matchwildcardvip": "false", + "dnscache.maxqueryrestarts": "11", + "dnscacheresolver.loglevel": "notice", + "dnsexpress.dbwritedelay": "15", + "dnsexpress.dbwritensd": "false", + "dnsexpress.dumpastext": "false", + "dnsexpress.hugepages": "0", + "dnsexpress.includeds": "false", + "dnsexpress.maxnotifypersec": "0", + "dnsexpress.minimalresponse": "false", + "dnsexpress.notifyport": "0", + "dnsexpress.persisthugepages": "false", + "dnsexpress.rpzupdatetime": "0", + "dnsexpress.rrperzonestats": "true", + "dnsexpress.rrsetrotate": "random", + "dnsexpress.rrtcpclose": "server", + "dnsexpress.xfrbackloggeddelay": "5", + "dnsexpress.xfrjitter": "false", + "dnsexpress.xfrnotifydelay": "5", + "dnsexpress.xfrpendingmax": "100", + "dnsexpress.xfrtimeout": "5", + "dnssec.fipswaitingqueuecap": "0", + "dnssec.maxnsec3persec": "0", + "dnssec.nsec3apextypesbitmap": "ns soa rrsig nsec3param dnskey", + "dnssec.nsec3underapextypesbitmap": "txt rrsig", + "dnssec.signaturecachemaxentries": "131072", + "dnssec.signaturecachensec3": "true", + "dnssec.signwaitqueuecap": "0", + "dnssec.xfr.finalrrmax": "1024", + "dnssec.xfr.pktmax": "64000", + "dnssec.xfr.timeout": "5", + "dos.allvlans": "true", + "dos.auto.threshold.hysteresis": "5", + "dos.auto.threshold.learnalways": "true", + "dos.auto.threshold.stresstest": "10000", + "dos.autodosd.alpha_max": "90", + "dos.autodosd.alpha_min": "20", + "dos.behavioral.analysis": "enable", + "dos.blleaklimit": "255", + "dos.debug.noneuron.wl": "false", + "dos.dns.respfrag.allow": "true", + "dos.dnsnxdomain.learnperiod": "7200", + "dos.dnsnxdomain.period": "86400", + "dos.dnsnxdomain.trackersize": "320", + "dos.dnsport": "53", + "dos.dnsvlan": "0", + "dos.dropv4mapped": "false", + "dos.forceswdos": "false", + "dos.fragforwardlimit": "0", + "dos.globalsflimits": "true", + "dos.httpbdos.exclusivity": "enabled", + "dos.httpbdos.exclusivity.timeout": "120", + "dos.icmp6msgtype1": "158", + "dos.icmp6msgtype2": "158", + "dos.ip.allow.unknown.proto1": "255", + "dos.ip.allow.unknown.proto2": "255", + "dos.iplowttl": "1", + "dos.ipv6.swexthdr": "true", + "dos.ipv6endpoint.prefix": "128", + "dos.ipv6lowhopcnt": "1", + "dos.logging.interval": "1", + "dos.maxdnssize": "4096", + "dos.maxewlsize": "256", + "dos.maxicmp6framesize": "1460", + "dos.maxicmpframesize": "1480", + "dos.maxipv6exthdrs": "4", + "dos.maxipv6extsize": "128", + "dos.maxsynsize": "64", + "dos.mergepersec": "20", + "dos.onehourinitrate": "0", + "dos.onehourminrate": "100", + "dos.protectedzone": "enable", + "dos.scrubtime": "10", + "dos.sip.uri.limit": "1024", + "dos.sipport": "5060", + "dos.spvabl.checkdynamicwl": "true", + "dos.syncookiedeactivate": "50", + "dos.tcp.allow.unknown.opt1": "0", + "dos.tcp.allow.unknown.opt2": "0", + "dos.tcplowwindowsize": "0", + "dos.tier1divisor": "2", + "dos.tscookie.vlan": "0", + "dos.unmatched.hwsyncookie_activate": "80", + "dos.vcmphwdos": "false", + "dos.wl_spva_entries_max": "1000", + "dos.wlipv6addrsel": "2", + "dosl7.allowed_origins": ",", + "dosl7.asm_cs_excluded_headers": ",", + "dosl7.asm_cs_excluded_urls": ",", + "dosl7.assume_https": "disable", + "dosl7.captcha_case_sensitivity": "disable", + "dosl7.captcha_challenge_type": "characters", + "dosl7.captcha_characters_pool": "ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789", + "dosl7.captcha_length_max": "6", + "dosl7.captcha_length_min": "6", + "dosl7.captcha_lines_max": "5", + "dosl7.captcha_lines_min": "5", + "dosl7.captcha_max_cpu_prc": "90", + "dosl7.captcha_noise_max": "2", + "dosl7.captcha_noise_min": "2", + "dosl7.captcha_perturbation_max": "85", + "dosl7.captcha_perturbation_min": "85", + "dosl7.captcha_transparency_percentage_max": "20", + "dosl7.captcha_transparency_percentage_min": "20", + "dosl7.chal_data_cookie_max_age": "30", + "dosl7.cors_ajax_urls": ",", + "dosl7.cors_font_urls": ",", + "dosl7.cors_related_domains": ",", + "dosl7.cs_encode": "enable", + "dosl7.cs_encrypt": "disable", + "dosl7.cs_excluded_headers": ",", + "dosl7.cs_excluded_urls": ",", + "dosl7.cs_expire_sec": "60", + "dosl7.cs_max_request_size": "10000", + "dosl7.cs_max_resend": "3", + "dosl7.cs_qualified_urls": ",", + "dosl7.cs_validate_ip": "enable", + "dosl7.cscloud_enabled": "disable", + "dosl7.cscloud_timeout": "1000", + "dosl7.cscloud_url": "https://re.security.f5aas.com/re/", + "dosl7.customheaders": "", + "dosl7.early_renewal_period": "30", + "dosl7.efoxy_cookie": "enable", + "dosl7.efoxy_local_storage": "enable", + "dosl7.efoxy_websql": "enable", + "dosl7.efoxy_window_name": "enable", + "dosl7.fastl4_allow": "enable", + "dosl7.geolocation_drop_private_ips": "disable", + "dosl7.idle_fast_path": "enable", + "dosl7.internal_url_cookie_expiration_time": "30", + "dosl7.long_ua_header_size": "0", + "dosl7.max_captcha_solution_age": "10", + "dosl7.max_captcha_solution_time": "120", + "dosl7.max_cookie_length": "10000", + "dosl7.max_dynamic_params_injection_length": "6000", + "dosl7.max_lookup_length": "255", + "dosl7.max_num_headers": "50", + "dosl7.max_user_agent_occurrences": "3", + "dosl7.min_captcha_solution_time": "2", + "dosl7.mobile_cookie_expire_sec": "120", + "dosl7.noscript_text": "Please enable JavaScript to view the page content.
Your support ID is: %DOSL7.noscript.support_id%.", + "dosl7.p3p_header": "CP=\"{}\"", + "dosl7.params": "none", + "dosl7.parse_html_content_types": "text/html", + "dosl7.parse_html_excluded_accept_header_values": "image,video,audio", + "dosl7.parse_html_excluded_extentions": "gif,png,bmp,jpg,ico,css,mp3,mp4,mpg,avi,wmv,mov,3gp,fla,swf,js", + "dosl7.parse_html_excluded_urls": ",", + "dosl7.parse_html_inject_tags": "after,head,before,script,before,/head,before,body", + "dosl7.prg_cookie_urls": ",", + "dosl7.prg_iframe_urls": ",", + "dosl7.proactive_defense_cookie_name": "TSPD_101", + "dosl7.proactive_defense_excluded_headers": ",", + "dosl7.proactive_defense_fictive_url": "/TSPD/", + "dosl7.proactive_defense_log_rate_limit": "300", + "dosl7.proactive_defense_max_http_request_length": "4096", + "dosl7.proactive_defense_prefix": "TSPD", + "dosl7.proactive_defense_renew_sec": "300", + "dosl7.proactive_defense_simple_redirect": "enable", + "dosl7.proactive_defense_simple_redirect_on_grace": "enable", + "dosl7.proactive_defense_validate_ip": "enable", + "dosl7.proactive_defense_validation_percent": "100", + "dosl7.report_acy_perf": "disable", + "dosl7.selenium_timeout": "150", + "dosl7.sign_embeded_script": "disable", + "dosl7.test": "disable", + "dosl7.use_secure_cookies": "disable", + "dosl7.web_rootkit_report_min_score": "4", + "dosl7d.attack_wait_timeout": "30", + "dosl7d.auto_below_thresh_timeout": "30", + "dosl7d.auto_cold_start_first_period_length": "120", + "dosl7d.auto_cold_start_first_period_switch_period": "60", + "dosl7d.auto_cold_start_second_period_length": "1320", + "dosl7d.auto_drop_ratio": "80", + "dosl7d.auto_geo_slice_length": "3600", + "dosl7d.auto_normal_switch_period": "720", + "dosl7d.auto_num_of_top_device_id": "64", + "dosl7d.auto_num_of_top_geolocation": "16", + "dosl7d.auto_num_of_top_ip": "128", + "dosl7d.auto_num_of_top_url": "512", + "dosl7d.auto_stress_thresh_multiplier": "150", + "dosl7d.auto_time_scale_factor": "1", + "dosl7d.auto_tps_thresh_multiplier": "300", + "dosl7d.clean_bot_publisher_anomalies": "1800", + "dosl7d.conf_change_freeze_on_period": "30", + "dosl7d.cs_legitimate_successful_rate": "50", + "dosl7d.cs_max_reply_time": "10", + "dosl7d.cs_min_requests_for_replies": "10", + "dosl7d.force_core_on_sigabrt": "disable", + "dosl7d.grafana_report": "disable", + "dosl7d.grafana_report_top_only": "enable", + "dosl7d.heaviness_factor": "200", + "dosl7d.max_attack_duration": "10800", + "dosl7d.max_icc_buffer_size": "2048", + "dosl7d.max_tcpdump_cpu_usage": "80", + "dosl7d.max_tcpdump_files": "1000", + "dosl7d.max_tcpdump_size": "10240", + "dosl7d.min_challenge_drop_time": "20", + "dosl7d.min_challenge_rps": "10", + "dosl7d.min_challenge_success_ratio": "10", + "dosl7d.min_geo_reliable_time": "72", + "dosl7d.min_heavy_url_drop_rate": "2", + "dosl7d.min_time_between_attacks": "30", + "dosl7d.min_time_for_attack_end": "120", + "dosl7d.min_transaction_count_per_interval": "10", + "dosl7d.publish_custom_message": "disable", + "dosl7d.shun_list": "enable", + "dosl7d.shun_prevention_time": "120", + "dosl7d.sliding_window_long": "86400", + "dosl7d.sliding_window_medium": "7200", + "dosl7d.sliding_window_short": "60", + "dosl7d.static_uri_protection": "enable", + "dosl7d.stress_absolute_threshold": "1", + "dosl7d.stress_relative_threshold": "100", + "dosl7d.susp_max_entities": "10000", + "dosl7d.tcpdump_rstcause": "disable", + "dosl7d.trigger_logging": "0", + "dynconfd.loglevel": "error", + "ecm.tm.compression": "0", + "ecm.tm.configport": "4475", + "ecm.tm.customcert": "0", + "ecm.tm.ecmport": "4473", + "ecm.tm.httpadapterport": "4476", + "ecm.tm.retries": "20", + "ecm.tm.ssl": "0", + "ecm.tm.tmport": "4474", + "fad.badpktpassrate": "1000", + "fad.ignoreresult": "false", + "failover.activemode": "disable", + "failover.activetime": "0", + "failover.bigipunitmask": "0", + "failover.crcvalues": "agree", + "failover.dbgfile": "/var/log/sodlog", + "failover.debug": "disable", + "failover.debugsteadystate": "disable", + "failover.forceactive": "disable", + "failover.forceoffline": "disable", + "failover.forcestandby": "disable", + "failover.hacable": "unset", + "failover.isredundant": "false", + "failover.linksup": "false", + "failover.manfailback": "disable", + "failover.mirrorl4pkts": "disable", + "failover.nettimeoutsec": "3", + "failover.network": "disable", + "failover.offlinelinkdown.port": "1030", + "failover.packetcheck": "enable", + "failover.packetchecklog": "enable", + "failover.printpeerstate": "enable", + "failover.rebootviasod": "enable", + "failover.secure": "disable", + "failover.selinuxallowscripts": "disable", + "failover.somehascores": "no", + "failover.standby.linkdowntime": "0", + "failover.standbytime": "0", + "failover.state": "offline", + "failover.substate": "none", + "failover.unitid": "1", + "failover.usetty01": "enable", + "failover.vlanfailsafe.resettimeronanyframe": "false", + "failover.vlanfailsafe.standbynoaction": "disable", + "failover.vlanfailsafe.startuptimer": "90", + "fault_monitord.disk_check.interval": "30", + "fault_monitord.disk_check.threshold": "90", + "flowspec.max.expired_and_saved_rules": "100", + "fw_nat.source.translation.proxy_arp": "enable", + "fw_nat.subscriber.id.lookup.count": "2", + "geolocation.preload": "enable", + "georedundancy.watchdog.period": "5", + "georedundancy.watchdog.timeoutperiods": "12", + "gre.lookupip": "disable", + "gtm.configtime": "0", + "gtm.coredump": "enable", + "gtm.crlfilecheckinterval": "10", + "gtm.debugprobelogging": "disable", + "gtm.debugprobetuninginterval": "0", + "gtm.dynamiclbsecondarymode": "round_robin", + "gtm.loadlinkcost": "disable", + "gtm.maxpersistsyncspersecond": "800", + "gtm.maxproxybufsize": "262144", + "gtm.onetimeautoconfig": "disable", + "gtm.peerinfolocalid": "-1", + "gtm.peerinfototalgtms": "0", + "gtm.persistsynctimespan": "10", + "gtm.querylogging": "disable", + "gtm.reqinitstate": "ready", + "gtm.selfdevicename": "", + "gtm.verbosemcpmessages": "disable", + "gtm.wideiptoporandom": "disable", + "hostname": "bigip1", + "hostname.ip.custom": "::", + "hostname.ip.mode": "mgmt", + "httpagents.realserver.log": "false", + "httpagents.stripipv6mappedipv4": "true", + "httpagents.wmi.log": "false", + "httpd.basic_auth": "enable", + "httpd.matchclient": "true", + "httpd.samesite_cookie": "strict", + "httpsecurity.avrstatenabled": "true", + "httpsecurity.maxheaderslengthlog": "1024", + "httpsecurity.maxheadervaluelength": "2048", + "httpsecurity.maxurllengthlog": "128", + "httpsecurity.uselastxff": "false", + "hwpd.status": "quiescent", + "iapplxrpm.timeout": "60", + "icontrol.basic_auth": "enable", + "icontrol.dtdparsing": "disable", + "icontrol.forcesessions": "disable", + "icontrol.groupid": "DefaultGroup", + "icontrol.loglevel": "none", + "icontrol.webrootenforcement": "disable", + "icrd.timeout": "60", + "icsa.forceadminpacketlogging": "disable", + "ilx.handlewait": "100", + "ipproto.lookupip": "disable", + "iprep.autoupdate": "enable", + "iprep.intervalmin": "5", + "iprep.ipv6intervalmin": "60", + "iprep.port": "443", + "iprep.protocol": "auto-detect", + "iprep.server": "api.bcti.brightcloud.com", + "iprep.sockettimeout": "15", + "ipsec.aesgmacinterop": "disable", + "ipsec.assign.msecs": "20", + "ipsec.debug.logkeys": "1", + "ipsec.debug.logsk": "0", + "ipsec.debug.pfkey.msg": "0", + "ipsec.debug.spi.load": "0", + "ipsec.disablepfs": "false", + "ipsec.icsaforceipfrag": "disable", + "ipsec.icsalogrejectedesp": "disable", + "ipsec.if.checkpolicy": "enable", + "ipsec.ikev2certificatedepth": "4", + "ipsec.ivchaining": "disable", + "ipsec.lookupip": "disable", + "ipsec.lookupspi": "enable", + "ipsec.maxroutedomain": "512", + "ipsec.maxtrafficselectors": "100", + "ipsec.migrate.cpu.diff": "8", + "ipsec.migrate.ha.pfkey": "0", + "ipsec.narrow.icmp": "0", + "ipsec.owner.algo": "0", + "ipsec.passesp": "enable", + "ipsec.pfkey.load": "0", + "ipsec.port.identity": "0", + "ipsec.proxymode": "disable", + "ipsec.recently.assigned": "1", + "ipsec.removeredundantsa": "disable", + "ipsec.removeredundantsa.delay": "0", + "ipsec.reorderqdepth": "1", + "ipsec.sessiondb.copymsg": "0", + "ipsec.sp.migrate": "0", + "ipsec.sp.owner": "0", + "ipsec.traceflags": "0", + "iptunnel.configsync": "enable", + "iptunnel.csumoffload": "enable", + "iptunnel.ether_nodag": "disable", + "iptunnel.gtp.teid_hash": "disable", + "iptunnel.hf.opaqueflags": "0", + "iptunnel.mac_overwrite": "disable", + "iptunnel.macaddr_per_tunnel": "disable", + "iptunnel.mpls_strip": "disable", + "iptunnel.nvgre.ethertype": "25944", + "iptunnel.transparent.flow.allocate": "enable", + "iptunnel.v6rd.antispoofing": "disable", + "iptunnel.vxlan.udpport": "0", + "iptunnel.vxlan.vtepidletimeout": "300", + "ipv6.dad.recovery": "0", + "ipv6.enabled": "true", + "ipv6.host.router_probe_interval": "5", + "ipv6.nbr.delaytime": "1", + "ipv6.nbr.incompletetimeout": "5", + "ipv6.nbr.maxentries": "2048", + "ipv6.nbr.priority": "normal", + "ipv6.nbr.reachabletimeout": "30", + "ipv6.nbr.reaptimeout": "3600", + "ipv6.nbr.retries": "3", + "ipv6.nbr.vlanpriority": "-1", + "ipv6.strictcompliance": "false", + "isession.compression.buffers": "4", + "isession.compression.fudgefactor": "9", + "isession.compression.highthresholdwatermarklevel": "10", + "isession.compression.lowthresholdwatermarklevel": "0", + "isession.compression.threshold": "95", + "isession.control.ipsec": "disable", + "isession.controlconnection.count": "1", + "isession.controlconnection.lock": "false", + "isession.ctrl.apm": "enable", + "isession.dedup.wirecheck": "true", + "kernel.ibpb_ibrs": "IBPB0-IBRS0", + "kernel.iommu": "disable", + "kernel.pti": "enable", + "keyboard.type": "US - Standard 101 key", + "l2.virtualwire.multicast.bridging": "enable", + "l2.virtualwire.multicast.stats": "enable", + "l2.virtualwire.standby.bridging": "disable", + "l2.virtualwire.tcn.connection.drop": "disable", + "l2.virtualwire.tcn.recovery.connection.drop.timeout": "0", + "l4bdos.anomaly.detection.frequency": "10", + "l4bdos.anomaly.threshold.floor": "1000", + "l4bdos.asym.anomaly.threshold.percent": "10", + "l4bdos.asym.kmeans.ctrl": "20", + "l4bdos.asym.learning.mode": "false", + "l4bdos.baseline.learning.period": "120", + "l4bdos.collect.stats.frequency": "2", + "l4bdos.dns.stress.compute.frequency": "200", + "l4bdos.ha.state.update.frequency": "600", + "l4bdos.netflow.collect.frequency": "1", + "l4bdos.netflow.disable.selective.bins": "false", + "l4bdos.packet.sampling.interval": "1", + "l4bdos.signature.disable.no_stats.periods": "5", + "l4bdos.signature.sample.packet.frequency": "0", + "l4bdos.transient.signature.merge.periods": "2", + "l4bdos.zerolearning.mitsens.high.mitigation": "80", + "l4bdos.zerolearning.mitsens.high.throughput": "15", + "l4bdos.zerolearning.mitsens.low.bins": "7", + "l4bdos.zerolearning.mitsens.low.mitigation": "95", + "l4bdos.zerolearning.mitsens.low.throughput": "10", + "l4bdos.zerolearning.mitsens.medium.mitigation": "90", + "l4bdos.zerolearning.mitsens.medium.throughput": "12", + "lacpd.refport.stick": "true", + "lcd.showmenu": "enable", + "led.locator": "disable", + "license.allowea": "true", + "license.antifraud.applicationencryption": "", + "license.antifraud.automatictransactiondetection": "", + "license.antifraud.id": "", + "license.antifraud.malwaredetection": "", + "license.antifraud.mobilesafe": "", + "license.antifraud.phishingdetection": "", + "license.forcedisabled": "", + "license.ignorecrc": "false", + "license.maxcores": "0", + "license.operational": "false", + "license.registrationkey": "", + "license.servicecheckdateok": "true", + "license.versionstate": "licensed", + "liveinstall.checksig": "disable", + "liveinstall.longmode": "enable", + "liveinstall.moveconfig": "enable", + "liveinstall.movelicense": "enable", + "liveinstall.packageset": "default", + "liveinstall.saveconfig": "enable", + "liveinstall.savelicense": "enable", + "liveupdate.allowautoinstallonsecondary": "false", + "liveupdate.autodownload": "enable", + "log.access.db": "enable", + "log.access.syslog": "enable", + "log.access.tmm.async": "enable", + "log.accesscontrol.level": "Notice", + "log.accessperrequest.level": "Notice", + "log.adapt.level": "Error", + "log.alertapmaccessthreshold": "75", + "log.alertapmconnectivitythreshold": "75", + "log.alertapmurlflimitedthreshold": "75", + "log.alertapmurlfthreshold": "75", + "log.alertbwthreshold": "75", + "log.alertd.level": "notice", + "log.antifraud.datasync": "disable", + "log.antifraud.level": "Notice", + "log.antifraud.request": "disable", + "log.antifraud.response": "disable", + "log.antifraud.sessiondb": "disable", + "log.arp.level": "Warning", + "log.asm.asmconfig.level": "info", + "log.asm.asmconfigevent.level": "info", + "log.asm.asmconfigverbose.level": "info", + "log.asm.asmcrond.level": "info", + "log.asm.asmlogd.level": "info", + "log.asm.bdagent.level": "debug", + "log.asm.clustering.level": "info", + "log.asm.dos.level": "info", + "log.asm.other.level": "debug", + "log.auth.level": "Error", + "log.autodiscd.level": "Error", + "log.autodosd.level": "Error", + "log.bcm56xxd.debugmask": "0", + "log.bcm56xxd.level": "Informational", + "log.bcm56xxd.tbuf": "50000", + "log.bdosd.level": "Error", + "log.big3d.level": "notice", + "log.big3dprobeplus.level": "crit", + "log.big3dshim.level": "notice", + "log.botd.level": "Info", + "log.clusterd.level": "Notice", + "log.clusterd.stdout": "disable", + "log.config.level": "Error", + "log.connector.level": "Error", + "log.csyncd.level": "Notice", + "log.csyncd.stdout": "disable", + "log.debugd.level": "Error", + "log.deflate.level": "Error", + "log.devmgmt.level": "Informational", + "log.diameter.level": "Error", + "log.dosl7.acy.level": "Notice", + "log.dosl7.all.level": "Notice", + "log.dosl7.bot.level": "Notice", + "log.dosl7.challenge.level": "Notice", + "log.dosl7.conf.level": "Notice", + "log.dosl7.datasync.level": "Notice", + "log.dosl7.main.level": "Notice", + "log.dosl7.misc.level": "Notice", + "log.dosl7.mobile.level": "Notice", + "log.dosl7.tcl.level": "Notice", + "log.dosprotect.level": "Warning", + "log.duplicateaddress.level": "Warning", + "log.dwbld.level": "Informational", + "log.eca.level": "Notice", + "log.em.admin.level": "Notice", + "log.em.alert.level": "Notice", + "log.em.device.level": "Notice", + "log.em.file.level": "Notice", + "log.em.stats.level": "Notice", + "log.em.swim.level": "Notice", + "log.evrouted.level": "Notice", + "log.evrouted.stdout": "disable", + "log.failover.level": "Informational", + "log.fault_monitord.level": "warning", + "log.fix.level": "Notice", + "log.flowspecd.level": "Error", + "log.ftp.level": "Notice", + "log.fw_fqdn.level": "Notice", + "log.fw_nat.level": "Notice", + "log.gtm.level": "notice", + "log.gtp.level": "Error", + "log.guestagentd.level": "Informational", + "log.ha.level": "Notice", + "log.halmsg.level": "Error", + "log.hclientd.level": "Notice", + "log.hornet.lib.level": "Notice", + "log.hornet.nest.level": "Notice", + "log.hornet.nestflowmanager.level": "Notice", + "log.hornet.nestupdater.level": "Notice", + "log.hornet.neuronupdater.level": "Notice", + "log.hornet.server.level": "Notice", + "log.hornet.textclient.level": "Notice", + "log.hostagentd.level": "Informational", + "log.http.level": "Error", + "log.httpsecurity.level": "Notice", + "log.hwpd.level": "Notice", + "log.icap.level": "Error", + "log.icr_eventd.level": "notice", + "log.imap.level": "Error", + "log.ip.level": "Warning", + "log.ipfix.display_info": "disable", + "log.ipfix.level": "Notice", + "log.ipfix.template_idle_timeout": "120", + "log.ipfix.template_utilization": "90", + "log.ipfixirules.level": "Notice", + "log.iprep.level": "Info", + "log.ipsecalg.level": "Notice", + "log.isession.level": "Notice", + "log.istatsd.level": "Notice", + "log.ivs.level": "Error", + "log.keymgmtd.level": "notice", + "log.lacpd.debugmask": "0", + "log.lacpd.level": "Informational", + "log.layer4.level": "Notice", + "log.libhal.level": "Notice", + "log.lind.level": "Notice", + "log.lind.stdout": "disable", + "log.lldpd.level": "Informational", + "log.lsn.comma": "disable", + "log.lsn.inbound": "disable", + "log.lsn.level": "Error", + "log.lsn.session.destination": "disable", + "log.lsn.session.end": "disable", + "log.lsn.session.start": "enable", + "log.lsnapi.level": "Error", + "log.map.level": "Notice", + "log.mcpd.level": "notice", + "log.mcpd.timing": "disable", + "log.mcpd.userregex": "", + "log.mdm.level": "Notice", + "log.merged.level": "warning", + "log.mgmt_acld.level": "Informational", + "log.monpd.level": "Informational", + "log.mr.level": "Error", + "log.mrftrap.level": "Error", + "log.mrmqtt.level": "Error", + "log.mrsip.level": "Error", + "log.natstatsd.level": "Error", + "log.net.level": "Warning", + "log.networkaccess.level": "Notice", + "log.nsyncd.level": "info", + "log.ocsp_responder.level": "Error", + "log.pccd.level": "Notice", + "log.pcp.level": "Error", + "log.pfmand.level": "Informational", + "log.pfmand.stdout": "disable", + "log.pkcs11d.level": "Error", + "log.pktclass.level": "Notice", + "log.pktfilter.level": "Notice", + "log.policy.level": "Informational", + "log.pop3.level": "Error", + "log.pptp.level": "Notice", + "log.rba.level": "Notice", + "log.rewrite.level": "Notice", + "log.rules.level": "Informational", + "log.saas.level": "Error", + "log.sctp.level": "Warning", + "log.sdmd.level": "info", + "log.sdmd.stdout": "disable", + "log.service.level": "Error", + "log.sflow.level": "Notice", + "log.smtps.level": "Error", + "log.sshplugin.level": "Informational", + "log.ssl.level": "Warning", + "log.sso.level": "Notice", + "log.statsd.level": "warning", + "log.statusd.level": "Notice", + "log.stpd.debugstr": ".", + "log.stpd.level": "Warning", + "log.sweeper.activation.enabled": "true", + "log.sweeper.evictions.interval": "2", + "log.tamd.level": "Error", + "log.tcpdump.level": "Notice", + "log.tftp.level": "Notice", + "log.tma.level": "Notice", + "log.tmm.level": "Notice", + "log.ts.level": "Informational", + "log.tunnel.level": "Notice", + "log.vcmpd.level": "Informational", + "log.vcmpd.stdout": "disable", + "log.vdi.level": "Notice", + "log.vxland.level": "Notice", + "log.webapplications.level": "Notice", + "log.webapplications.trace.sessionid": "", + "log.webssh.level": "Notice", + "log.wr_urldb.level": "Warning", + "log.zrd.level": "notice", + "log.zxfrd.level": "notice", + "logcheck.alertthres": "90", + "logcheck.msgcnt": "1000", + "logcheck.warnthres": "80", + "logintegrity.loglevel": "error", + "logintegrity.support": "disable", + "logpublisher.atomic": "true", + "logpublisher.logstash_rfc5424_fix": "false", + "logrotate.logage": "8", + "ltm.configtime": "0", + "mapt.role": "0", + "mcp.gtm.objnamectrlcharvalidation": "log", + "mcpd.baseconfigloaded": "false", + "mcpd.client.msgbytes.overflow.highmark": "5000000", + "mcpd.client.msgbytes.overflow.lowmark": "4000000", + "mcpd.client.msgbytes.overflow.timeout": "4800", + "mcpd.daemon.msgbytes.overflow.highmark": "25000000", + "mcpd.daemon.msgbytes.overflow.lowmark": "20000000", + "mcpd.daemon.msgbytes.overflow.timeout": "1800", + "mcpd.initialload": "wide", + "mcpd.maxdbsize": "512", + "mcpd.msgcnt.overflow.highmark": "1000000", + "mcpd.msgcnt.overflow.lowmark": "900000", + "mcpd.msgcnt.overflow.timeout": "1800", + "mcpd.mvenabled": "false", + "mcpd.restrictsecondary": "true", + "mcpd.validation.fqdn": "enable", + "mcpd.vastatusinterval": "3", + "md.afmsampling": "1", + "md.cleanupnontmmlookupsintervalseconds": "300", + "md.cleanuprealtimedataintervalseconds": "60", + "md.delaybeforeclusterpublish": "5", + "md.dologging": "0", + "md.geopath": "/usr/share/GeoIP/F5GeoIP.dat", + "md.mincspminjectionskewinterval": "60", + "md.monitoringthreadpriority": "TS,0", + "md.showexternalloggingdescription": "1", + "merged.correlateprocess.enable": "true", + "merged.correlateprocess.importance": "999", + "merged.istats.merge.interval": "10", + "merged.merge": "public_tables", + "merged.merge.interval": "1", + "merged.method": "fast_merge", + "merged.nice.level": "5", + "merged.snapshots": "true", + "mgmt.autolasthop": "enable", + "mgmt.portlogging.bandwidthcap": "60", + "mgmt.portlogging.listenerretry": "2", + "mgmt.portlogging.serverretry": "2", + "mgmt.portlogging.servertimeout": "30", + "mgmt_acld.disable_ifmap": "false", + "mgmt_acld.ucase_dom": "false", + "mgmt_acld.use_debug_timeouts": "false", + "mhdag.bitshift": "6", + "mhdag.pu.table.size.multiplier": "1", + "mode.maint": "disable", + "mode.master": "false", + "mqtt.egress_buffer_high_threshold": "32768", + "mrf.mqtt.client_id_max_len": "1024", + "mrf.mqtt.client_id_prefix_max_len": "128", + "mrf.mqtt.will_message_max_len": "128", + "mrf.mqtt.will_topic_max_len": "128", + "mysqldfailure.enabled": "true", + "mysqldfailure.haaction.primary": "restart_all", + "mysqldfailure.haaction.secondary": "go_offline", + "mysqlhad.dbgfile": "/var/log/mysqlhad.log", + "mysqlhad.debug": "false", + "mysqlhad.heartbeattimeout": "30", + "mysqlhad.restartsbeforeaction": "1", + "named.worker.threads": "1", + "nest.nde_alloc_factor": "2", + "nest.num_active_nde": "0", + "net.tunnel.globals.hostmanaged": "false", + "nethsm.safenet.hsmip": "", + "nethsm.thales.hsmip": "::", + "nethsm.thales.rfsip": "::", + "neuron.tmmclienttest": "0", + "neurond.debug.driver": "disable", + "neurond.debug.force_nsp_rsp": "disable", + "neurond.debug.i2c": "disable", + "neurond.debug.ilk": "disable", + "neurond.debug.lookup": "disable", + "neurond.debug.lookup_force": "disable", + "neurond.debug.mcp": "disable", + "neurond.debug.mpde": "disable", + "neurond.debug.no_keepalive": "disable", + "neurond.debug.no_nsp_keepalive": "disable", + "neurond.debug.rule_add": "disable", + "neurond.debug.rule_del": "disable", + "neurond.debug.rule_move": "disable", + "neurond.debug.rule_sort": "disable", + "neurond.debug.sanity": "disable", + "neurond.debug.sanity_light": "disable", + "nitrox3.compression.hangreset": "reset", + "nsh.debuglevel": "0", + "nsh.demodebug": "disable", + "nsh.egresspathid": "456", + "nsh.egressserviceid": "255", + "nsh.enable": "enable", + "nsh.ingresscheck": "disable", + "nsh.ingresspathid": "123", + "nsh.ingressserviceid": "7", + "nsh.nextprotocol": "3", + "nsh.vxlangpe.innermac.replace": "enable", + "nsh.vxlanport": "6633", + "ntp.servers": "", + "ntp.timezone": "America/Los_Angeles", + "offbox.health.window": "5000", + "offbox.log.level": "0", + "packetfilter": "disable", + "packetfilter.allow.arp": "enable", + "packetfilter.allow.important.icmp": "enable", + "packetfilter.defaultaction": "accept", + "packetfilter.defaultlog": "disable", + "packetfilter.established": "disable", + "packetfilter.sendicmperrors": "disable", + "password.dcredit": "0", + "password.difok": "8", + "password.lcredit": "0", + "password.maxdays": "99999", + "password.maxloginfailures": "0", + "password.mindays": "0", + "password.minlen": "6", + "password.ocredit": "0", + "password.remember": "0", + "password.ucredit": "0", + "password.unlock_time": "0", + "password.warndays": "7", + "pccd.alwaysfromscratch": "false", + "pccd.deploy.timeout": "30", + "pccd.extramb": "0", + "pccd.form.adminip": "ipt", + "pccd.form.global": "afc", + "pccd.form.iapp": "afc", + "pccd.form.rtdom": "afc", + "pccd.form.selfip": "afc", + "pccd.form.virtual": "afc", + "pccd.hash.load.factor": "25", + "pccd.maxblobsize": "4090", + "pccd.overlap.check": "enable", + "pccd.perpolicycompilation": "true", + "pccd.retry.count": "5", + "pccd.rule.debug": "false", + "pccd.status": "quiescent", + "pem.sessiondb.stats.max.entries": "100000", + "persist.destaddrcarpipport": "disable", + "persist.destaddrlimitmode": "timeout", + "persist.destaddrmaxcount": "2048", + "persist.srcaddrcarpipport": "disable", + "persist.wellknownproxyclass": "/Common/aol", + "pfmand.healthstatus": "disable", + "pfmand.healthstatus.deviceerror.ceiling": "15", + "pfmand.healthstatus.guesterror.ceiling": "20", + "platform.chassis.lcd": "enable", + "platform.chassis.slot": "0", + "platform.cpu.fanspeed.threshold": "0", + "platform.cpu.temperature.threshold": "0", + "platform.disklatency.enabled": "true", + "platform.disklatency.loginterval": "60", + "platform.disklatency.readinterval": "1", + "platform.disklatency.readsize": "512", + "platform.disklatency.vcmpreadinterval": "60", + "platform.diskmonitor.freelast._root_": "0", + "platform.diskmonitor.freelast.appdata": "0", + "platform.diskmonitor.freelast.config": "0", + "platform.diskmonitor.freelast.dev": "0", + "platform.diskmonitor.freelast.dev_shm": "0", + "platform.diskmonitor.freelast.run": "0", + "platform.diskmonitor.freelast.run_pamcache": "0", + "platform.diskmonitor.freelast.shared": "0", + "platform.diskmonitor.freelast.shared_rrd.1.2": "0", + "platform.diskmonitor.freelast.usr": "0", + "platform.diskmonitor.freelast.var": "0", + "platform.diskmonitor.freelast.var_log": "0", + "platform.diskmonitor.freelast.var_loipc": "0", + "platform.diskmonitor.freelast.var_prompt": "0", + "platform.diskmonitor.freelast.var_tmstat": "0", + "platform.diskmonitor.freelast.vmdisk": "0", + "platform.diskmonitor.growthalert._root_": "5", + "platform.diskmonitor.growthalert.appdata": "5", + "platform.diskmonitor.growthalert.config": "5", + "platform.diskmonitor.growthalert.dev": "5", + "platform.diskmonitor.growthalert.dev_shm": "5", + "platform.diskmonitor.growthalert.run": "5", + "platform.diskmonitor.growthalert.run_pamcache": "5", + "platform.diskmonitor.growthalert.shared": "5", + "platform.diskmonitor.growthalert.shared_rrd.1.2": "5", + "platform.diskmonitor.growthalert.usr": "5", + "platform.diskmonitor.growthalert.var": "3", + "platform.diskmonitor.growthalert.var_log": "5", + "platform.diskmonitor.growthalert.var_loipc": "5", + "platform.diskmonitor.growthalert.var_prompt": "5", + "platform.diskmonitor.growthalert.var_tmstat": "5", + "platform.diskmonitor.growthalert.vmdisk": "5", + "platform.diskmonitor.interval": "10", + "platform.diskmonitor.limitalert._root_": "3", + "platform.diskmonitor.limitalert.appdata": "20", + "platform.diskmonitor.limitalert.config": "20", + "platform.diskmonitor.limitalert.dev": "20", + "platform.diskmonitor.limitalert.dev_shm": "20", + "platform.diskmonitor.limitalert.run": "20", + "platform.diskmonitor.limitalert.run_pamcache": "20", + "platform.diskmonitor.limitalert.shared": "20", + "platform.diskmonitor.limitalert.shared_rrd.1.2": "20", + "platform.diskmonitor.limitalert.usr": "20", + "platform.diskmonitor.limitalert.var": "20", + "platform.diskmonitor.limitalert.var_log": "10", + "platform.diskmonitor.limitalert.var_loipc": "20", + "platform.diskmonitor.limitalert.var_prompt": "20", + "platform.diskmonitor.limitalert.var_tmstat": "20", + "platform.diskmonitor.limitalert.vmdisk": "25", + "platform.diskmonitor.limitwarn._root_": "5", + "platform.diskmonitor.limitwarn.appdata": "30", + "platform.diskmonitor.limitwarn.config": "30", + "platform.diskmonitor.limitwarn.dev": "30", + "platform.diskmonitor.limitwarn.dev_shm": "30", + "platform.diskmonitor.limitwarn.run": "30", + "platform.diskmonitor.limitwarn.run_pamcache": "30", + "platform.diskmonitor.limitwarn.shared": "30", + "platform.diskmonitor.limitwarn.shared_rrd.1.2": "30", + "platform.diskmonitor.limitwarn.usr": "30", + "platform.diskmonitor.limitwarn.var": "40", + "platform.diskmonitor.limitwarn.var_log": "20", + "platform.diskmonitor.limitwarn.var_loipc": "30", + "platform.diskmonitor.limitwarn.var_prompt": "30", + "platform.diskmonitor.limitwarn.var_tmstat": "30", + "platform.diskmonitor.limitwarn.vmdisk": "40", + "platform.diskmonitor.monitor._root_": "limit", + "platform.diskmonitor.monitor.appdata": "limit", + "platform.diskmonitor.monitor.config": "limit", + "platform.diskmonitor.monitor.dev": "limit", + "platform.diskmonitor.monitor.dev_shm": "limit", + "platform.diskmonitor.monitor.run": "limit", + "platform.diskmonitor.monitor.run_pamcache": "limit", + "platform.diskmonitor.monitor.shared": "limit", + "platform.diskmonitor.monitor.shared_rrd.1.2": "limit", + "platform.diskmonitor.monitor.usr": "limit", + "platform.diskmonitor.monitor.var": "limit", + "platform.diskmonitor.monitor.var_log": "limit", + "platform.diskmonitor.monitor.var_loipc": "limit", + "platform.diskmonitor.monitor.var_prompt": "limit", + "platform.diskmonitor.monitor.var_tmstat": "limit", + "platform.diskmonitor.monitor.vmdisk": "limit", + "platform.diskmonitor.state": "enable", + "platform.diskmonitor.time": "0", + "platform.diskmonitor.time._root_": "0", + "platform.diskmonitor.time.appdata": "0", + "platform.diskmonitor.time.config": "0", + "platform.diskmonitor.time.dev": "0", + "platform.diskmonitor.time.dev_shm": "0", + "platform.diskmonitor.time.run": "0", + "platform.diskmonitor.time.run_pamcache": "0", + "platform.diskmonitor.time.shared": "0", + "platform.diskmonitor.time.shared_rrd.1.2": "0", + "platform.diskmonitor.time.usr": "0", + "platform.diskmonitor.time.var": "0", + "platform.diskmonitor.time.var_log": "0", + "platform.diskmonitor.time.var_loipc": "0", + "platform.diskmonitor.time.var_prompt": "0", + "platform.diskmonitor.time.var_tmstat": "0", + "platform.diskmonitor.time.vmdisk": "0", + "platform.fantray.speedcontrol": "auto", + "platform.powersupplymonitor": "enable", + "provision.1nic": "disable", + "provision.1nicautoconfig": "enable", + "provision.action": "none", + "provision.afm.extramb": "0", + "provision.cpu.afm": "0", + "provision.cpu.am": "0", + "provision.cpu.apm": "0", + "provision.cpu.asm": "0", + "provision.cpu.avr": "0", + "provision.cpu.cgnat": "0", + "provision.cpu.dos": "0", + "provision.cpu.em": "0", + "provision.cpu.fps": "0", + "provision.cpu.gtm": "0", + "provision.cpu.host": "0", + "provision.cpu.ilx": "0", + "provision.cpu.lc": "0", + "provision.cpu.ltm": "0", + "provision.cpu.pem": "0", + "provision.cpu.sslo": "0", + "provision.cpu.swg": "0", + "provision.cpu.tam": "0", + "provision.cpu.tmos": "10", + "provision.cpu.urldb": "0", + "provision.cpu.vcmp": "0", + "provision.disk.afm": "0", + "provision.disk.am": "0", + "provision.disk.apm": "0", + "provision.disk.asm": "0", + "provision.disk.avr": "0", + "provision.disk.cgnat": "0", + "provision.disk.dos": "0", + "provision.disk.em": "0", + "provision.disk.fps": "0", + "provision.disk.gtm": "0", + "provision.disk.host": "0", + "provision.disk.ilx": "0", + "provision.disk.lc": "0", + "provision.disk.ltm": "0", + "provision.disk.pem": "0", + "provision.disk.sslo": "0", + "provision.disk.swg": "0", + "provision.disk.tam": "0", + "provision.disk.tmos": "0", + "provision.disk.urldb": "0", + "provision.disk.vcmp": "0", + "provision.enforce": "true", + "provision.extramb": "0", + "provision.initialized": "false", + "provision.managementeth": "eth0", + "provision.memory.afm": "0", + "provision.memory.afm.host": "0", + "provision.memory.am": "0", + "provision.memory.am.host": "0", + "provision.memory.apm": "0", + "provision.memory.apm.host": "0", + "provision.memory.asm": "0", + "provision.memory.asm.host": "0", + "provision.memory.avr": "0", + "provision.memory.avr.host": "0", + "provision.memory.cgnat": "0", + "provision.memory.cgnat.host": "0", + "provision.memory.dos": "0", + "provision.memory.dos.host": "0", + "provision.memory.em": "0", + "provision.memory.em.host": "0", + "provision.memory.fps": "0", + "provision.memory.fps.host": "0", + "provision.memory.gtm": "0", + "provision.memory.gtm.host": "0", + "provision.memory.host": "0", + "provision.memory.ilx": "0", + "provision.memory.ilx.host": "0", + "provision.memory.lc": "0", + "provision.memory.lc.host": "0", + "provision.memory.ltm": "0", + "provision.memory.ltm.host": "0", + "provision.memory.pem": "0", + "provision.memory.pem.host": "0", + "provision.memory.sslo": "0", + "provision.memory.sslo.host": "0", + "provision.memory.swg": "0", + "provision.memory.swg.host": "0", + "provision.memory.tam": "0", + "provision.memory.tam.host": "0", + "provision.memory.tmos": "0", + "provision.memory.tmos.host": "0", + "provision.memory.ui": "0", + "provision.memory.urldb": "0", + "provision.memory.urldb.host": "0", + "provision.memory.vcmp": "0", + "provision.memory.vcmp.host": "0", + "provision.noautoreboot": "false", + "provision.pending": "false", + "provision.restjavad.extramb": "384", + "provision.tmmcount": "0", + "provision.tmmcountactual": "0", + "provision.tomcat.extramb": "0", + "provision.wocplugincount": "1", + "provisioned.cpu.afm": "0", + "provisioned.cpu.am": "0", + "provisioned.cpu.apm": "0", + "provisioned.cpu.asm": "0", + "provisioned.cpu.avr": "0", + "provisioned.cpu.cgnat": "0", + "provisioned.cpu.dos": "0", + "provisioned.cpu.em": "0", + "provisioned.cpu.fps": "0", + "provisioned.cpu.gtm": "0", + "provisioned.cpu.host": "0", + "provisioned.cpu.ilx": "0", + "provisioned.cpu.lc": "0", + "provisioned.cpu.ltm": "0", + "provisioned.cpu.pem": "0", + "provisioned.cpu.sslo": "0", + "provisioned.cpu.swg": "0", + "provisioned.cpu.tam": "0", + "provisioned.cpu.tmos": "10", + "provisioned.cpu.urldb": "0", + "provisioned.cpu.vcmp": "0", + "provisioned.disk.afm": "0", + "provisioned.disk.am": "0", + "provisioned.disk.apm": "0", + "provisioned.disk.asm": "0", + "provisioned.disk.avr": "0", + "provisioned.disk.cgnat": "0", + "provisioned.disk.dos": "0", + "provisioned.disk.em": "0", + "provisioned.disk.fps": "0", + "provisioned.disk.gtm": "0", + "provisioned.disk.host": "0", + "provisioned.disk.ilx": "0", + "provisioned.disk.lc": "0", + "provisioned.disk.ltm": "0", + "provisioned.disk.pem": "0", + "provisioned.disk.sslo": "0", + "provisioned.disk.swg": "0", + "provisioned.disk.tam": "0", + "provisioned.disk.tmos": "0", + "provisioned.disk.urldb": "0", + "provisioned.disk.vcmp": "0", + "provisioned.memory.afm": "0", + "provisioned.memory.afm.host": "0", + "provisioned.memory.am": "0", + "provisioned.memory.am.host": "0", + "provisioned.memory.apm": "0", + "provisioned.memory.apm.host": "0", + "provisioned.memory.asm": "0", + "provisioned.memory.asm.host": "0", + "provisioned.memory.avr": "0", + "provisioned.memory.avr.host": "0", + "provisioned.memory.cgnat": "0", + "provisioned.memory.cgnat.host": "0", + "provisioned.memory.dos": "0", + "provisioned.memory.dos.host": "0", + "provisioned.memory.em": "0", + "provisioned.memory.em.host": "0", + "provisioned.memory.fps": "0", + "provisioned.memory.fps.host": "0", + "provisioned.memory.gtm": "0", + "provisioned.memory.gtm.host": "0", + "provisioned.memory.host": "0", + "provisioned.memory.ilx": "0", + "provisioned.memory.ilx.host": "0", + "provisioned.memory.lc": "0", + "provisioned.memory.lc.host": "0", + "provisioned.memory.ltm": "0", + "provisioned.memory.ltm.host": "0", + "provisioned.memory.pem": "0", + "provisioned.memory.pem.host": "0", + "provisioned.memory.sslo": "0", + "provisioned.memory.sslo.host": "0", + "provisioned.memory.swg": "0", + "provisioned.memory.swg.host": "0", + "provisioned.memory.tam": "0", + "provisioned.memory.tam.host": "0", + "provisioned.memory.tmos": "0", + "provisioned.memory.tmos.host": "0", + "provisioned.memory.ui": "0", + "provisioned.memory.urldb": "0", + "provisioned.memory.urldb.host": "0", + "provisioned.memory.vcmp": "0", + "provisioned.memory.vcmp.host": "0", + "proxy.host": "", + "proxy.password": "", + "proxy.port": "8080", + "proxy.protocol": "http", + "proxy.username": "", + "pva.acceleration": "full", + "pva.evictunknownflow": "1", + "pva.fix.lowlatency": "disable", + "pva.fwdaccel": "disable", + "pva.offload.uniflow": "false", + "pva.priorityratethresholdkb.high": "5120", + "pva.priorityratethresholdkb.low": "1", + "pva.priorityratethresholdkb.medium": "50", + "pva.reoffload.delay": "5", + "pva.reoffload.exponential": "true", + "pva.standby.flush": "0", + "pva.tenantdirectmode": "disable", + "pva.thrashratepercentage": "30", + "pva.udpest.clientpkts.threshold": "2", + "pva.udpest.serverpkts.threshold": "1", + "pva.validatetcpseqinicmp": "true", + "pvamsgrawdump.samples.reset": "0", + "pvasyncookies.enabled": "true", + "pvasyncookies.hashmode": "default", + "pvasyncookies.preferhwlmode": "false", + "pvasyncookies.secretupdate.interval": "4", + "pvasyncookies.virtual.connthresholdhigh": "5", + "pvasyncookies.virtual.invalidthreshold": "4", + "pvasyncookies.virtual.maxsyncache": "2999", + "qat.deflate.buffer_size": "medium", + "qat.dev.infl.sample.modulus": "100", + "qat.dev.infl.timer.period": "5", + "qinq.cos": "outer", + "quic.bit.grease": "enable", + "quic.cmetrics": "enable", + "quic.config.validate": "enable", + "quic.preestablished.threshold": "16384", + "quic.qlogging": "disable", + "quickassist.compression.buffertype": "medium", + "quickassist.crypto.pollperiod": "60", + "radius.messageauthenticator": "false", + "ramcache.gzipconsolidate": "enable", + "ramcache.interstripecachememorypercent": "25", + "ramcache.maxmemorypercent": "50", + "rateshaper.cmpdivide": "enable", + "rateshaper.logratelimit": "0", + "restjavad.disablepackagemanagementtasks": "false", + "restjavad.disablerpmtasks": "false", + "restjavad.startup.restnodedrestart.awaittimeout": "1200", + "restjavad.timeout": "60", + "restnoded.timeout": "60", + "rewrite.html.maxtagsizekb": "1024", + "riskengine.status": "disable", + "route.metrics.maxentries": "0", + "route.metrics.mtu": "enable", + "route.metrics.timeout": "600", + "route.metrics.validated_update": "enable", + "rule.validation": "strict", + "saspd.gwmdowndelay": "30", + "saspd.loglevel": "error", + "scheduler.busypoll": "false", + "scheduler.dynamicsleepduration.ltm": "true", + "scheduler.enableschedpause.ltm": "false", + "scheduler.hsbasleeprxlimit.ltm": "256", + "scheduler.hsbawakerxlimit.ltm": "256", + "scheduler.hsblowlatencyborder.ltm": "20", + "scheduler.hsbpollmode.ltm": "always", + "scheduler.hsbtimeout.ltm": "250", + "scheduler.idleenforcercue.ltm": "-1", + "scheduler.idleenforcerhaltus.ltm": "-1", + "scheduler.idleenforcerv1pluginminactive.ltm": "1", + "scheduler.idleenforcerv1pluginmininactive.ltm": "5", + "scheduler.idleenforceryieldus.ltm": "-1", + "scheduler.idlesampleperiod.ltm": "100", + "scheduler.ixlv.contigidlecnt": "256", + "scheduler.maxsleepduration.ltm": "-1", + "scheduler.minsleepduration.ltm": "-1", + "scheduler.resetstatsfrequency.ltm": "-1", + "scheduler.rtcfrequency.ltm": "-1", + "scheduler.splitplanes.asmopt": "true", + "scheduler.splitplanes.ltm": "true", + "scheduler.usertc.ltm": "false", + "scrubber.counthwdrop": "false", + "sdag.cdp.log.level": "Informational", + "sdag.log.level": "Informational", + "sdag.proxy.log.level": "Informational", + "sdag.runtime.hashtable": "", + "sdag.shuffle.table": "0", + "security.cabundledownload": "enable", + "security.cloud_services.allow": "disable", + "security.cloud_services.default_url": "", + "security.commoncriteria": "false", + "security.commoncriteria.stip": "false", + "security.commoncriteria.stip.drbg_enabled": "false", + "security.commoncriteria.stip.drbg_timer": "300", + "security.commoncriteria.stip.external_audit_server_enabled": "false", + "security.commoncriteria.stip.external_audit_server_pool": "", + "security.commoncriteria.stip.integrity_enabled": "false", + "security.configexport": "false", + "security.configpassword": "", + "security.fips140.compliance": "false", + "security.fips140.fipserror.recoverythreshold": "3", + "security.fips140.isdaemoncompliancereq": "true", + "security.fips140.isintegritytestreq": "true", + "security.minkeysize.level": "Warning", + "security.tap.allow": "disabled", + "service.cloudinit": "enable", + "service.httpd.allow": "::", + "service.snmp.allow": "127.0.0.0/8", + "service.ssh": "enable", + "service.ssh.allow": "ALL", + "setup.run": "true", + "sfc.loglevel": "1", + "sfc.strict_ifc_si": "disable", + "sflow.min_sampling_rate.http": "100", + "sflow.min_sampling_rate.packet": "1024", + "snat.anyipprotocol": "disable", + "snat.hosttraffic": "disable", + "snmp.bigiptraps": "enable", + "snmp.bigiptraps.suppress.count": "3", + "snmp.bigiptraps.suppress.interval": "60", + "snmp.daemon": "enable", + "snmp.snmpdca.log": "false", + "snmp.v1.enabled": "enable", + "snmp.v2.enabled": "enable", + "softpva.ipv4": "disable", + "softpva.ipv6": "disable", + "softpva.size": "0", + "spdy.serverhighwatermark": "128", + "spdy.serverlowwatermark": "0", + "ssd.availablespace.warningmargin": "20", + "ssd.mediawearoutindicator.warningmargin": "20", + "ssh.maxsessionlimit": "10", + "ssh.maxsessionlimitperuser": "-1", + "ssh.rootsessionlimit": "disable", + "ssh.sessionlimit": "disable", + "sshplugin.allow_return_auth_success_for_auth_none_request": "false", + "sshplugin.max_active_serverside_rekeys": "100", + "sshplugin.max_num_outstanding_threads": "100", + "sshplugin.outstanding_thread_lifetime_max": "60", + "sshplugin.thread_stack_size_kb": "2048", + "ssl.certrequest.commonname": "_undef_", + "ssl.certrequest.countryname": "US", + "ssl.certrequest.divisionname": "_undef_", + "ssl.certrequest.localityname": "_undef_", + "ssl.certrequest.organizationname": "_undef_", + "ssl.certrequest.stateorprovincename": "_undef_", + "ssl.fallback_scsv": "enable", + "ssl.fips.failuretimeout": "60", + "ssl.forwardproxy.inspectionconsent": "no", + "ssl.forwardproxy.localforgedcertlog": "disable", + "ssl.handshake.threshold": "4096", + "ssl.outerrecordtls1_0": "enable", + "ssl.renegotiatewithinitialclienthello": "disable", + "ssl.sessionticketkey.regen": "252900", + "ssl.tls12.ios5": "false", + "statemirror.clustermirroring": "within", + "statemirror.graceperiod": "5", + "statemirror.heartbeat": "500", + "statemirror.ipaddr": "::", + "statemirror.mirrorsessions": "enable", + "statemirror.peeripaddr": "::", + "statemirror.peerlistenport": "1028", + "statemirror.primary.autofailback": "true", + "statemirror.queuelen": "8388608", + "statemirror.queuepct": "15", + "statemirror.reconnect.delay": "1", + "statemirror.secondary.ipaddr": "::", + "statemirror.secondary.peeripaddr": "::", + "statemirror.secure": "enable", + "statemirror.state": "enable", + "statemirror.tcpmssadjust": "0", + "statemirror.timeout": "60", + "statemirror.verify": "disable", + "statsd.cpu.interval": "1", + "statsd.disk.interval": "5", + "statsd.diskstats.log.interval": "60", + "statsd.host.interval": "5", + "statsd.intelpcm.interval": "0", + "statsd.process.cleanup.offset": "10", + "statsd.process.list": "all", + "statsd.process.poll.interval": "10", + "statsd.traffic.interval": "1", + "statsd.virtual.server.interval": "5", + "switchboard.bcm5692_a1_fe_ipg_fix": "enable", + "switchboard.buffer.ingress.pgdynamic": "disable", + "switchboard.buffer.maxdynport": "100", + "switchboard.buffer.maxdyntotal.egress": "50", + "switchboard.buffer.maxdyntotal.ingress": "85", + "switchboard.dos.control": "133", + "switchboard.failsafe": "enable", + "switchboard.failsafe.action": "go_offline_abort_tm", + "switchboard.failsafe.mode": "active", + "switchboard.failsafe.timeout": "30", + "switchboard.l2.mitigation": "monitor", + "switchboard.link.recoveryaction": "None", + "switchboard.link.recoverythreshold": "6", + "switchboard.maxbcastrate": "200000", + "switchboard.maxdlfrate": "200000", + "switchboard.maxmcastrate": "200000", + "switchboard.startup.linkdowntime": "0", + "switchboard.wred": "disable", + "switchboard.wred.dropslope": "20", + "switchboard.wred.dropstart": "75", + "systemauth.disablebash": "false", + "systemauth.disableduserhardening.lock": "false", + "systemauth.disableduserhardening.shell": "false", + "systemauth.disableexternalmonitors": "false", + "systemauth.disablelocaladminlockout": "false", + "systemauth.disablemanualunlock": "false", + "systemauth.disablerootlogin": "false", + "systemauth.fallback.remotetolocal": "false", + "systemauth.nolocalonly": "false", + "systemauth.permitloginwithoutheaders": "disable", + "systemauth.primaryadminuser": "admin", + "systemauth.source": "local", + "tamd.crldp.nosignature": "disable", + "tamd.crldp.nullcrl": "disable", + "tamd.worker.threads": "100", + "tap.config.applytimeout": "300", + "tap.config.period": "60", + "tap.log.level": "0", + "tcp.hash": "port", + "tcpdump.ifname": "1.1", + "tcpdump.sslprovider": "disable", + "telemd.loglevel": "error", + "tm.acceptipoptions": "disable", + "tm.acceptipsourceroute": "disable", + "tm.allowethernetsourcetype": "unicast", + "tm.allowigmprouteralert": "enable", + "tm.allowipsourceroute": "disable", + "tm.allowmulticastl2destinationtraffic": "disable", + "tm.bfdegressdscp": "0", + "tm.bfdpassthrough": "disable", + "tm.bgpegressdscp": "0", + "tm.blackholeunreachable": "disable", + "tm.clonel2higigcontrol": "enable", + "tm.continuematching": "false", + "tm.dsrlocalencap": "disable", + "tm.dupsynenforce": "enable", + "tm.egress.pktpriority": "3", + "tm.egressdscp": "0", + "tm.enforcepathmtu": "enable", + "tm.expirenatondelete": "disable", + "tm.fastl4_ack_mirror": "enable", + "tm.fastl4_ignore_sctp_zero_checksum": "disable", + "tm.fastl4_invalid_pmtu_passthrough": "disable", + "tm.fastl4_mirroring_taciturn": "disable", + "tm.fastl4_rst_on_icmp": "enable", + "tm.flowstate.timeout": "30", + "tm.fragmenttimeout": "6", + "tm.fw.defaultaction": "accept", + "tm.fw.defaultrule.log": "disable", + "tm.fw.globaldefaultrule.log": "disable", + "tm.fw.iptbl.sweeper.period": "1200", + "tm.fw.log.action.acceptdecisiveasaccept": "false", + "tm.fw.log.syslogrfc5424.customfields": "false", + "tm.fw.stageddefaultrule.log": "disable", + "tm.fw.stagedglobaldefaultrule.log": "disable", + "tm.hud_history_depth": "0", + "tm.icsaicmpreplay": "allow", + "tm.icsastricttcpforwarding": "disable", + "tm.ipfragmemlimit": "35", + "tm.ipfragreassemblestrict": "disable", + "tm.ipv4dagfrag": "disable", + "tm.l2forwardidletimeout": "300", + "tm.lhpnomemberaction": "0", + "tm.linklocal.allowservice": "none", + "tm.lsn.dnat_suppress_logs_period": "300", + "tm.lsn.pick_duration_microseconds": "1500", + "tm.lsn.retries": "512", + "tm.macmasqaddr_per_vlan": "false", + "tm.maxforwardicmprate": "0", + "tm.maxicmprate": "100", + "tm.maxipfragpkts": "4096", + "tm.maxipfragsperpkt": "128", + "tm.maxrejectrate": "250", + "tm.maxrejectrate.timeout": "30", + "tm.minipfragsize": "552", + "tm.minipv6fragsize": "1232", + "tm.minpathmtu": "296", + "tm.monitorencap": "disable", + "tm.pathmtudiscovery": "enable", + "tm.pathmtudontfragoverride": "disable", + "tm.portfind.linear": "16", + "tm.portfind.random": "16", + "tm.portfind.src_preserve": "false", + "tm.portfind.threshold.timeout": "30", + "tm.portfind.threshold.trigger": "8", + "tm.portfind.threshold.warning": "true", + "tm.pptp.timeout": "60", + "tm.ratetracker.t2suppressor": "10", + "tm.rejectunmatched": "true", + "tm.rstcause.log": "disable", + "tm.rstcause.pkt": "disable", + "tm.simultaneousopen": "allow", + "tm.socket.log.aborts": "disable", + "tm.strongipid": "disable", + "tm.sweeper.avr.freq": "256", + "tm.sweeper.flow.acl": "enable", + "tm.sweeper.flow.del.dist": "disable", + "tm.sweeper.flow.ipint": "enable", + "tm.tcp.enforcepathmtu": "disable", + "tm.tcp.oc.proxymss": "disable", + "tm.tcpabcsslimit": "2", + "tm.tcpaggressivepartialack": "disable", + "tm.tcpallowinsecurerst": "disable", + "tm.tcpanalytics.min_geoip_cf": "0", + "tm.tcpanalytics.reportinterval": "2000", + "tm.tcpforwardchecksumadjust": "false", + "tm.tcpinitwinafterxon": "enable", + "tm.tcpinitwinmultiplierafterxon": "1", + "tm.tcplargereceivecompact": "enable", + "tm.tcplargereceiveoffload": "enable", + "tm.tcpmemorypressure": "enable", + "tm.tcpmemorypressure.hiwater": "90", + "tm.tcpmemorypressure.lowater": "80", + "tm.tcpmptcpdebugenabled": "disable", + "tm.tcpmptcpdiagenabled": "disable", + "tm.tcpmptcpenabled": "enable", + "tm.tcpmptcpjoinsysmax": "10000", + "tm.tcpmptcpselectivertx": "disable", + "tm.tcpmptcptokensync": "enable", + "tm.tcpprogressive.autobuffertuning": "disable", + "tm.tcpprogressive.autonaglerttthresh": "20", + "tm.tcpprogressive.burstcontrol": "disable", + "tm.tcpprogressive.proxybufmax": "2097152", + "tm.tcpprogressive.proxybufmin": "65535", + "tm.tcpprogressive.proxybufoffset": "65535", + "tm.tcpprogressive.rcvbufbdpmultiplier": "1", + "tm.tcpprogressive.rcvbufincr": "65536", + "tm.tcpprogressive.rcvbufincrsmall": "2", + "tm.tcpprogressive.rcvbufmax": "16777216", + "tm.tcpprogressive.rcvbufmin": "65535", + "tm.tcpprogressive.rcvbufmininterval": "100", + "tm.tcpprogressive.rttthresh": "10", + "tm.tcpprogressive.sndbufbdpmultiplier": "1", + "tm.tcpprogressive.sndbufincr": "65536", + "tm.tcpprogressive.sndbufincrsmall": "2", + "tm.tcpprogressive.sndbufmax": "16777216", + "tm.tcpprogressive.sndbufmin": "131070", + "tm.tcpprogressive.sndbufmininterval": "100", + "tm.tcpsackglobalmaxholes": "65536", + "tm.tcpsackmaxholes": "128", + "tm.tcpsegmentationoffload": "enable", + "tm.tcpsendrandomtimestamp": "disable", + "tm.tcpsendsynackmssalways": "enable", + "tm.tcpslowstartafteridle": "enable", + "tm.tcpstopblindinjection": "disable", + "tm.tcptimestampmirror": "enable", + "tm.tcptracing": "0", + "tm.tcptxpausemax": "256", + "tm.tcptxpausemin": "100", + "tm.tcpudpiprxchecksum": "default", + "tm.tcpudptxchecksum": "Hardware-enabled", + "tm.tcpwoodsidefasterrecovery": "disable", + "tm.udpmaxrateidleperiod": "10", + "tm.udpqueueinitialdropprobability": "0", + "tm.udpqueueoccupancythreshold": "30", + "tmm.access.auta": "disable", + "tmm.access.extendedlog": "enable", + "tmm.access.logouturlrefererheadercheck": "disable", + "tmm.access.maxrequestbodysize": "64000", + "tmm.access.policytrace": "disable", + "tmm.access.prp_global_timeout": "5", + "tmm.access.prprejectendingnoserversidehs": "enable", + "tmm.access.subsessionstateprefix": "000fffff", + "tmm.cdp.debug": "0", + "tmm.cdp.requirematchingstates": "disable", + "tmm.ce.statsuppressed": "false", + "tmm.cec.classifier.abr.enable": "false", + "tmm.cec.classifier.abr.max_packets": "256", + "tmm.cec.classifier.asme.enable": "true", + "tmm.cec.classifier.behavioral.enable": "false", + "tmm.cec.classifier.behavioral.evc_max_packets": "22500", + "tmm.cec.classifier.bittorrent.enable": "true", + "tmm.cec.classifier.dfa.enable": "true", + "tmm.cec.classifier.dns.caching.timeout": "0", + "tmm.cec.classifier.dns.enable": "true", + "tmm.cec.classifier.ftp.enable": "true", + "tmm.cec.classifier.http2.enable": "true", + "tmm.cec.classifier.http.enable": "true", + "tmm.cec.classifier.http.max_headers": "64", + "tmm.cec.classifier.ixe.enable": "false", + "tmm.cec.classifier.openvpn.enable": "true", + "tmm.cec.classifier.quic.enable": "true", + "tmm.cec.classifier.rtmp.enable": "true", + "tmm.cec.classifier.rtsp.enable": "true", + "tmm.cec.classifier.sip.enable": "true", + "tmm.cec.classifier.skype.enable": "true", + "tmm.cec.classifier.ssl.enable": "true", + "tmm.cec.classifier.ssl_training.enable": "false", + "tmm.cec.classifier.ssl_training.interval": "1", + "tmm.cec.classifier.ssl_training.log.stats": "false", + "tmm.cec.classifier.ssl_training.max_record": "15", + "tmm.cec.classifier.stun.enable": "true", + "tmm.cec.classifiers_override_bitmask": "0", + "tmm.cec.hitless_upgrade.timeout": "5", + "tmm.cec.log.level": "Warning", + "tmm.cec.max_packets": "10", + "tmm.cec.tables.bits": "19", + "tmm.cec.tables.evict.lru_after": "65535", + "tmm.classallocatemetadata": "enable", + "tmm.classmaxelementsreturned": "75000", + "tmm.classsweepsperfree": "150", + "tmm.connector.shutdownreturntimeout": "10", + "tmm.coredump": "enable", + "tmm.deflate.inflate.max.ratio": "1000", + "tmm.deflate.memory.threshold": "1572864", + "tmm.devel.max_memory_mb": "0", + "tmm.dhcp.client.connection.packets.inprogress.max": "10000", + "tmm.dhcp.dhcpv6.ttl_client_overwrite": "0", + "tmm.dhcp.log.level": "Error", + "tmm.dhcp.relay.change.src": "enable", + "tmm.dhcp.relay.giaddr.overwrite": "enable", + "tmm.dhcp.routedomain.strictisolate": "disable", + "tmm.dhcp.server.connection.packets.inprogress.max": "10000", + "tmm.diameter.application.enforce.capability.exchange.avps": "all", + "tmm.dns64.closewait": "5", + "tmm.dpi.log.level": "Warning", + "tmm.ffwd.enable": "true", + "tmm.fips140.posttries": "2", + "tmm.gpa.behavioranalysis": "true", + "tmm.gpa.cec.behavioral.ignore_low_ports": "false", + "tmm.gpa.cec.behavioral.min_class_npkt": "5", + "tmm.gpa.cec.behavioral.min_leaf_class_conf": "0", + "tmm.gpa.cec.behavioral.min_node_class_conf": "101", + "tmm.gpa.cec.behavioral.nodes_to_ignore": "NA", + "tmm.gpa.cec.behavioral_protocols": "35", + "tmm.gpa.cec.classifiers_to_use": "23", + "tmm.gpa.cec.classifiers_to_wait": "0", + "tmm.gpa.cec.enable": "true", + "tmm.gpa.cec.fast_rtmp_e.enabled": "false", + "tmm.gpa.cec.fast_rtmp_e.min_request_len": "1200", + "tmm.gpa.cec.flow_bundling.3tuples.dst.max_records": "500000", + "tmm.gpa.cec.flow_bundling.3tuples.src.max_records": "500000", + "tmm.gpa.cec.flow_bundling.3tuples.timeout": "60", + "tmm.gpa.cec.flow_bundling.enable": "true", + "tmm.gpa.cec.flow_bundling.l4.behavioral.counter_timeout": "60", + "tmm.gpa.cec.flow_bundling.l4.behavioral.enable": "true", + "tmm.gpa.cec.flow_bundling.l4.behavioral.reclass_freq": "10", + "tmm.gpa.cec.flow_bundling.l4.behavioral.rule_timeout": "300", + "tmm.gpa.cec.flow_bundling.l4.behavioral.threshold": "3", + "tmm.gpa.cec.flow_bundling.ssl_session_id.max_records": "500000", + "tmm.gpa.cec.flow_bundling.ssl_session_id.timeout": "18000", + "tmm.gpa.cec.log.detail": "Brief", + "tmm.gpa.cec.log.dict_dump_freq": "500", + "tmm.gpa.cec.log.flow_filter": "*", + "tmm.gpa.cec.log.hsl_level": "Warning", + "tmm.gpa.cec.log.hsl_pool": "/Common/hsl", + "tmm.gpa.cec.log.hsl_proto": "TCP", + "tmm.gpa.cec.log.ignore_level": "Warning", + "tmm.gpa.cec.log.module_exclude_mask": "0", + "tmm.gpa.cec.log.module_mask": "4294967295", + "tmm.gpa.classification.enable": "true", + "tmm.gpa.datagroup": "disable", + "tmm.gpa.ixe.enable": "true", + "tmm.gpa.log.level": "Warning", + "tmm.gpa.optimization": "true", + "tmm.gpa.signature_update.timeout": "600", + "tmm.gpa.srdb.defer_finalization": "false", + "tmm.gpa.ssl_training.log.publisher": "", + "tmm.gpa.statupdate": "16384", + "tmm.gpa.statupdate.hi": "512", + "tmm.gpa.statupdate.lo": "8", + "tmm.gpa.transactional": "true", + "tmm.gpa.urlcat": "true", + "tmm.gpa.urlcat.cloud.only": "false", + "tmm.gpa.urlcat.customdb.only": "false", + "tmm.gpa.urlcat.no.cloud": "false", + "tmm.gradualfileloadadjust": "enable", + "tmm.gradualfileloadspeed": "8", + "tmm.gtm.enforcepersistsync": "true", + "tmm.hsb.dataplanerebootaction": "enable", + "tmm.hsb.hgmfcsburst": "17", + "tmm.hsb.hgmfcsrebootaction": "enable", + "tmm.hsb.hgmfcsrebootthreshold": "10", + "tmm.hsb.hgmfcsthreshold": "10", + "tmm.hsb.hgmtxpausethreshold": "300", + "tmm.hsb.hwchecksumvalidation": "enable", + "tmm.hsb.loopbackvalidation": "enable", + "tmm.hsb.loopbackvalidationerrthreshold": "0", + "tmm.hsb.txpause": "enable", + "tmm.hsb.xlmachaaction": "11", + "tmm.http2.sendrstwhy": "false", + "tmm.http.cookie.decrypt.policy": "erase", + "tmm.http.oc.droponerror": "true", + "tmm.http.passthru.invalid_content_length": "disable", + "tmm.http.rfc_cookies": "enable", + "tmm.http.tcl.validation": "enable", + "tmm.http.uselastxff": "false", + "tmm.imap.max_partial_connbytes": "16384", + "tmm.imap.max_partial_conncount": "1024", + "tmm.imap.xbufdump": "0", + "tmm.inline_route_update": "disable", + "tmm.ipother.log.level": "Notice", + "tmm.ipv4.ttl.default": "255", + "tmm.ipv6.ttl.default": "64", + "tmm.lb.lcaccuracy": "100", + "tmm.lb.precisiondelay": "250", + "tmm.lb.precisionscale": "1000", + "tmm.lb.wlcoffset": "disable", + "tmm.lib.urlcat.log.level": "Warning", + "tmm.lognonsessionpackets": "disable", + "tmm.maxremoteloglength": "1024", + "tmm.mcp.disconnect.core": "false", + "tmm.mcp.replay.timeout": "60", + "tmm.mpifailsafe": "enable", + "tmm.nbr.queue": "4", + "tmm.ocspresponder.maxrequestbodysize": "1024", + "tmm.oops": "log", + "tmm.pcp.max_async_pending_requests": "10000", + "tmm.pem.actions.icap.limit": "8", + "tmm.pem.actions.lookup.optimize": "enable", + "tmm.pem.actions.redirect.parameter.name": "cordef_data", + "tmm.pem.actions.redirect.uri.size": "1024", + "tmm.pem.actions.reporting.fastl4.interval": "5", + "tmm.pem.actions.reporting.hsl.limit.cpu.threshold": "0", + "tmm.pem.actions.steering.response": "enable", + "tmm.pem.actions.steering.xhdr.name": "X-CORDEF-DATA", + "tmm.pem.auth.cache.time": "30", + "tmm.pem.avr.periodic.reporting": "60", + "tmm.pem.cppe.defmonitorinterval": "3000", + "tmm.pem.cppe.flowentriesprocessperrun": "20", + "tmm.pem.cppe.maxsessionstraversalrtt": "10", + "tmm.pem.cppe.sessionentriesprocessperrun": "200", + "tmm.pem.cppe.timeintervalreportonzerovolume": "false", + "tmm.pem.diameter.application.ignoreunsupportedmandatoryavps": "true", + "tmm.pem.diameter.application.resultcode.peertoobusy.maxretry": "3", + "tmm.pem.diameter.application.resultcode.peertoobusy.timeout": "0", + "tmm.pem.diameter.application.silentdelete.prov.error.sessions": "false", + "tmm.pem.diameter.application.trigger.delete.onpeer.failure": "true", + "tmm.pem.dtos.sampled.os.from": "User-Agent", + "tmm.pem.dtos.tcpf.sampling.interval": "10", + "tmm.pem.dtos.ua.sampling.interval": "10", + "tmm.pem.insert.deflate.memory.threshold": "1572864", + "tmm.pem.insert.inflate.max.ratio": "100", + "tmm.pem.insert.memory.threshold": "524288", + "tmm.pem.irule.action.error.abort": "disable", + "tmm.pem.log.level": "Critical", + "tmm.pem.persistence.timeout": "180", + "tmm.pem.policy.reevaluation.interval": "20", + "tmm.pem.radius.aaa.retransmission.backoff": "1", + "tmm.pem.rancon.auxbmval": "0", + "tmm.pem.rancon.flow.sample.interval": "1", + "tmm.pem.rancon.reporting.event_bitmask": "3", + "tmm.pem.rancon.sess.idle_timeout": "60", + "tmm.pem.rancon.sess.sample.interval": "2", + "tmm.pem.rancon.sess.state_debounce_count": "2", + "tmm.pem.rancon.towerid.con_threshold": "4", + "tmm.pem.rancon.towerid.enabled": "disable", + "tmm.pem.rancon.towerid.sample.interval": "4", + "tmm.pem.session.actions.apply.equalprecedence": "false", + "tmm.pem.session.actions.apply.onlylowprecedence": "false", + "tmm.pem.session.delete.if.max.ipaddr.per.class.exceeded": "enable", + "tmm.pem.session.dropped.flow.count": "disable", + "tmm.pem.session.endpointimmediatedelete": "true", + "tmm.pem.session.gx.reporting.disable.afterthreshold": "true", + "tmm.pem.session.gx.reporting.immediate": "false", + "tmm.pem.session.hashdepth": "17", + "tmm.pem.session.inactivitytimeout": "120", + "tmm.pem.session.ip.addr.max": "1", + "tmm.pem.session.ipv4.addr.max": "1", + "tmm.pem.session.ipv6.addr.max": "1", + "tmm.pem.session.ipv6.prefix.len": "128", + "tmm.pem.session.multiple.ip.stats.enabled": "enable", + "tmm.pem.session.policy.installunknown": "true", + "tmm.pem.session.ppe.recreate.afterpeerfailure": "false", + "tmm.pem.session.processing.time": "500", + "tmm.pem.session.provisioning.continuous": "enable", + "tmm.pem.session.quota.bucket.denied.timeout": "0", + "tmm.pem.session.quota.bucket.depleted.timeout": "0", + "tmm.pem.session.quota.bucket.idle.timeout": "0", + "tmm.pem.session.quota.bucket.notapplicable.timeout": "0", + "tmm.pem.session.quota.bucket.provpending.timeout": "2", + "tmm.pem.session.quota.gy.failurehandling": "terminate", + "tmm.pem.session.quota.notapplicableretrytimeout": "30", + "tmm.pem.session.quota.provision": "dynamic", + "tmm.pem.session.quota.provretrytimeout": "120", + "tmm.pem.session.quota.reject.ignore": "enable", + "tmm.pem.session.quota.tx.timeout": "5", + "tmm.pem.session.radius.provisioning.hold.time": "0", + "tmm.pem.session.radius.retransmit.timeout": "30", + "tmm.pem.session.timeout.endpointdeleteresponse": "3600", + "tmm.pem.session.timeout.finalusagerecord": "1200", + "tmm.pem.session.timeout.provpending": "600", + "tmm.pem.session.timeout.provretry": "1200", + "tmm.pem.session.usage.retry.interval": "120", + "tmm.pem.session.volume.stats.threshold": "10", + "tmm.pem.spm.maxsessionlimit": "524288", + "tmm.pem.srdb.enable": "true", + "tmm.pem.srdb.entry.highconfidence": "240", + "tmm.pem.srdb.entry.initialconfidence": "64", + "tmm.pem.srdb.entry.lowconfidence": "16", + "tmm.pem.srdb.entry.step": "32", + "tmm.pem.srdb.hashtable.hashbits": "10", + "tmm.pem.srdb.hashtable.maxflows": "32", + "tmm.pem.srdb.hashtable.maxprobes": "16", + "tmm.pem.ssp.init.delay": "30", + "tmm.pem.static.subscriber.ppe.lookup.enabled": "true", + "tmm.pem.td.bandwidth.wt": "0", + "tmm.pem.td.detected.off.threshold": "40", + "tmm.pem.td.detected.on.threshold": "45", + "tmm.pem.td.expected.bandwidth": "0", + "tmm.pem.td.expected.num.conn": "0", + "tmm.pem.td.num.conn.wt": "0", + "tmm.pem.td.sample.interval": "180", + "tmm.pem.td.tcpf.os.wt": "0", + "tmm.pem.td.ttl.wt": "20", + "tmm.pem.td.ua.os.wt": "0", + "tmm.pkcs11d.invalidatekeyhandle": "0", + "tmm.pkcs11d.loadkeyhandles": "0", + "tmm.pkcs11d.shmid": "0", + "tmm.policy.tracelevel": "0", + "tmm.pop3.max_partial_connbytes": "16384", + "tmm.pop3.max_partial_conncount": "1024", + "tmm.protocol_inspection.attribute.abort_udp_flow_on_drop_action": "false", + "tmm.protocol_inspection.attribute.sip_call_logs": "false", + "tmm.protocol_inspection.attribute.sip_call_stat_entries": "1000", + "tmm.protocol_inspection.insp.ids.maxcount": "10", + "tmm.protocol_inspection.learning.learning_interval": "10080", + "tmm.protocol_inspection.learning.suggestion_interval": "720", + "tmm.protocol_inspection.log.level": "Warning", + "tmm.protocol_inspection.log.per_flow.maxcount": "10", + "tmm.proxyssl.bucketcount": "1023", + "tmm.proxyssl.cachesize": "2621440", + "tmm.quic.log.level": "Critical", + "tmm.resolv.cachesize": "8192", + "tmm.resolv.retry": "3", + "tmm.resolv.timeout": "5", + "tmm.returnmemory": "disable", + "tmm.reuse.ss.timewaitconns": "enable", + "tmm.sctp.program_forwarding_flows": "enable", + "tmm.sctp.redirect_packets": "enable", + "tmm.sessiondb.binlimit.asm.sessiondp": "300000", + "tmm.sessiondb.binlimit.asm.sessionsw": "500000", + "tmm.sessiondb.binlimit.fps.user": "300000", + "tmm.sessiondb.ha_mps_limit": "0", + "tmm.sessiondb.match_ha_unit": "true", + "tmm.sessiondb.table_cmd_timeout_override": "false", + "tmm.smtps.max_partial_connbytes": "16384", + "tmm.smtps.max_partial_conncount": "1024", + "tmm.sp.sip.allowtcpudpconversion": "disable", + "tmm.ssl.alwaysstaple": "disable", + "tmm.ssl.cachesize": "262144", + "tmm.ssl.certlifespaninhours": "disable", + "tmm.ssl.closerevoked": "disable", + "tmm.ssl.cn.shunt": "enable", + "tmm.ssl.corruptcertenabled": "true", + "tmm.ssl.defaultlistenerstatrow": "disable", + "tmm.ssl.dh1024": "disable", + "tmm.ssl.dtlsantrplwinsize": "64", + "tmm.ssl.dtlsmaxcrs": "1", + "tmm.ssl.dtlsqueuesize": "127", + "tmm.ssl.dtlsrxhsrec": "70", + "tmm.ssl.extmsenabled": "true", + "tmm.ssl.loggingcreatedcerts": "disable", + "tmm.ssl.maxactivehandshakes": "0", + "tmm.ssl.maxaggregaterenegotiationperminute": "0", + "tmm.ssl.maxhandshakesize": "32768", + "tmm.ssl.servercert_softval": "disable", + "tmm.ssl.useffdhe": "true", + "tmm.ssl.v2compatibility": "disable", + "tmm.sslsni.bucketcount": "64", + "tmm.sslsnicert.bucketcount": "64", + "tmm.switchboard.rxbusy": "disable", + "tmm.tcl.executionlimit": "500", + "tmm.tcl.rule.aborted.log.ratio": "1", + "tmm.tcl.rule.connect.allow_loopback_addresses": "false", + "tmm.tcl.rule.node.allow_loopback_addresses": "false", + "tmm.tcpdump.pkt.ratelimit": "0", + "tmm.threads": "0", + "tmm.threadsactual": "0", + "tmm.timer.maxusecperpoll": "250", + "tmm.umem.debug_buftag": "disable", + "tmm.umem.debug_depth": "5", + "tmm.umem.trace": "disable", + "tmm.umem.trace_log": "none", + "tmm.umem_largeslab_threshold": "33", + "tmm.umem_reap_aggress": "3", + "tmm.umem_reap_aggrlevel": "80", + "tmm.urlcat.cloud.cache.maxsize": "131072", + "tmm.urlcat.cloud.cache.reset": "", + "tmm.urlcat.cloud.no.ipv4": "false", + "tmm.urlcat.log.level": "Warning", + "tmm.urlcat.no_db_limit": "false", + "tmm.urldb.no.ip": "disable", + "tmm.validate": "disable", + "tmm.verbose": "disable", + "tmm.verbosecmp": "disable", + "tmm.verbosemcperr": "true", + "tmm.verbosemcpmessages": "disable", + "tmm.vlantxfilter": "enable", + "tmm.websocket.deflate.memory.threshold": "1572864", + "tmm.websocket.inflate.max.ratio": "1000", + "tmm.wlite": "enable", + "tmm.wlite.pinning": "disable", + "tmplugin.scheduler": "poll", + "tmplugin.splitplanes.nice": "0", + "tmrouted.gracefulrestartdelay": "5", + "tmrouted.hareconnectfecretries": "0", + "tmrouted.netlinkcmdidletimeout": "5", + "tmrouted.netlinklistenidletimeout": "5", + "tmrouted.rhifailoverdelay": "0", + "tmrouted.tmos.routing": "disable", + "tmrouted.tmos.routing.status": "none", + "tmui.audit.max.lines": "10000", + "tmui.system.setup.network.canconfigureexternal": "true", + "tmui.system.setup.network.canconfigureha": "true", + "tmui.system.setup.network.canconfigureinternal": "true", + "tmui.system.setup.network.canconfiguretrust": "true", + "tmui.system.setup.network.configsync.choice": "true", + "tmui.system.setup.network.failover.choice": "true", + "tmui.system.setup.network.failover.method.choice": "true", + "tmui.system.setup.network.vlan.external": "external", + "tmui.system.setup.network.vlan.ha": "HA", + "tmui.system.setup.network.vlan.internal": "internal", + "total.sandbox.size": "512", + "trunk.cluster.distribution": "optimized", + "trunk.cluster.dlfflushpkts": "100000", + "trunk.cluster.dlfflushpoll": "2000000", + "trunk.internal.distribution": "srcdestip", + "trunk.internal.ffp": "enable", + "trust.adddevicemaxpolltimeout": "300", + "trust.configupdatedone": "false", + "trust.icontrolport": "443", + "trust.suspendtime": "3", + "tsconfd.loglevel": "none", + "ucs.asm.traffic_data.load": "matching", + "ucs.asm.traffic_data.save": "enable", + "ucs.loadtime": "0", + "ucs.platformcheck": "true", + "ucs.resettrust": "false", + "udp.hash": "port", + "ui.advancedsearch": "false", + "ui.advisory.color": "green", + "ui.advisory.enabled": "false", + "ui.advisory.text": "This is a system advisory message.", + "ui.is24hour": "false", + "ui.logaccess.accelerationpolicyeditor": "disable", + "ui.logaccess.applicationeditor": "disable", + "ui.logaccess.applicationsecurityadmin": "disable", + "ui.logaccess.applicationsecurityeditor": "disable", + "ui.logaccess.applicationsecurityoperationsadministrator": "disable", + "ui.logaccess.certificatemanager": "disable", + "ui.logaccess.firewallmanager": "disable", + "ui.logaccess.fraudprotectionmanager": "disable", + "ui.logaccess.guest": "disable", + "ui.logaccess.irulemanager": "disable", + "ui.logaccess.manager": "disable", + "ui.logaccess.operator": "disable", + "ui.logaccess.usermanager": "disable", + "ui.statistics.modulestatistics.dnsdelivery.persistencerecords": "false", + "ui.statistics.modulestatistics.dnsgslb.persistencerecords": "false", + "ui.statistics.modulestatistics.localtraffic.persistencerecords": "false", + "ui.system.preferences.advancedselection": "basic", + "ui.system.preferences.displayhostnameswhenpossible": "false", + "ui.system.preferences.recordsperscreen": "10", + "ui.system.preferences.screenrefreshinterval": "-1", + "ui.system.preferences.startscreen": "welcome", + "ui.system.preferences.statisticsformat": "normalized", + "ui.users.redirectsuperuserstoauthsummary": "false", + "ui.wom.quickstart": "false", + "unix.config.ntp.replace.clusterhosts": "", + "upgradeselector.package": "upgrade-selector", + "upgradeselector.url": "ftp://update.f5.com/", + "urldb.masterdb.index.building": "false", + "urldb.rtsudb.index.building": "false", + "user.acceptedeula": "none", + "users.defaultpartition": "[All]", + "users.defaultrole": "900", + "users.remoteconsoleaccess": "disable", + "users.strictpasswords": "enable", + "vcmp.concurrent_vdisk_accesses": "1", + "vcmp.dynamic_rsync_conn_allowed": "false", + "vcmp.guest.console": "telnet", + "vcmp.guest.console.logging": "disable", + "vcmp.guest.console.timeout": "0", + "vcmp.guest.deprecate_legacy_vlans": "false", + "vcmp.guest.failsafe": "disable", + "vcmp.guest.tmstat.tables.allowed": "default", + "vcmp.installer.use_vdisk_templates": "default", + "vcmp.mgmt.allow_host_guest_communication": "true", + "vcmp.mgmt.allow_tagged_traffic": "false", + "vcmp.mgmt.allow_vlan_1_tagged_traffic": "false", + "vcmp.mgmt.enable_hnet": "true", + "vcmp.mgmt.guest_source_ip_checks": "true", + "vcmp.mgmt.guest_source_mac_checks": "true", + "vcmp.scheduler.allow_splitplanes": "true", + "vcmp.scheduler.hrtimer": "false", + "vcmp.scheduler.nice_usecs": "120", + "vcmp.scheduler.rt_usecs": "880", + "vcmp.timeout.installing": "1000", + "vcmp.timeout.migrating": "2700", + "vcmp.timeout.starting": "900", + "vcmp.timeout.stopping": "180", + "vcmp.timeout.watchdog": "20", + "vcmp.vdisk.new_image_size": "150", + "vcmp.vdisk.size.estimate": "10", + "vcmpd.fake_qemu": "disable", + "vcmpd.fake_qemu.args": "", + "ve.ndal.exit_on_ue": "false", + "ve.ndal.pkt_trace": "false", + "ve.scheduler.splitplanes": "false", + "vendor.knowledgebase.a": "", + "vendor.knowledgebase.a.href": "", + "vendor.licservguiuri": "", + "vendor.licservhost": "", + "vendor.licservprotocol": "", + "vendor.licservuri": "", + "vendor.supportemail": "", + "vendor.vendorcommonname": "", + "vendor.vendorfullname": "", + "vendor.wwwurl": "", + "version.basebuild": "", + "version.build": "", + "version.built": "", + "version.changelist": "", + "version.date": "", + "version.edition": "", + "version.fipsmodule": "F5 Device Cryptographic Module", + "version.jobid": "", + "version.product": "", + "version.sequence": "", + "version.version": "", + "vlan.backplane.id": "4095", + "vlan.backplane.mtu": "4096", + "vlan.fdb.timeout": "300", + "vlan.macassignment": "unique", + "vlan.stpassignment": "auto", + "vlangroup.flow.allocate": "enable", + "vlangroup.forwarding.override": "enable", + "vpn.buffervolumekb": "64", + "vpn.logstats": "disable", + "vpn.packetdropperiod": "5", + "vpn.pertunnelstats.sid": "", + "vpn.serveriplist": "", + "wam.cache.disk.status": "active", + "wam.cache.entities.dump": "0", + "wam.cache.entities.dump.rate": "1000", + "wam.cache.entities.dump.regex": ".", + "wam.cache.range.maxranges": "8", + "wam.cache.requestqueue.maxqueuelen": "0", + "wam.cache.requestqueue.maxwait": "180000", + "wam.cache.smallobject.threshold": "-1", + "wam.maxdomainlistsize": "30", + "wam.use.also.if.none.match": "disable", + "watchdog.state": "enable", + "wccp.loglevel": "1", + "webserver.cert.0.organizationname": "My Company", + "webserver.cert.countryname": "US", + "webserver.cert.localityname": "Seattle", + "webserver.cert.organizationalunitname": "_undef_", + "webserver.cert.stateorprovincename": "WA", + "webserver.prefix": "http", + "woc.remembered.data.encyption": "false", + "woc.remembered.lan.vlans": "", + "woc.remembered.wan.vlans": "", + "wocd.control.timeout": "10", + "wocd.log.level": "info", + "wocplugin.cifs.bdp": "300", + "wocplugin.cifs.loglevel": "1", + "wocplugin.cifs.lowbdpcutoff": "30", + "wocplugin.cifs.minreadsize": "0", + "wocplugin.loglevel": "1", + "wocplugin.mapi.loglevel": "1", + "wom.discovered.autosave": "true", + "wr_urldbd.cloud_cache.limit": "5500000", + "wr_urldbd.cloud_cache.log.level": "none", + "zxfrd.dbloadstamp": "0", + "zxfrd.dependency.named": "true", +} + +type DBVariable struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` +} + +// GetDBVariable returns a named DB variable. +func (b *BigIP) GetDBVariable(name string) (*DBVariable, error) { + var dbVar DBVariable + err, ok := b.getForEntity(&dbVar, uriSys, uriDb, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &dbVar, nil +} + +// CreateDBVariable doesn't really create new configuration element +// Function will update old value with the existing value +func (b *BigIP) CreateDBVariable(config *DBVariable) error { + return b.patch(config, uriSys, uriDb, config.Name) +} + +// DeleteDBVariable resets a DB variable to its default value. +// DELETE method is not supported for database variables - this function +// instead updates the value to the default value from DefaultDBValues map. +func (b *BigIP) DeleteDBVariable(name string) error { + val, ok := DefaultDBValues[name] + if !ok { + return fmt.Errorf("default value not found for DB variable '%s'. This variable may not be supported or may not have a default value defined", name) + } + + stringVal, ok := val.(string) + if !ok { + return fmt.Errorf("default value for DB variable '%s' is not a string (got type %T)", name, val) + } + + config := &DBVariable{ + Value: stringVal, + } + return b.patch(config, uriSys, uriDb, name) +} + +// ModifyDBVariable allows the change of DB variable value +func (b *BigIP) ModifyDBVariable(config *DBVariable) error { + return b.patch(config, uriSys, uriDb, config.Name) +} diff --git a/examples/db_vars/main.go b/examples/db_vars/main.go new file mode 100644 index 0000000..4bc62d1 --- /dev/null +++ b/examples/db_vars/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "os" + + "github.com/f5devcentral/go-bigip" +) + +func main() { + // Connect to the BIG-IP system. + // Replace with your actual BIG-IP credentials and hostname + config := &bigip.Config{ + //Address: "https://192.168.1.1", + Username: "admin", + //Password: "admin", + CertVerifyDisable: true, // Disable certificate verification for testing purposes + } + + config.Address = os.Getenv("BIGIP_ADDRESS") + if config.Address != "" { + fmt.Println("BIGIP_ADDRESS:", config.Address) + } else { + fmt.Println("BIGIP_ADDRESS is not set.") + } + + config.Password = os.Getenv("BIGIP_PASSWORD") + if config.Password != "" { + fmt.Println("BIGIP_PASSWORD:", config.Password) + } else { + fmt.Println("BIGIP_PASSWORD is not set.") + } + + f5 := bigip.NewSession(config) + + testDBVariableRead(f5) + testDBVariableCreation(f5) + testDBVariableUpdate(f5) + testDBVariableDelete(f5) + +} diff --git a/examples/db_vars/test_db_var.go b/examples/db_vars/test_db_var.go new file mode 100644 index 0000000..4da03df --- /dev/null +++ b/examples/db_vars/test_db_var.go @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Database Variable Testing ////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testDBVariableRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing System DB Variable Read Operation ===") + + // Test DB variable configuration + dbVar, err := f5.GetDBVariable("ui.advisory.enabled") + if err != nil { + log.Printf("Error getting Database Variable: %v", err) + return + } + if dbVar != nil { + fmt.Printf("Retrieved Database Variable:\n") + fmt.Printf(" Name: %s\n", dbVar.Name) + fmt.Printf(" Value: %s\n", dbVar.Value) + } +} + +func testDBVariableCreation(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing System DB Variable Creation Operation ===") + + // Test DB variable configuration + dbVar := &bigip.DBVariable{ + Name: "ui.advisory.enabled", + Value: "true", + } + + // CREATE: Set DB Variable value + fmt.Println("Setting System DB Variable...") + err := f5.CreateDBVariable(dbVar) + if err != nil { + log.Printf("Error creating DB Variable: %v", err) + return + } + fmt.Printf("DB Variable ui.advisory.enabled changed successfully.\n") + +} + +func testDBVariableUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing System DB Variable Modify Operation ===") + + // Test DB variable configuration + dbVar := &bigip.DBVariable{ + Name: "ui.advisory.color", + Value: "orange", + } + + // CREATE: Set DB Variable value + fmt.Println("Modifying System DB Variable...") + err := f5.ModifyDBVariable(dbVar) + if err != nil { + log.Printf("Error modifying DB Variable: %v", err) + return + } + fmt.Printf("DB Variable ui.advisory.color changed successfully.\n") + +} + +func testDBVariableDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing DB Variable Removal/Reset-To-Defaults Operation ===") + // Test DB variable configuration + dbVar := &bigip.DBVariable{ + Name: "ui.advisory.enabled", + } + // DELETE: Reset DB Variable to default + fmt.Println("Resetting DB Variable to default...") + err := f5.DeleteDBVariable(dbVar.Name) + if err != nil { + log.Printf("Error resetting DB Variable to defaults: %v", err) + return + } + fmt.Printf("DB Variable %s was set back to default value '%v' successfully.\n", dbVar.Name, bigip.DefaultDBValues[dbVar.Name]) + +} From 58786616f8f2b890ae9cbcd70e6850d4344d0acf Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Thu, 11 Dec 2025 17:14:55 +0100 Subject: [PATCH 03/25] Implementing Mgmt Route Support --- examples/sys/main.go | 47 +++++++++++++++++ examples/sys/test_mgmt_route.go | 93 +++++++++++++++++++++++++++++++++ sys.go | 65 +++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 examples/sys/main.go create mode 100644 examples/sys/test_mgmt_route.go diff --git a/examples/sys/main.go b/examples/sys/main.go new file mode 100644 index 0000000..8cb25c8 --- /dev/null +++ b/examples/sys/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "os" + + "github.com/f5devcentral/go-bigip" +) + +func main() { + // Connect to the BIG-IP system. + // Replace with your actual BIG-IP credentials and hostname + config := &bigip.Config{ + //Address: "https://192.168.1.1", + Username: "admin", + //Password: "admin", + CertVerifyDisable: true, // Disable certificate verification for testing purposes + } + + config.Address = os.Getenv("BIGIP_ADDRESS") + if config.Address != "" { + fmt.Println("BIGIP_ADDRESS:", config.Address) + } else { + fmt.Println("BIGIP_ADDRESS is not set.") + } + + config.Password = os.Getenv("BIGIP_PASSWORD") + if config.Password != "" { + fmt.Println("BIGIP_PASSWORD:", config.Password) + } else { + fmt.Println("BIGIP_PASSWORD is not set.") + } + + f5 := bigip.NewSession(config) + + mgmtRouteTesting := false + + if mgmtRouteTesting { + testManagementRouteCreation(f5) + testManagementRouteRead(f5) + testManagementRouteUpdate(f5) + testManagementRouteRead(f5) + testManagementRouteDelete(f5) + testManagementRouteRead(f5) + } + +} diff --git a/examples/sys/test_mgmt_route.go b/examples/sys/test_mgmt_route.go new file mode 100644 index 0000000..d61fcca --- /dev/null +++ b/examples/sys/test_mgmt_route.go @@ -0,0 +1,93 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +//////////////////////////////////////////////////////////////////////// +////////////// Management Route Testing ////////////// +//////////////////////////////////////////////////////////////////////// + +func testManagementRouteRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management Route Read Operation ===") + + fmt.Println("Getting all Management Routes...") + mgmtroutes, err := f5.GetManagementRoutes() + if err != nil { + log.Printf("Error getting Management Routes: %v", err) + return + } + fmt.Printf("Found %d Management Routes\n", len(mgmtroutes.ManagementRoutes)) + + fmt.Println("Getting specific Management Route...") + for i := 0; i < len(mgmtroutes.ManagementRoutes); i++ { + mgmtroute, err := f5.GetManagementRoute(mgmtroutes.ManagementRoutes[i].Name) + if err != nil { + log.Printf("Error getting Management Route: %v", err) + return + } + if mgmtroute != nil { + fmt.Printf("Retrieved Management Route:\n%s - %s via %s (MTU: %d)\n", mgmtroute.Name, mgmtroute.Network, mgmtroute.Gateway, mgmtroute.MTU) + } + } + +} + +func testManagementRouteCreation(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management Route Creation Operation ===") + + mgmtRoute := &bigip.ManagementRoute{ + Name: "/Common/test-route", + Gateway: "10.171.125.61", + //MTU: 1500, + Network: "32.50.33.0/24", + } + + fmt.Println("Creating Management Route...") + err := f5.CreateManagementRoute(mgmtRoute) + if err != nil { + log.Printf("Error creating Management Route: %v", err) + return + } + fmt.Printf("Management Route %s created successfully.\n", mgmtRoute.Name) + +} + +func testManagementRouteUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management Route Update Operation ===") + + mgmtRoute := &bigip.ManagementRoute{ + Name: "/Common/test-route", + Gateway: "10.171.125.45", + //MTU: 1500, + Network: "32.50.33.0/24", + } + + fmt.Println("Updating Management Route...") + err := f5.ModifyManagementRoute(mgmtRoute.Name, mgmtRoute) + if err != nil { + log.Printf("Error updating Management Route: %v", err) + return + } + fmt.Printf("Management Route %s updated successfully.\n", mgmtRoute.Name) + +} + +func testManagementRouteDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management Route Delete Operation ===") + + mgmtRoute := &bigip.ManagementRoute{ + Name: "/Common/test-route", + } + + fmt.Println("Deleting Management Route...") + err := f5.DeleteManagementRoute(mgmtRoute.Name) + if err != nil { + log.Printf("Error deleting Management Route: %v", err) + return + } + fmt.Printf("Management Route %s deleted successfully.\n", mgmtRoute.Name) +} diff --git a/sys.go b/sys.go index f534c40..ae70c0b 100644 --- a/sys.go +++ b/sys.go @@ -283,6 +283,7 @@ func (p *LogPublisher) UnmarshalJSON(b []byte) error { } const ( + uriMgmtRoute = "management-route" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1251,3 +1252,67 @@ func (b *BigIP) ModifyRoleInfo(name string, roleInfo *RoleInfo) error { func (b *BigIP) DeleteRoleInfo(name string) error { return b.delete(uriAuth, uriRemoteRole, uriRoleInfo, name) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Management Route ///////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// ManagementRoutes represents a collection of BIG-IP management routes. +type ManagementRoutes struct { + ManagementRoutes []ManagementRoute `json:"items"` +} + +// ManagementRoute represents a BIG-IP management route configuration. +type ManagementRoute struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + Gateway string `json:"gateway,omitempty"` + MTU int `json:"mtu,omitempty"` + Network string `json:"network,omitempty"` + Description string `json:"description,omitempty"` +} + +// GetManagementRoutes returns a list of management routes. +func (b *BigIP) GetManagementRoutes() (*ManagementRoutes, error) { + var mgmtroute ManagementRoutes + err, ok := b.getForEntity(&mgmtroute, uriSys, uriMgmtRoute) + if err != nil { + if !ok { + return &ManagementRoutes{}, nil + } + return nil, err + } + + return &mgmtroute, nil +} + +// GetManagementRoute returns a named Management Route. +func (b *BigIP) GetManagementRoute(managementroute string) (*ManagementRoute, error) { + var mgmtroute ManagementRoute + err, ok := b.getForEntity(&mgmtroute, uriSys, uriMgmtRoute, managementroute) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &mgmtroute, nil +} + +// CreateManagementRoute adds a new management route to the BIG-IP system. must include the +// subnet mask in CIDR notation, i.e.: "10.1.1.0/24". +func (b *BigIP) CreateManagementRoute(config *ManagementRoute) error { + return b.post(config, uriSys, uriMgmtRoute) +} + +// DeleteManagementRoute removes a management route. +func (b *BigIP) DeleteManagementRoute(name string) error { + return b.delete(uriSys, uriMgmtRoute, name) +} + +// ModifyManagementRoute allows for a change of any attribute of a management route. Fields that +// can be modified are referenced in the ManagementRoute struct. +func (b *BigIP) ModifyManagementRoute(name string, config *ManagementRoute) error { + return b.put(config, uriSys, uriMgmtRoute, name) +} From a638f45291ab401710bb469e031c839a0a04d23e Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 12 Dec 2025 14:00:26 +0100 Subject: [PATCH 04/25] Implement Mgmt Firewall Rules support --- examples/sys/main.go | 11 +++ examples/sys/test_mgmt_fw_rule.go | 119 ++++++++++++++++++++++++++++++ go.mod | 2 +- sys.go | 115 +++++++++++++++++++++++++++++ 4 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_mgmt_fw_rule.go diff --git a/examples/sys/main.go b/examples/sys/main.go index 8cb25c8..b344398 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -34,6 +34,7 @@ func main() { f5 := bigip.NewSession(config) mgmtRouteTesting := false + mgmtFwRuleTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -44,4 +45,14 @@ func main() { testManagementRouteRead(f5) } + if mgmtFwRuleTesting { + testManagementFwRulesRead(f5) + testManagementFwRuleCreation(f5) + testManagementFwRulesRead(f5) + testManagementFwRuleModify(f5) + testManagementFwRulesRead(f5) + testManagementFwRuleDelete(f5) + testManagementFwRulesRead(f5) + } + } diff --git a/examples/sys/test_mgmt_fw_rule.go b/examples/sys/test_mgmt_fw_rule.go new file mode 100644 index 0000000..cb53ccf --- /dev/null +++ b/examples/sys/test_mgmt_fw_rule.go @@ -0,0 +1,119 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Management Firewall Rules Testing ////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testManagementFwRulesRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management Firewall Rule Read Operation ===") + + fmt.Println("Getting all Management Firewall Rules...") + mgmtiprules, err := f5.GetManagementFwRules() + if err != nil { + log.Printf("Error getting Management Firewall Rules: %v", err) + return + } + fmt.Printf("Found %d Management Firewall Rules\n", len(mgmtiprules.MgmtFirewallRules)) + + fmt.Println("Getting specific Management Firewall Rule...") + for i := 0; i < len(mgmtiprules.MgmtFirewallRules); i++ { + mgmtiprule, err := f5.GetManagementFwRule(mgmtiprules.MgmtFirewallRules[i].Name) + if err != nil { + log.Printf("Error getting Management Firewall Rule: %v", err) + return + } + if mgmtiprule != nil { + fmt.Printf("Retrieved Management Firewall Rule:\n%s - %s via %v\n", mgmtiprule.Name, mgmtiprule.Action, mgmtiprule.Destination) + } + } +} + +func testManagementFwRuleCreation(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management Firewall Rule Creation Operation ===") + + mgmtFwRule := &bigip.MgmtFirewallRule{ + Name: "test-rule", + IpProtocol: "tcp", + Action: "accept", + Log: "no", + Status: "enabled", + PlaceBefore: "first", + Destination: bigip.MgmtFwRuleIpPortData{ + Addresses: []bigip.MgmtFwRuleAddress{ + {Name: "30.40.40.0/24"}, + {Name: "30.40.50.0/24"}, + }, + Ports: []bigip.MgmtFwRulePort{ + {Name: "555"}, + }, + }, + Source: bigip.MgmtFwRuleIpPortData{ + Addresses: []bigip.MgmtFwRuleAddress{ + {Name: "10.30.40.0/24"}, + {Name: "20.30.50.0/24"}, + }, + Ports: []bigip.MgmtFwRulePort{ + {Name: "8080"}, + {Name: "4443"}, + }, + }, + } + + fmt.Println("Creating Management Firewall Rule...") + err := f5.CreateManagementFwRule(mgmtFwRule) + if err != nil { + log.Printf("Error creating Management Firewall Rule: %v", err) + return + } + fmt.Printf("Management Firewall Rule %s created successfully.\n", mgmtFwRule.Name) +} + +func testManagementFwRuleModify(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management Firewall Rule Modify Operation ===") + + mgmtFwRule := &bigip.MgmtFirewallRule{ + Name: "test-rule", + IpProtocol: "tcp", + Schedule: "/Common/ssh_schedule", + Status: "scheduled", + Destination: bigip.MgmtFwRuleIpPortData{ + Addresses: []bigip.MgmtFwRuleAddress{ + {Name: "30.30.70.0/24"}, + {Name: "30.30.80.0/24"}, + }, + Ports: []bigip.MgmtFwRulePort{}, + }, + } + + fmt.Println("Updating Management Firewall Rule...") + err := f5.ModifyManagementFwRule(mgmtFwRule.Name, mgmtFwRule) + if err != nil { + log.Printf("Error updating Management Firewall Rule: %v", err) + return + } + fmt.Printf("Management Firewall Rule %s updated successfully.\n", mgmtFwRule.Name) +} + +func testManagementFwRuleDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Management IP Rules Delete Operation ===") + + mgmtfwRule := &bigip.MgmtFirewallRule{ + Name: "test-rule", + } + + fmt.Println("Deleting Management Firewall Rule...") + err := f5.DeleteManagementFwRule(mgmtfwRule.Name) + if err != nil { + log.Printf("Error deleting Management Firewall Rule: %v", err) + return + } + fmt.Printf("Management Firewall Rule %s deleted successfully.\n", mgmtfwRule.Name) + +} diff --git a/go.mod b/go.mod index 508d569..1ac455a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/f5devcentral/go-bigip -go 1.20 +go 1.24 require github.com/stretchr/testify v1.2.1 diff --git a/sys.go b/sys.go index ae70c0b..f6b4f46 100644 --- a/sys.go +++ b/sys.go @@ -12,6 +12,7 @@ package bigip import ( "encoding/json" + "errors" "fmt" "log" "os" @@ -284,6 +285,8 @@ func (p *LogPublisher) UnmarshalJSON(b []byte) error { const ( uriMgmtRoute = "management-route" + uriMgmtIpRules = "management-ip-rules" + uriRules = "rules" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1316,3 +1319,115 @@ func (b *BigIP) DeleteManagementRoute(name string) error { func (b *BigIP) ModifyManagementRoute(name string, config *ManagementRoute) error { return b.put(config, uriSys, uriMgmtRoute, name) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Management Firewall Rule ///////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// MgmtFirewallRules represents a collection of BIG-IP management firewall rules. +type MgmtFirewallRules struct { + MgmtFirewallRules []MgmtFirewallRule `json:"items"` +} + +// MgmtFwRuleAddress represents an IP address or address range for firewall matching. +type MgmtFwRuleAddress struct { + Name string `json:"name,omitempty"` +} + +// MgmtFwRulePort represents a port or port range for firewall matching. +type MgmtFwRulePort struct { + Name string `json:"name,omitempty"` +} + +// MgmtFwRuleICMP represents an ICMP type and code specification for firewall rules. +// Format is "type:code" (e.g., "3:1" for destination unreachable / host unreachable). +type MgmtFwRuleICMP struct { + Name string `json:"name,omitempty"` +} + +// MgmtFwRuleIpPortData contains source or destination IP and port matching criteria for firewall rules. +type MgmtFwRuleIpPortData struct { + AddressLists []string `json:"addressLists,omitempty"` + Addresses []MgmtFwRuleAddress `json:"addresses,omitzero"` + PortLists []string `json:"portLists,omitempty"` + Ports []MgmtFwRulePort `json:"ports,omitzero"` +} + +// MgmtFirewallRule represents a BIG-IP management firewall rule configuration. +// These rules control access to the management interface. +type MgmtFirewallRule struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + Description string `json:"description,omitempty"` + UUID string `json:"uuid,omitempty"` + Action string `json:"action,omitempty" validate:"oneof=accept drop reject"` + IpProtocol string `json:"ipProtocol,omitempty"` + Log string `json:"log,omitempty" validate:"oneof=yes no"` + PlaceAfter string `json:"placeAfter,omitempty"` + PlaceBefore string `json:"placeBefore,omitempty"` + Status string `json:"status,omitempty"` + Schedule string `json:"schedule,omitempty"` + Destination MgmtFwRuleIpPortData `json:"destination,omitempty"` + Source MgmtFwRuleIpPortData `json:"source,omitempty"` + ICMPs []MgmtFwRuleICMP `json:"icmp,omitzero"` +} + +func validateMgmtRulePlacing(config *MgmtFirewallRule) error { + hasAfter := config.PlaceAfter != "" + hasBefore := config.PlaceBefore != "" + + if hasAfter && hasBefore { + return errors.New("cannot set both 'PlaceAfter' and 'PlaceBefore', choose one") + } + if !hasAfter && !hasBefore { + return errors.New("must set either 'PlaceAfter' or 'PlaceBefore' for rule placement") + } + return nil +} + +// GetManagementFwRules returns a list of management firewall rules. +func (b *BigIP) GetManagementFwRules() (*MgmtFirewallRules, error) { + var mgmtfwrules MgmtFirewallRules + err, ok := b.getForEntity(&mgmtfwrules, uriSecurity, uriFirewall, uriMgmtIpRules, uriRules) + if err != nil { + if !ok { + return &MgmtFirewallRules{}, nil + } + return nil, err + } + + return &mgmtfwrules, nil +} + +// GetManagementFwRule returns a named Management Firewall Rule. +func (b *BigIP) GetManagementFwRule(name string) (*MgmtFirewallRule, error) { + var mgmtfwrule MgmtFirewallRule + err, ok := b.getForEntity(&mgmtfwrule, uriSecurity, uriFirewall, uriMgmtIpRules, uriRules, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &mgmtfwrule, nil +} + +// CreateManagementFwRule adds a new management firewall rule to the BIG-IP system. +func (b *BigIP) CreateManagementFwRule(config *MgmtFirewallRule) error { + err := validateMgmtRulePlacing(config) + if err != nil { + return err + } + return b.post(config, uriSecurity, uriFirewall, uriMgmtIpRules, uriRules) +} + +// ModifyManagementFwRule allows you to change any attribute of a management firewall rule. +func (b *BigIP) ModifyManagementFwRule(name string, config *MgmtFirewallRule) error { + return b.put(config, uriSecurity, uriFirewall, uriMgmtIpRules, uriRules, name) +} + +// DeleteManagementFwRule removes a management firewall rule. +func (b *BigIP) DeleteManagementFwRule(name string) error { + return b.delete(uriSecurity, uriFirewall, uriMgmtIpRules, uriRules, name) +} From f0d524120170b8c3fd3e29f797322bac59231d2c Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 12 Dec 2025 16:26:27 +0100 Subject: [PATCH 05/25] Implement Sys Auth Remote Roles support --- examples/sys/main.go | 12 +++- examples/sys/test_remote_roles.go | 103 ++++++++++++++++++++++++++++++ sys.go | 80 +++++++++++++++++++++++ 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_remote_roles.go diff --git a/examples/sys/main.go b/examples/sys/main.go index b344398..842c121 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -34,7 +34,8 @@ func main() { f5 := bigip.NewSession(config) mgmtRouteTesting := false - mgmtFwRuleTesting := true + mgmtFwRuleTesting := false + remoteRoleTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -54,5 +55,14 @@ func main() { testManagementFwRuleDelete(f5) testManagementFwRulesRead(f5) } + if remoteRoleTesting { + testRemoteRoleRead(f5) + testRemoteRoleCreation(f5) + testRemoteRoleRead(f5) + testRemoteRoleUpdate(f5) + testRemoteRoleRead(f5) + testRemoteRoleDelete(f5) + testRemoteRoleRead(f5) + } } diff --git a/examples/sys/test_remote_roles.go b/examples/sys/test_remote_roles.go new file mode 100644 index 0000000..7da7e14 --- /dev/null +++ b/examples/sys/test_remote_roles.go @@ -0,0 +1,103 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Remote Role Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testRemoteRoleRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote Role Read Operation ===") + + fmt.Println("Getting all Remote Roles...") + remoteRoles, err := f5.GetRemoteRoles() + if err != nil { + log.Printf("Error getting Remote Roles: %v", err) + return + } + fmt.Printf("Found %d Remote Roles\n", len(remoteRoles.RemoteRoles)) + + fmt.Println("\nGetting specific Remote Roles...") + for i := 0; i < len(remoteRoles.RemoteRoles); i++ { + remoteRole, err := f5.GetRemoteRole(remoteRoles.RemoteRoles[i].Name) + if err != nil { + log.Printf("Error getting Remote Role: %v", err) + continue + } + if remoteRole != nil { + fmt.Printf("Retrieved Remote Role:\n") + fmt.Printf(" Name: %s\n", remoteRole.Name) + fmt.Printf(" Attribute: %s\n", remoteRole.Attribute) + fmt.Printf(" Role: %s\n", remoteRole.Role) + fmt.Printf(" Console: %s\n", remoteRole.Console) + fmt.Printf(" User Partition: %s\n", remoteRole.UserPartition) + fmt.Printf(" Line Order: %d\n", remoteRole.LineOrder) + fmt.Printf(" Deny: %s\n", remoteRole.Deny) + fmt.Printf(" Description: %s\n", remoteRole.Description) + fmt.Println() + } + } +} + +func testRemoteRoleCreation(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote Role Creation Operation ===") + + remoteRole := &bigip.RemoteRole{ + Name: "lb_admins", + Attribute: "memberof=cn=lb_admins,ou=groups,dc=test,dc=com", + Console: "tmsh", + Deny: "disabled", + LineOrder: 1000, + Role: "administrator", + UserPartition: "All", + Description: "Test admin group created via API", + } + + fmt.Println("Creating Remote Role...") + err := f5.CreateRemoteRole(remoteRole) + if err != nil { + log.Printf("Error creating Remote Role: %v", err) + return + } + fmt.Printf("Remote Role %s created successfully.\n", remoteRole.Name) +} + +func testRemoteRoleUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote Role Update Operation ===") + + remoteRole := &bigip.RemoteRole{ + Name: "lb_admins", + Attribute: "memberof=cn=lb_admins,ou=groups,dc=test,dc=com", + Console: "disabled", + Deny: "disabled", + LineOrder: 1000, + Role: "guest", + UserPartition: "Common", + Description: "Updated test admin group - changed to guest role", + } + + fmt.Println("Updating Remote Role...") + err := f5.ModifyRemoteRole(remoteRole.Name, remoteRole) + if err != nil { + log.Printf("Error updating Remote Role: %v", err) + return + } + fmt.Printf("Remote Role %s updated successfully.\n", remoteRole.Name) +} + +func testRemoteRoleDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote Role Delete Operation ===") + + fmt.Println("Deleting Remote Role test_admins...") + err := f5.DeleteRemoteRole("lb_admins") + if err != nil { + log.Printf("Error deleting Remote Role: %v", err) + return + } + fmt.Printf("Remote Role lb_admins deleted successfully.\n") +} diff --git a/sys.go b/sys.go index f6b4f46..05c944a 100644 --- a/sys.go +++ b/sys.go @@ -1431,3 +1431,83 @@ func (b *BigIP) ModifyManagementFwRule(name string, config *MgmtFirewallRule) er func (b *BigIP) DeleteManagementFwRule(name string) error { return b.delete(uriSecurity, uriFirewall, uriMgmtIpRules, uriRules, name) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Authentication - Remote Role //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// RemoteRoles represent a collection of the user roles on the BIGIP system. +type RemoteRoles struct { + RemoteRoles []RemoteRole `json:"items"` +} + +// // RemoteRoles represents a specific user role on the BIGIP system. +type RemoteRole struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + Generation int `json:"generation,omitempty"` + Attribute string `json:"attribute,omitempty"` + Console string `json:"console,omitempty"` + Deny string `json:"deny,omitempty"` + Description string `json:"description,omitempty"` + LineOrder int `json:"lineOrder,omitempty"` + Role string `json:"role,omitempty"` + UserPartition string `json:"userPartition,omitempty"` +} + +// GetRemoteRoles returns a list of all remote role configurations. +func (b *BigIP) GetRemoteRoles() (*RemoteRoles, error) { + var remoteRoles RemoteRoles + err, ok := b.getForEntity(&remoteRoles, uriAuth, uriRemoteRole, uriRoleInfo) + if err != nil { + if !ok { + return &RemoteRoles{}, nil + } + return nil, err + } + + return &remoteRoles, nil +} + +// GetRemoteRole returns a named remote role configuration. +func (b *BigIP) GetRemoteRole(name string) (*RemoteRole, error) { + var remoteRole RemoteRole + err, ok := b.getForEntity(&remoteRole, uriAuth, uriRemoteRole, uriRoleInfo, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &remoteRole, nil +} + +func validateRemoteRole(config *RemoteRole) error { + if config.Attribute == "" { + return errors.New("attribute is required (e.g., 'memberof=cn=group,dc=example,dc=com')") + } + if config.LineOrder == 0 { + return errors.New("lineOrder is required") + } + return nil +} + +// CreateRemoteRole adds a new remote role configuration to the BIG-IP system. +func (b *BigIP) CreateRemoteRole(config *RemoteRole) error { + err := validateRemoteRole(config) + if err != nil { + return err + } + return b.post(config, uriAuth, uriRemoteRole, uriRoleInfo) +} + +// ModifyRemoteRole allows the update of the attributes. +func (b *BigIP) ModifyRemoteRole(name string, config *RemoteRole) error { + return b.patch(config, uriAuth, uriRemoteRole, uriRoleInfo, name) +} + +// DeleteRemoteRole removes a remote role configuration. +func (b *BigIP) DeleteRemoteRole(name string) error { + return b.delete(uriAuth, uriRemoteRole, uriRoleInfo, name) +} From 19a0b46cde278d1f6748da2f84f6407332cecd3e Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 12 Dec 2025 18:00:53 +0100 Subject: [PATCH 06/25] Implement Sys LDAP Auth support --- examples/sys/main.go | 12 +++- examples/sys/test_ldap_auth.go | 102 +++++++++++++++++++++++++++++++++ sys.go | 82 ++++++++++++++++++++++++++ 3 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_ldap_auth.go diff --git a/examples/sys/main.go b/examples/sys/main.go index 842c121..d191c75 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -35,7 +35,8 @@ func main() { mgmtRouteTesting := false mgmtFwRuleTesting := false - remoteRoleTesting := true + remoteRoleTesting := false + ldapAuthTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -64,5 +65,14 @@ func main() { testRemoteRoleDelete(f5) testRemoteRoleRead(f5) } + if ldapAuthTesting { + testLdapAuthRead(f5) + testLdapAuthCreation(f5) + testLdapAuthRead(f5) + testLdapAuthUpdate(f5) + testLdapAuthRead(f5) + testLdapAuthDelete(f5) + testLdapAuthRead(f5) + } } diff --git a/examples/sys/test_ldap_auth.go b/examples/sys/test_ldap_auth.go new file mode 100644 index 0000000..d87f463 --- /dev/null +++ b/examples/sys/test_ldap_auth.go @@ -0,0 +1,102 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// LDAP Authentication Testing /////////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testLdapAuthRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing LDAP Authentication Read Operation ===") + + // READ: Get system LDAP Configuration + fmt.Println("\nGetting System Auth LDAP Configurations...") + + ldapConfig, err := f5.GetLdapConfig("system-auth") + if err != nil { + log.Printf("Error getting LDAP Configuration: %v", err) + } + if ldapConfig != nil { + fmt.Printf("Retrieved LDAP Configuration:\n") + fmt.Printf(" Name: %s\n", ldapConfig.Name) + fmt.Printf(" Servers: %v\n", ldapConfig.Servers) + fmt.Printf(" Port: %d\n", ldapConfig.Port) + fmt.Printf(" SearchBaseDn: %s\n", ldapConfig.SearchBaseDn) + fmt.Printf(" BindDn: %s\n", ldapConfig.BindDn) + fmt.Printf(" SSL: %s\n", ldapConfig.Ssl) + fmt.Printf(" Referrals: %s\n", ldapConfig.Referrals) + fmt.Println() + } else { + fmt.Printf("System LDAP Authentication is not configured.\n") + } + +} + +func testLdapAuthCreation(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing LDAP Authentication Creation Operation ===") + + // Note: BIG-IP only allows "system-auth" as the LDAP configuration name + ldapConfig := &bigip.LdapConfig{ + Name: "system-auth", + BindDn: "cn=ldap_admin,dc=test,dc=com", + BindPw: "password", + LoginAttribute: "uid", + CheckRolesGroup: "enabled", + Debug: "enabled", + Port: 1389, + Referrals: "no", + Scope: "sub", + SearchBaseDn: "dc=test,dc=com", + Servers: []string{"192.168.252.11"}, + } + + fmt.Println("Creating LDAP Configuration...") + err := f5.CreateLdapConfig(ldapConfig) + if err != nil { + log.Printf("Error creating LDAP Configuration: %v", err) + return + } + fmt.Printf("LDAP Configuration %s created successfully.\n", ldapConfig.Name) +} + +func testLdapAuthUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing LDAP Authentication Update Operation ===") + + ldapConfig := &bigip.LdapConfig{ + Name: "system-auth", + BindDn: "cn=ldap_admin,dc=test,dc=com", + BindPw: "newpassword123", + LoginAttribute: "uid", + CheckRolesGroup: "disabled", + Debug: "disabled", + Port: 389, + Referrals: "yes", + Scope: "sub", + SearchBaseDn: "dc=test,dc=com", + } + + fmt.Println("Updating LDAP Configuration...") + err := f5.ModifyLdapConfig(ldapConfig.Name, ldapConfig) + if err != nil { + log.Printf("Error updating LDAP Configuration: %v", err) + return + } + fmt.Printf("LDAP Configuration %s updated successfully.\n", ldapConfig.Name) +} + +func testLdapAuthDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing LDAP Authentication Delete Operation ===") + + fmt.Println("Deleting LDAP Configuration system-auth...") + err := f5.DeleteLdapConfig("system-auth") + if err != nil { + log.Printf("Error deleting LDAP Configuration: %v", err) + return + } + fmt.Printf("LDAP Configuration system-auth deleted successfully.\n") +} diff --git a/sys.go b/sys.go index 05c944a..08f534a 100644 --- a/sys.go +++ b/sys.go @@ -287,6 +287,7 @@ const ( uriMgmtRoute = "management-route" uriMgmtIpRules = "management-ip-rules" uriRules = "rules" + uriLdap = "ldap" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1511,3 +1512,84 @@ func (b *BigIP) ModifyRemoteRole(name string, config *RemoteRole) error { func (b *BigIP) DeleteRemoteRole(name string) error { return b.delete(uriAuth, uriRemoteRole, uriRoleInfo, name) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// LDAP Authentication //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// LDAPConfig represents LDAP configuration used for authentication to BIGIP system. +type LdapConfig struct { + Name string `json:"name,omitempty" validate:"eq=system-auth"` + BindDn string `json:"bindDn,omitempty"` + BindPw string `json:"bindPw,omitempty"` + BindTimeout int `json:"bindTimeout,omitempty"` + CheckHostAttr string `json:"checkHostAttr,omitempty"` + CheckRolesGroup string `json:"checkRolesGroup,omitempty"` + Debug string `json:"debug,omitempty"` + Filter string `json:"filter,omitempty"` + GroupDn string `json:"groupDn,omitempty"` + GroupMemberAttribute string `json:"groupMemberAttribute,omitempty"` + IdleTimeout int `json:"idleTimeout,omitempty"` + IgnoreAuthInfoUnavail string `json:"ignoreAuthInfoUnavail,omitempty"` + IgnoreUnknownUser string `json:"ignoreUnknownUser,omitempty"` + LoginAttribute string `json:"loginAttribute,omitempty"` + Port int `json:"port,omitempty"` + Referrals string `json:"referrals,omitempty"` + Scope string `json:"scope,omitempty"` + SearchBaseDn string `json:"searchBaseDn,omitempty"` + SearchTimeout int `json:"searchTimeout,omitempty"` + Servers []string `json:"servers,omitempty"` + Ssl string `json:"ssl,omitempty"` + SslCaCertFile string `json:"sslCaCertFile,omitempty"` + SslCheckPeer string `json:"sslCheckPeer,omitempty"` + SslCiphers string `json:"sslCiphers,omitempty"` + SslClientCert string `json:"sslClientCert,omitempty"` + SslClientKey string `json:"sslClientKey,omitempty"` + UserTemplate string `json:"userTemplate,omitempty"` + Version int `json:"version,omitempty"` + Warnings string `json:"warnings,omitempty"` +} + +// GetLdapConfig returns a named LDAP authentication configuration. +func (b *BigIP) GetLdapConfig(name string) (*LdapConfig, error) { + var ldapConfig LdapConfig + err, ok := b.getForEntity(&ldapConfig, uriAuth, uriLdap, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &ldapConfig, nil +} + +func validateLdapConfig(config *LdapConfig) error { + if len(config.Servers) == 0 { + return errors.New("servers is required option, at least one LDAP server must be specified") + } + if config.Name != "" && config.Name != "system-auth" { + return errors.New("name must be 'system-auth'") + } + return nil +} + +// CreateLdapConfig adds a new LDAP authentication configuration to the BIG-IP system. +// BIG-IP only allows the name "system-auth" for LDAP configurations +func (b *BigIP) CreateLdapConfig(config *LdapConfig) error { + err := validateLdapConfig(config) + if err != nil { + return err + } + return b.post(config, uriAuth, uriLdap) +} + +// ModifyLdapConfig allows for a change of attribute in LDAP configuration +func (b *BigIP) ModifyLdapConfig(name string, config *LdapConfig) error { + return b.patch(config, uriAuth, uriLdap, name) +} + +// DeleteLdapConfig removes an LDAP authentication configuration. +func (b *BigIP) DeleteLdapConfig(name string) error { + return b.delete(uriAuth, uriLdap, name) +} From 3da79d67eb4e754282a326f28e9089b68a89e86f Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 12 Dec 2025 18:25:39 +0100 Subject: [PATCH 07/25] Implement Sys Auth Source support --- examples/sys/main.go | 12 ++++- examples/sys/test_auth_source.go | 76 ++++++++++++++++++++++++++++++++ sys.go | 44 ++++++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_auth_source.go diff --git a/examples/sys/main.go b/examples/sys/main.go index d191c75..dfa620b 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -36,7 +36,8 @@ func main() { mgmtRouteTesting := false mgmtFwRuleTesting := false remoteRoleTesting := false - ldapAuthTesting := true + ldapAuthTesting := false + authSourceTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -74,5 +75,14 @@ func main() { testLdapAuthDelete(f5) testLdapAuthRead(f5) } + if authSourceTesting { + testAuthSourceRead(f5) + testAuthSourceCreate(f5) + testAuthSourceRead(f5) + testAuthSourceUpdate(f5) + testAuthSourceRead(f5) + testAuthSourceDelete(f5) + testAuthSourceRead(f5) + } } diff --git a/examples/sys/test_auth_source.go b/examples/sys/test_auth_source.go new file mode 100644 index 0000000..38abd1f --- /dev/null +++ b/examples/sys/test_auth_source.go @@ -0,0 +1,76 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Authentication Source Testing ///////////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testAuthSourceRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Authentication Source Read Operation ===") + + fmt.Println("Getting Authentication Source configuration...") + authSource, err := f5.GetAuthSource() + if err != nil { + log.Printf("Error getting Authentication Source: %v", err) + return + } + if authSource != nil { + fmt.Printf("Retrieved Authentication Source:\n") + fmt.Printf(" Type: %s\n", authSource.Type) + fmt.Printf(" Fallback: %s\n", authSource.Fallback) + } +} + +func testAuthSourceCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Authentication Source Create Operation ===") + + authSource := &bigip.AuthSource{ + Type: "ldap", + Fallback: "false", + } + + fmt.Println("Setting Authentication Source to LDAP...") + err := f5.CreateAuthSource(authSource) + if err != nil { + log.Printf("Error creating Authentication Source: %v", err) + return + } + fmt.Printf("Authentication Source set successfully:\n Type: %s\n Fallback: %s\n", + authSource.Type, authSource.Fallback) +} + +func testAuthSourceUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Authentication Source Update Operation ===") + + authSource := &bigip.AuthSource{ + Type: "radius", + Fallback: "false", + } + + fmt.Println("Updating Authentication Source...") + err := f5.ModifyAuthSource(authSource) + if err != nil { + log.Printf("Error updating Authentication Source: %v", err) + return + } + fmt.Printf("Authentication Source updated successfully:\n Type: %s\n Fallback: %s\n", + authSource.Type, authSource.Fallback) +} + +func testAuthSourceDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Authentication Source Delete Operation ===") + + fmt.Println("Resetting Authentication Source to defaults...") + err := f5.DeleteAuthSource() + if err != nil { + log.Printf("Error deleting Authentication Source: %v", err) + return + } + fmt.Printf("Authentication Source reset to defaults:\n Type: local\n Fallback: false\n") +} diff --git a/sys.go b/sys.go index 08f534a..65dd7aa 100644 --- a/sys.go +++ b/sys.go @@ -288,6 +288,7 @@ const ( uriMgmtIpRules = "management-ip-rules" uriRules = "rules" uriLdap = "ldap" + uriAuthSrc = "source" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1593,3 +1594,46 @@ func (b *BigIP) ModifyLdapConfig(name string, config *LdapConfig) error { func (b *BigIP) DeleteLdapConfig(name string) error { return b.delete(uriAuth, uriLdap, name) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Authentication Source //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// AuthSource represents authentication source used to access BIGIP system. +type AuthSource struct { + Fallback string `json:"fallback,omitempty"` + Type string `json:"type,omitempty"` +} + +// GetAuthSource retrieves the current authentication source configuration. +func (b *BigIP) GetAuthSource() (*AuthSource, error) { + var authSource AuthSource + err, ok := b.getForEntity(&authSource, uriAuth, uriAuthSrc) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &authSource, nil +} + +// CreateAuthSource sets the authentication source configuration. +func (b *BigIP) CreateAuthSource(config *AuthSource) error { + return b.patch(config, uriAuth, uriAuthSrc) +} + +// ModifyAuthSource updates the authentication source configuration. +func (b *BigIP) ModifyAuthSource(config *AuthSource) error { + return b.patch(config, uriAuth, uriAuthSrc) +} + +// DeleteAuthSource resets the authentication source to default values. +func (b *BigIP) DeleteAuthSource() error { + defaultConfig := &AuthSource{ + Type: "local", + Fallback: "false", + } + return b.patch(defaultConfig, uriAuth, uriAuthSrc) +} From 948d8edef5e80a96d93e5ececdbd4eac6158609b Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Mon, 15 Dec 2025 10:09:06 +0100 Subject: [PATCH 08/25] Implementing Sys Auth Remote User support --- examples/sys/main.go | 12 ++++- examples/sys/test_remote_user.go | 79 ++++++++++++++++++++++++++++++++ sys.go | 46 +++++++++++++++++++ 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_remote_user.go diff --git a/examples/sys/main.go b/examples/sys/main.go index dfa620b..57e4dce 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -37,7 +37,8 @@ func main() { mgmtFwRuleTesting := false remoteRoleTesting := false ldapAuthTesting := false - authSourceTesting := true + authSourceTesting := false + remoteUserTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -84,5 +85,14 @@ func main() { testAuthSourceDelete(f5) testAuthSourceRead(f5) } + if remoteUserTesting { + testRemoteUserRead(f5) + testRemoteUserCreate(f5) + testRemoteUserRead(f5) + testRemoteUserUpdate(f5) + testRemoteUserRead(f5) + testRemoteUserDelete(f5) + testRemoteUserRead(f5) + } } diff --git a/examples/sys/test_remote_user.go b/examples/sys/test_remote_user.go new file mode 100644 index 0000000..a867762 --- /dev/null +++ b/examples/sys/test_remote_user.go @@ -0,0 +1,79 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Remote User Testing ///////////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testRemoteUserRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote User Read Operation ===") + + fmt.Println("Getting Remote User configuration...") + remoteUser, err := f5.GetRemoteUser() + if err != nil { + log.Printf("Error getting Remote User: %v", err) + return + } + if remoteUser != nil { + fmt.Printf("Retrieved Remote User:\n") + fmt.Printf(" Default Partition: %s\n", remoteUser.DefaultPartition) + fmt.Printf(" Default Role: %s\n", remoteUser.DefaultRole) + fmt.Printf(" Remote Console Access: %s\n", remoteUser.RemoteConsoleAccess) + } +} + +func testRemoteUserCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote User Create Operation ===") + + remoteUser := &bigip.RemoteUser{ + DefaultPartition: "Common", + DefaultRole: "guest", + RemoteConsoleAccess: "tmsh", + } + + fmt.Println("Setting Remote User configuration...") + err := f5.CreateRemoteUser(remoteUser) + if err != nil { + log.Printf("Error creating Remote User: %v", err) + return + } + fmt.Printf("Remote User set successfully:\n DefaultPartition: %s\n DefaultRole: %s\n RemoteConsoleAccess: %s\n", + remoteUser.DefaultPartition, remoteUser.DefaultRole, remoteUser.RemoteConsoleAccess) +} + +func testRemoteUserUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote User Update Operation ===") + + remoteUser := &bigip.RemoteUser{ + DefaultPartition: "all", + DefaultRole: "operator", + RemoteConsoleAccess: "disabled", + } + + fmt.Println("Updating Remote User...") + err := f5.ModifyRemoteUser(remoteUser) + if err != nil { + log.Printf("Error updating Remote User: %v", err) + return + } + fmt.Printf("Remote User updated successfully:\n DefaultPartition: %s\n DefaultRole: %s\n RemoteConsoleAccess: %s\n", + remoteUser.DefaultPartition, remoteUser.DefaultRole, remoteUser.RemoteConsoleAccess) +} + +func testRemoteUserDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Remote User Delete Operation ===") + + fmt.Println("Resetting Remote User to defaults...") + err := f5.DeleteRemoteUser() + if err != nil { + log.Printf("Error deleting Remote User: %v", err) + return + } + fmt.Printf("Remote User reset to defaults:\n DefaultPartition: all\n DefaultRole: no-access\n RemoteConsoleAccess: disabled\n") +} diff --git a/sys.go b/sys.go index 65dd7aa..8afa4d6 100644 --- a/sys.go +++ b/sys.go @@ -289,6 +289,7 @@ const ( uriRules = "rules" uriLdap = "ldap" uriAuthSrc = "source" + uriRemoteUser = "remote-user" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1637,3 +1638,48 @@ func (b *BigIP) DeleteAuthSource() error { } return b.patch(defaultConfig, uriAuth, uriAuthSrc) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Authentication Remote User ////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// RemoteUser represents the authorization data for external users +type RemoteUser struct { + DefaultPartition string `json:"defaultPartition,omitempty"` + DefaultRole string `json:"defaultRole,omitempty"` + RemoteConsoleAccess string `json:"remoteConsoleAccess,omitempty"` +} + +// GetRemoteUser retrieves the current remote user configuration. +func (b *BigIP) GetRemoteUser() (*RemoteUser, error) { + var remoteUser RemoteUser + err, ok := b.getForEntity(&remoteUser, uriAuth, uriRemoteUser) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &remoteUser, nil +} + +// CreateRemoteUser sets the remote user configuration. +func (b *BigIP) CreateRemoteUser(config *RemoteUser) error { + return b.patch(config, uriAuth, uriRemoteUser) +} + +// ModifyRemoteUser updates the remote user configuration. +func (b *BigIP) ModifyRemoteUser(config *RemoteUser) error { + return b.patch(config, uriAuth, uriRemoteUser) +} + +// DeleteRemoteUser resets the remote user configuration to default values. +func (b *BigIP) DeleteRemoteUser() error { + defaultConfig := &RemoteUser{ + DefaultPartition: "all", + DefaultRole: "no-access", + RemoteConsoleAccess: "disabled", + } + return b.patch(defaultConfig, uriAuth, uriRemoteUser) +} From a12e9efaf7bc1d83ef4abc8b74416606aa038dd3 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Mon, 15 Dec 2025 12:45:35 +0100 Subject: [PATCH 09/25] Implement Syslog support and old syslog code cleanup --- examples/sys/main.go | 12 ++- examples/sys/test_syslog.go | 100 ++++++++++++++++++++ sys.go | 181 +++++++++++++++++++----------------- 3 files changed, 205 insertions(+), 88 deletions(-) create mode 100644 examples/sys/test_syslog.go diff --git a/examples/sys/main.go b/examples/sys/main.go index 57e4dce..f227651 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -38,7 +38,8 @@ func main() { remoteRoleTesting := false ldapAuthTesting := false authSourceTesting := false - remoteUserTesting := true + remoteUserTesting := false + syslogTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -94,5 +95,14 @@ func main() { testRemoteUserDelete(f5) testRemoteUserRead(f5) } + if syslogTesting { + testSyslogRead(f5) + testSyslogCreate(f5) + testSyslogRead(f5) + testSyslogUpdate(f5) + testSyslogRead(f5) + testSyslogDelete(f5) + testSyslogRead(f5) + } } diff --git a/examples/sys/test_syslog.go b/examples/sys/test_syslog.go new file mode 100644 index 0000000..853acc1 --- /dev/null +++ b/examples/sys/test_syslog.go @@ -0,0 +1,100 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Syslog Configuration Testing ///////////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testSyslogRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Syslog Configuration Read Operation ===") + + fmt.Println("Getting Syslog configuration...") + syslogConfig, err := f5.GetSyslogConfig() + if err != nil { + log.Printf("Error getting Syslog configuration: %v", err) + return + } + if syslogConfig != nil { + fmt.Printf("Retrieved Syslog Configuration:\n") + fmt.Printf(" Include: %s\n", syslogConfig.Include) + fmt.Printf(" Remote Servers: %d\n", len(syslogConfig.RemoteServers)) + for i, server := range syslogConfig.RemoteServers { + fmt.Printf(" Server %d: %s:%d (LocalIP: %s)\n", i+1, server.Host, server.RemotePort, server.LocalIp) + } + } +} + +func testSyslogCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Syslog Configuration Create Operation ===") + + syslogConfig := &bigip.SyslogConfig{ + RemoteServers: []bigip.SyslogRemoteServer{ + { + Name: "/Common/remote-syslog-01", + Host: "10.1.10.251", + LocalIp: "none", + RemotePort: 1514, + Description: "Test remote syslog server", + }, + }, + } + + fmt.Println("Setting Syslog configuration...") + err := f5.CreateSyslogConfig(syslogConfig) + if err != nil { + log.Printf("Error creating Syslog configuration: %v", err) + return + } + fmt.Printf("Syslog configuration set successfully:\n") + fmt.Printf(" Include: %s\n Remote Servers: %d\n", + syslogConfig.Include, len(syslogConfig.RemoteServers)) +} + +func testSyslogUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Syslog Configuration Update Operation ===") + + syslogConfig := &bigip.SyslogConfig{ + Include: ` +filter f_complete { + facility(auth,authpriv); +}; +destination d_syslog_server { + udp(\"10.1.10.251\" port (1514)); +}; +log { + source(s_syslog_pipe); + filter(f_complete); + destination(d_syslog_server); +}; +`, + RemoteServers: []bigip.SyslogRemoteServer{}, + } + + fmt.Println("Updating Syslog configuration...") + err := f5.ModifySyslogConfig(syslogConfig) + if err != nil { + log.Printf("Error updating Syslog configuration: %v", err) + return + } + fmt.Printf("Syslog configuration updated successfully:\n") + fmt.Printf(" Include: %s\n Remote Servers: %d\n", + syslogConfig.Include, len(syslogConfig.RemoteServers)) +} + +func testSyslogDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Syslog Configuration Delete Operation ===") + + fmt.Println("Resetting Syslog configuration to defaults...") + err := f5.DeleteSyslogConfig() + if err != nil { + log.Printf("Error deleting Syslog configuration: %v", err) + return + } + fmt.Printf("Syslog configuration reset to defaults.\n") +} diff --git a/sys.go b/sys.go index 8afa4d6..255a7dc 100644 --- a/sys.go +++ b/sys.go @@ -91,74 +91,6 @@ type Provision struct { MemoryRatio int `json:"memoryRatio,omitempty"` } -type Syslogs struct { - Syslogs []Syslog `json:"items"` -} - -type Syslog struct { - AuthPrivFrom string - RemoteServers []RemoteServer -} - -type syslogDTO struct { - AuthPrivFrom string `json:"authPrivFrom,omitempty"` - RemoteServers struct { - Items []RemoteServer `json:"items,omitempty"` - } `json:"remoteServers,omitempty"` -} - -func (p *Syslog) MarshalJSON() ([]byte, error) { - var dto syslogDTO - return json.Marshal(dto) -} - -func (p *Syslog) UnmarshalJSON(b []byte) error { - var dto syslogDTO - err := json.Unmarshal(b, &dto) - if err != nil { - return err - } - - p.AuthPrivFrom = dto.AuthPrivFrom - p.RemoteServers = dto.RemoteServers.Items - - return nil -} - -type RemoteServer struct { - Name string `json:"name,omitempty"` - Host string `json:"host,omitempty"` - RemotePort int `json:"remotePort,omitempty"` -} - -type remoteServerDTO struct { - Name string `json:"name,omitempty"` - Host string `json:"host,omitempty"` - RemotePort int `json:"remotePort,omitempty"` -} - -func (p *RemoteServer) MarshalJSON() ([]byte, error) { - return json.Marshal(remoteServerDTO{ - Name: p.Name, - Host: p.Host, - RemotePort: p.RemotePort, - }) -} - -func (p *RemoteServer) UnmarshalJSON(b []byte) error { - var dto remoteServerDTO - err := json.Unmarshal(b, &dto) - if err != nil { - return err - } - - p.Name = dto.Name - p.Host = dto.Host - p.RemotePort = dto.RemotePort - - return nil -} - type SNMPs struct { SNMPs []SNMP `json:"items"` } @@ -899,25 +831,6 @@ func (b *BigIP) Provisions(name string) (*Provision, error) { return &provision, nil } -func (b *BigIP) Syslogs() (*Syslog, error) { - var syslog Syslog - err, _ := b.getForEntity(&syslog, uriSys, uriSyslog) - - if err != nil { - return nil, err - } - - return &syslog, nil -} - -func (b *BigIP) CreateSyslog(r *Syslog) error { - return b.patch(r, uriSys, uriSyslog) -} - -func (b *BigIP) ModifySyslog(r *Syslog) error { - return b.put(r, uriSys, uriSyslog) -} - func (b *BigIP) CreateSNMP(sysContact string, sysLocation string, allowedAddresses []string) error { config := &SNMP{ SysContact: sysContact, @@ -1683,3 +1596,97 @@ func (b *BigIP) DeleteRemoteUser() error { } return b.patch(defaultConfig, uriAuth, uriRemoteUser) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// System Syslog Configuration //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// SyslogRemoteServer represents a remote syslog server configuration. +type SyslogRemoteServer struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Host string `json:"host,omitempty"` + LocalIp string `json:"localIp,omitempty"` + RemotePort int `json:"remotePort,omitempty"` +} + +// SyslogConfig represents the BIG-IP system syslog configuration. +type SyslogConfig struct { + AuthPrivFrom string `json:"authPrivFrom,omitempty"` + AuthPrivTo string `json:"authPrivTo,omitempty"` + ClusteredHostSlot string `json:"clusteredHostSlot,omitempty"` + ClusteredMessageSlot string `json:"clusteredMessageSlot,omitempty"` + ConsoleLog string `json:"consoleLog,omitempty"` + CronFrom string `json:"cronFrom,omitempty"` + CronTo string `json:"cronTo,omitempty"` + DaemonFrom string `json:"daemonFrom,omitempty"` + DaemonTo string `json:"daemonTo,omitempty"` + Description string `json:"description,omitempty"` + Include string `json:"include,omitempty"` + IsoDate string `json:"isoDate,omitempty"` + KernFrom string `json:"kernFrom,omitempty"` + KernTo string `json:"kernTo,omitempty"` + Local6From string `json:"local6From,omitempty"` + Local6To string `json:"local6To,omitempty"` + MailFrom string `json:"mailFrom,omitempty"` + MailTo string `json:"mailTo,omitempty"` + MessagesFrom string `json:"messagesFrom,omitempty"` + MessagesTo string `json:"messagesTo,omitempty"` + UserLogFrom string `json:"userLogFrom,omitempty"` + UserLogTo string `json:"userLogTo,omitempty"` + RemoteServers []SyslogRemoteServer `json:"remoteServers,omitzero"` +} + +// GetSyslogConfig retrieves the current system syslog configuration. +func (b *BigIP) GetSyslogConfig() (*SyslogConfig, error) { + var syslogConfig SyslogConfig + err, ok := b.getForEntity(&syslogConfig, uriSys, uriSyslog) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &syslogConfig, nil +} + +// CreateSyslogConfig sets the system syslog configuration. +func (b *BigIP) CreateSyslogConfig(config *SyslogConfig) error { + return b.patch(config, uriSys, uriSyslog) +} + +// ModifySyslogConfig updates the system syslog configuration. +func (b *BigIP) ModifySyslogConfig(config *SyslogConfig) error { + return b.patch(config, uriSys, uriSyslog) +} + +// DeleteSyslogConfig resets the system syslog configuration to default values. +func (b *BigIP) DeleteSyslogConfig() error { + defaultConfig := &SyslogConfig{ + AuthPrivFrom: "notice", + AuthPrivTo: "emerg", + ClusteredHostSlot: "enabled", + ClusteredMessageSlot: "disabled", + ConsoleLog: "enabled", + CronFrom: "warning", + CronTo: "emerg", + DaemonFrom: "notice", + DaemonTo: "emerg", + Description: "none", + Include: "none", + IsoDate: "disabled", + KernFrom: "debug", + KernTo: "emerg", + Local6From: "notice", + Local6To: "emerg", + MailFrom: "notice", + MailTo: "emerg", + MessagesFrom: "notice", + MessagesTo: "warning", + UserLogFrom: "notice", + UserLogTo: "emerg", + RemoteServers: []SyslogRemoteServer{}, + } + return b.patch(defaultConfig, uriSys, uriSyslog) +} From 02c7d4e37c0871a08157f904b8e7cd480edc9299 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Mon, 15 Dec 2025 13:14:04 +0100 Subject: [PATCH 10/25] Implementing hostname and GUI banner support --- examples/sys/main.go | 12 ++++- examples/sys/test_global_settings.go | 81 ++++++++++++++++++++++++++++ sys.go | 47 ++++++++++++++++ 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_global_settings.go diff --git a/examples/sys/main.go b/examples/sys/main.go index f227651..17fb9e8 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -39,7 +39,8 @@ func main() { ldapAuthTesting := false authSourceTesting := false remoteUserTesting := false - syslogTesting := true + syslogTesting := false + globalSettingsTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -104,5 +105,14 @@ func main() { testSyslogDelete(f5) testSyslogRead(f5) } + if globalSettingsTesting { + testGlobalSettingsRead(f5) + testGlobalSettingsCreate(f5) + testGlobalSettingsRead(f5) + testGlobalSettingsUpdate(f5) + testGlobalSettingsRead(f5) + testGlobalSettingsDelete(f5) + testGlobalSettingsRead(f5) + } } diff --git a/examples/sys/test_global_settings.go b/examples/sys/test_global_settings.go new file mode 100644 index 0000000..b039646 --- /dev/null +++ b/examples/sys/test_global_settings.go @@ -0,0 +1,81 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Global Settings Testing ///////////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testGlobalSettingsRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Global Settings Read Operation ===") + + fmt.Println("Getting Global Settings configuration...") + globalSettings, err := f5.GetGlobalSettings() + if err != nil { + log.Printf("Error getting Global Settings: %v", err) + return + } + if globalSettings != nil { + fmt.Printf("Retrieved Global Settings:\n") + fmt.Printf(" Hostname: %s\n", globalSettings.Hostname) + fmt.Printf(" GUI Security Banner: %s\n", globalSettings.GuiSecurityBanner) + fmt.Printf(" GUI Security Banner Text: %s\n", globalSettings.GuiSecurityBannerText) + } +} + +func testGlobalSettingsCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Global Settings Create Operation ===") + + globalSettings := &bigip.GlobalSettings{ + Hostname: "ltm02.f5lab.com", + GuiSecurityBanner: "enabled", + GuiSecurityBannerText: "AUTHORIZED ACCESS ONLY\nUnauthorized access is prohibited.", + } + + fmt.Println("Setting Global Settings configuration...") + err := f5.CreateGlobalSettings(globalSettings) + if err != nil { + log.Printf("Error creating Global Settings: %v", err) + return + } + fmt.Printf("Global Settings set successfully:\n") + fmt.Printf(" Hostname: %s\n GUI Security Banner: %s\n", + globalSettings.Hostname, globalSettings.GuiSecurityBanner) +} + +func testGlobalSettingsUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Global Settings Update Operation ===") + + globalSettings := &bigip.GlobalSettings{ + Hostname: "mybigip02.lab.local", + GuiSecurityBanner: "disabled", + GuiSecurityBannerText: "Disabled banner", + } + + fmt.Println("Updating Global Settings...") + err := f5.ModifyGlobalSettings(globalSettings) + if err != nil { + log.Printf("Error updating Global Settings: %v", err) + return + } + fmt.Printf("Global Settings updated successfully:\n") + fmt.Printf(" Hostname: %s\n GUI Security Banner: %s\n", + globalSettings.Hostname, globalSettings.GuiSecurityBanner) +} + +func testGlobalSettingsDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Global Settings Delete Operation ===") + + fmt.Println("Resetting Global Settings to defaults...") + err := f5.DeleteGlobalSettings() + if err != nil { + log.Printf("Error deleting Global Settings: %v", err) + return + } + fmt.Printf("Global Settings reset to defaults.\n") +} diff --git a/sys.go b/sys.go index 255a7dc..391f226 100644 --- a/sys.go +++ b/sys.go @@ -222,6 +222,7 @@ const ( uriLdap = "ldap" uriAuthSrc = "source" uriRemoteUser = "remote-user" + uriGlobalSettings = "global-settings" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1690,3 +1691,49 @@ func (b *BigIP) DeleteSyslogConfig() error { } return b.patch(defaultConfig, uriSys, uriSyslog) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// System Global Settings //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// GlobalSettings represents the BIG-IP system global settings configuration. +// Only a subset of attributes has been implemented. +type GlobalSettings struct { + GuiSecurityBanner string `json:"guiSecurityBanner,omitempty"` + GuiSecurityBannerText string `json:"guiSecurityBannerText,omitempty"` + Hostname string `json:"hostname,omitempty"` +} + +// GetGlobalSettings retrieves the current system global settings configuration. +func (b *BigIP) GetGlobalSettings() (*GlobalSettings, error) { + var globalSettings GlobalSettings + err, ok := b.getForEntity(&globalSettings, uriSys, uriGlobalSettings) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &globalSettings, nil +} + +// CreateGlobalSettings sets the system global settings configuration using PATCH. +func (b *BigIP) CreateGlobalSettings(config *GlobalSettings) error { + return b.patch(config, uriSys, uriGlobalSettings) +} + +// ModifyGlobalSettings updates the system global settings configuration. +func (b *BigIP) ModifyGlobalSettings(config *GlobalSettings) error { + return b.patch(config, uriSys, uriGlobalSettings) +} + +// DeleteGlobalSettings resets the system global settings configuration to default values. +func (b *BigIP) DeleteGlobalSettings() error { + defaultConfig := &GlobalSettings{ + GuiSecurityBanner: "enabled", + GuiSecurityBannerText: "Welcome to the BIG-IP Configuration Utility.\n\nLog in with your username and password using the fields on the left.", + Hostname: "bigip1", + } + return b.patch(defaultConfig, uriSys, uriGlobalSettings) +} From ea86b7cd920d9b89795712c18828e629d3606f96 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Mon, 15 Dec 2025 16:14:53 +0100 Subject: [PATCH 11/25] Implementing SSHD support --- examples/sys/main.go | 12 +++++- examples/sys/test_sshd.go | 84 +++++++++++++++++++++++++++++++++++++++ sys.go | 57 ++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_sshd.go diff --git a/examples/sys/main.go b/examples/sys/main.go index 17fb9e8..04c0177 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -40,7 +40,8 @@ func main() { authSourceTesting := false remoteUserTesting := false syslogTesting := false - globalSettingsTesting := true + globalSettingsTesting := false + sshdTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -114,5 +115,14 @@ func main() { testGlobalSettingsDelete(f5) testGlobalSettingsRead(f5) } + if sshdTesting { + testSSHDRead(f5) + testSSHDCreate(f5) + testSSHDRead(f5) + testSSHDUpdate(f5) + testSSHDRead(f5) + testSSHDDelete(f5) + testSSHDRead(f5) + } } diff --git a/examples/sys/test_sshd.go b/examples/sys/test_sshd.go new file mode 100644 index 0000000..0a84ff6 --- /dev/null +++ b/examples/sys/test_sshd.go @@ -0,0 +1,84 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// SSHD Configuration Testing ////////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testSSHDRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SSHD Configuration Read Operation ===") + + fmt.Println("Getting SSHD configuration...") + sshdConfig, err := f5.GetSSHDConfig() + if err != nil { + log.Printf("Error getting SSHD configuration: %v", err) + return + } + if sshdConfig != nil { + fmt.Printf("Retrieved SSHD Configuration:\n") + fmt.Printf(" Port: %d\n", sshdConfig.Port) + fmt.Printf(" Login: %s\n", sshdConfig.Login) + fmt.Printf(" LogLevel: %s\n", sshdConfig.LogLevel) + fmt.Printf(" Banner: %s\n", sshdConfig.Banner) + fmt.Printf(" BannerText: %s\n", sshdConfig.BannerText) + fmt.Printf(" InactivityTimeout: %d\n", sshdConfig.InactivityTimeout) + fmt.Printf(" Allow: %v\n", sshdConfig.Allow) + } +} + +func testSSHDCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SSHD Configuration Create Operation ===") + + sshdConfig := &bigip.SSHDConfig{ + Banner: "enabled", + BannerText: "AUTHORIZED ACCESS ONLY\nUnauthorized access is prohibited and logged.", + Allow: []string{"10.1.10.0/24", "192.168.1.0/24"}, + } + + fmt.Println("Setting SSHD configuration...") + err := f5.CreateSSHDConfig(sshdConfig) + if err != nil { + log.Printf("Error creating SSHD configuration: %v", err) + return + } + fmt.Printf("SSHD configuration set successfully:\n") + fmt.Printf("BannerText: %s\n Allow: %s\n ", + sshdConfig.BannerText, sshdConfig.Allow) +} + +func testSSHDUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SSHD Configuration Update Operation ===") + + sshdConfig := &bigip.SSHDConfig{ + BannerText: "Updated Banner", + Allow: []string{"172.18.20.0/24"}, + } + + fmt.Println("Updating SSHD configuration...") + err := f5.ModifySSHDConfig(sshdConfig) + if err != nil { + log.Printf("Error updating SSHD configuration: %v", err) + return + } + fmt.Printf("SSHD configuration updated successfully:\n") + fmt.Printf("BannerText: %s\n Allow: %s\n ", + sshdConfig.BannerText, sshdConfig.Allow) +} + +func testSSHDDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SSHD Configuration Delete Operation ===") + + fmt.Println("Resetting SSHD configuration to defaults...") + err := f5.DeleteSSHDConfig() + if err != nil { + log.Printf("Error deleting SSHD configuration: %v", err) + return + } + fmt.Printf("SSHD configuration reset to defaults.\n") +} diff --git a/sys.go b/sys.go index 391f226..b51925d 100644 --- a/sys.go +++ b/sys.go @@ -223,6 +223,7 @@ const ( uriAuthSrc = "source" uriRemoteUser = "remote-user" uriGlobalSettings = "global-settings" + uriSshd = "sshd" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1737,3 +1738,59 @@ func (b *BigIP) DeleteGlobalSettings() error { } return b.patch(defaultConfig, uriSys, uriGlobalSettings) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// SSHD Configuration //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// SSHDConfig represents the BIG-IP SSHD (SSH daemon) configuration. +type SSHDConfig struct { + Allow []string `json:"allow,omitempty"` + Banner string `json:"banner,omitempty"` + BannerText string `json:"bannerText,omitempty"` + FipsCipherVersion int `json:"fipsCipherVersion,omitempty"` + InactivityTimeout int `json:"inactivityTimeout,omitempty"` + Include string `json:"include,omitempty"` + LogLevel string `json:"logLevel,omitempty"` + Login string `json:"login,omitempty"` + Port int `json:"port,omitempty"` +} + +// GetSSHDConfig retrieves the current SSHD configuration. +func (b *BigIP) GetSSHDConfig() (*SSHDConfig, error) { + var sshdConfig SSHDConfig + err, ok := b.getForEntity(&sshdConfig, uriSys, uriSshd) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &sshdConfig, nil +} + +// CreateSSHDConfig sets the SSHD configuration. +func (b *BigIP) CreateSSHDConfig(config *SSHDConfig) error { + return b.patch(config, uriSys, uriSshd) +} + +// ModifySSHDConfig updates the SSHD configuration. +func (b *BigIP) ModifySSHDConfig(config *SSHDConfig) error { + return b.patch(config, uriSys, uriSshd) +} + +// DeleteSSHDConfig resets the SSHD configuration to default values. +func (b *BigIP) DeleteSSHDConfig() error { + defaultConfig := &SSHDConfig{ + Allow: []string{"ALL"}, + Banner: "disabled", + BannerText: "none", + InactivityTimeout: 0, + Include: "none", + LogLevel: "info", + Login: "enabled", + Port: 22, + } + return b.patch(defaultConfig, uriSys, uriSshd) +} From 371369ad28b2a2bec77fa0e0a3c3db76cd40f59b Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Mon, 15 Dec 2025 16:56:25 +0100 Subject: [PATCH 12/25] Implementing HTTPD support --- examples/sys/main.go | 12 ++++- examples/sys/test_httpd.go | 82 ++++++++++++++++++++++++++++ sys.go | 108 +++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_httpd.go diff --git a/examples/sys/main.go b/examples/sys/main.go index 04c0177..fd0be37 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -41,7 +41,8 @@ func main() { remoteUserTesting := false syslogTesting := false globalSettingsTesting := false - sshdTesting := true + sshdTesting := false + httpdTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -124,5 +125,14 @@ func main() { testSSHDDelete(f5) testSSHDRead(f5) } + if httpdTesting { + testHTTPDRead(f5) + testHTTPDCreate(f5) + testHTTPDRead(f5) + testHTTPDUpdate(f5) + testHTTPDRead(f5) + testHTTPDDelete(f5) + testHTTPDRead(f5) + } } diff --git a/examples/sys/test_httpd.go b/examples/sys/test_httpd.go new file mode 100644 index 0000000..bdb6834 --- /dev/null +++ b/examples/sys/test_httpd.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// HTTPD Configuration Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testHTTPDRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HTTPD Configuration Read Operation ===") + + fmt.Println("Getting HTTPD configuration...") + httpdConfig, err := f5.GetHTTPDConfig() + if err != nil { + log.Printf("Error getting HTTPD configuration: %v", err) + return + } + if httpdConfig != nil { + fmt.Printf("Retrieved HTTPD Configuration:\n") + fmt.Printf(" Allow: %v\n", httpdConfig.Allow) + fmt.Printf(" AuthPamIdleTimeout: %d\n", httpdConfig.AuthPamIdleTimeout) + fmt.Printf(" LogLevel: %s\n", httpdConfig.LogLevel) + fmt.Printf(" MaxClients: %d\n", httpdConfig.MaxClients) + fmt.Printf(" SslCertfile: %s\n", httpdConfig.SslCertfile) + fmt.Printf(" SslCertkeyfile: %s\n", httpdConfig.SslCertkeyfile) + } +} + +func testHTTPDCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HTTPD Configuration Create Operation ===") + + httpdConfig := &bigip.HTTPDConfig{ + Allow: []string{"10.1.10.0/24", "192.168.1.0/24"}, + AuthPamIdleTimeout: 1800, + MaxClients: 20, + } + + fmt.Println("Setting HTTPD configuration...") + err := f5.CreateHTTPDConfig(httpdConfig) + if err != nil { + log.Printf("Error creating HTTPD configuration: %v", err) + return + } + fmt.Printf("HTTPD configuration set successfully:\n") + fmt.Printf(" Allow: %v\n AuthPamIdleTimeout: %d\n MaxClients: %d\n", + httpdConfig.Allow, httpdConfig.AuthPamIdleTimeout, httpdConfig.MaxClients) +} + +func testHTTPDUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HTTPD Configuration Update Operation ===") + + httpdConfig := &bigip.HTTPDConfig{ + AuthPamIdleTimeout: 2400, + Allow: []string{"172.18.0.0/16"}, + } + + fmt.Println("Updating HTTPD configuration...") + err := f5.ModifyHTTPDConfig(httpdConfig) + if err != nil { + log.Printf("Error updating HTTPD configuration: %v", err) + return + } + fmt.Printf("HTTPD configuration updated successfully:\n") + fmt.Printf(" Allow: %v\n AuthPamIdleTimeout: %d\n", httpdConfig.Allow, httpdConfig.AuthPamIdleTimeout) +} + +func testHTTPDDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HTTPD Configuration Delete Operation ===") + + fmt.Println("Resetting HTTPD configuration to defaults...") + err := f5.DeleteHTTPDConfig() + if err != nil { + log.Printf("Error deleting HTTPD configuration: %v", err) + return + } + fmt.Printf("HTTPD configuration reset to defaults.\n") +} diff --git a/sys.go b/sys.go index b51925d..4f46abe 100644 --- a/sys.go +++ b/sys.go @@ -224,6 +224,7 @@ const ( uriRemoteUser = "remote-user" uriGlobalSettings = "global-settings" uriSshd = "sshd" + uriHttpd = "httpd" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1794,3 +1795,110 @@ func (b *BigIP) DeleteSSHDConfig() error { } return b.patch(defaultConfig, uriSys, uriSshd) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// HTTPD Configuration /////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// HTTPDConfig represents the BIG-IP HTTPD (HTTP daemon) configuration. +type HTTPDConfig struct { + Allow []string `json:"allow,omitempty"` + AuthName string `json:"authName,omitempty"` + AuthPamDashboardTimeout string `json:"authPamDashboardTimeout,omitempty"` + AuthPamIdleTimeout int `json:"authPamIdleTimeout,omitempty"` + AuthPamValidateIp string `json:"authPamValidateIp,omitempty"` + FastcgiTimeout int `json:"fastcgiTimeout,omitempty"` + FipsCipherVersion int `json:"fipsCipherVersion,omitempty"` + HostnameLookup string `json:"hostnameLookup,omitempty"` + Include string `json:"include,omitempty"` + LogLevel string `json:"logLevel,omitempty"` + MaxClients int `json:"maxClients,omitempty"` + RedirectHttpToHttps string `json:"redirectHttpToHttps,omitempty"` + RequestBodyMaxTimeout int `json:"requestBodyMaxTimeout,omitempty"` + RequestBodyMinRate int `json:"requestBodyMinRate,omitempty"` + RequestBodyTimeout int `json:"requestBodyTimeout,omitempty"` + RequestHeaderMaxTimeout int `json:"requestHeaderMaxTimeout,omitempty"` + RequestHeaderMinRate int `json:"requestHeaderMinRate,omitempty"` + RequestHeaderTimeout int `json:"requestHeaderTimeout,omitempty"` + SslCaCertFile string `json:"sslCaCertFile,omitempty"` + SslCertchainfile string `json:"sslCertchainfile,omitempty"` + SslCertfile string `json:"sslCertfile,omitempty"` + SslCertkeyfile string `json:"sslCertkeyfile,omitempty"` + SslCiphersuite string `json:"sslCiphersuite,omitempty"` + SslInclude string `json:"sslInclude,omitempty"` + SslOcspDefaultResponder string `json:"sslOcspDefaultResponder,omitempty"` + SslOcspEnable string `json:"sslOcspEnable,omitempty"` + SslOcspOverrideResponder string `json:"sslOcspOverrideResponder,omitempty"` + SslOcspResponderTimeout int `json:"sslOcspResponderTimeout,omitempty"` + SslOcspResponseMaxAge int `json:"sslOcspResponseMaxAge,omitempty"` + SslOcspResponseTimeSkew int `json:"sslOcspResponseTimeSkew,omitempty"` + SslPort int `json:"sslPort,omitempty"` + SslProtocol string `json:"sslProtocol,omitempty"` + SslVerifyClient string `json:"sslVerifyClient,omitempty"` + SslVerifyDepth int `json:"sslVerifyDepth,omitempty"` +} + +// GetHTTPDConfig retrieves the current HTTPD configuration. +func (b *BigIP) GetHTTPDConfig() (*HTTPDConfig, error) { + var httpdConfig HTTPDConfig + err, ok := b.getForEntity(&httpdConfig, uriSys, uriHttpd) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &httpdConfig, nil +} + +// CreateHTTPDConfig sets the HTTPD configuration. +func (b *BigIP) CreateHTTPDConfig(config *HTTPDConfig) error { + return b.patch(config, uriSys, uriHttpd) +} + +// ModifyHTTPDConfig updates the HTTPD configuration. +func (b *BigIP) ModifyHTTPDConfig(config *HTTPDConfig) error { + return b.patch(config, uriSys, uriHttpd) +} + +// DeleteHTTPDConfig resets the HTTPD configuration to default values. +func (b *BigIP) DeleteHTTPDConfig() error { + defaultConfig := &HTTPDConfig{ + Allow: []string{"All"}, + AuthName: "BIG-IP", + AuthPamDashboardTimeout: "off", + AuthPamIdleTimeout: 1200, + AuthPamValidateIp: "on", + FastcgiTimeout: 300, + FipsCipherVersion: 0, + HostnameLookup: "off", + Include: "none", + LogLevel: "warn", + MaxClients: 10, + RedirectHttpToHttps: "disabled", + RequestBodyMaxTimeout: 0, + RequestBodyMinRate: 500, + RequestBodyTimeout: 60, + RequestHeaderMaxTimeout: 40, + RequestHeaderMinRate: 500, + RequestHeaderTimeout: 20, + SslCaCertFile: "none", + SslCertchainfile: "none", + SslCertfile: "/etc/httpd/conf/ssl.crt/server.crt", + SslCertkeyfile: "/etc/httpd/conf/ssl.key/server.key", + SslCiphersuite: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:AES128-SHA256:AES256-SHA256", + SslInclude: "none", + SslOcspDefaultResponder: "http://127.0.0.1", + SslOcspEnable: "off", + SslOcspOverrideResponder: "off", + SslOcspResponderTimeout: 300, + SslOcspResponseMaxAge: -1, + SslOcspResponseTimeSkew: 300, + SslPort: 443, + SslProtocol: "all -SSLv2 -SSLv3 -TLSv1", + SslVerifyClient: "no", + SslVerifyDepth: 10, + } + return b.patch(defaultConfig, uriSys, uriHttpd) +} From 91baa6b5ffc915179078db93bb77d4e546b81ea3 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Tue, 16 Dec 2025 09:49:12 +0100 Subject: [PATCH 13/25] Implementing SnmpConfig to support complete CRUD --- examples/sys/main.go | 12 ++++- examples/sys/test_snmp_config.go | 79 ++++++++++++++++++++++++++++++++ sys.go | 45 ++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_snmp_config.go diff --git a/examples/sys/main.go b/examples/sys/main.go index fd0be37..7e6fe11 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -42,7 +42,8 @@ func main() { syslogTesting := false globalSettingsTesting := false sshdTesting := false - httpdTesting := true + httpdTesting := false + snmpConfigTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -134,5 +135,14 @@ func main() { testHTTPDDelete(f5) testHTTPDRead(f5) } + if snmpConfigTesting { + testSnmpConfigRead(f5) + testSnmpConfigCreate(f5) + testSnmpConfigRead(f5) + testSnmpConfigUpdate(f5) + testSnmpConfigRead(f5) + testSnmpConfigDelete(f5) + testSnmpConfigRead(f5) + } } diff --git a/examples/sys/test_snmp_config.go b/examples/sys/test_snmp_config.go new file mode 100644 index 0000000..3bd103b --- /dev/null +++ b/examples/sys/test_snmp_config.go @@ -0,0 +1,79 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// SNMP Config Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testSnmpConfigRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Config Read Operation ===") + + fmt.Println("Getting SNMP Config...") + snmpConfig, err := f5.GetSnmpConfig() + if err != nil { + log.Printf("Error getting SNMP Config: %v", err) + return + } + + if snmpConfig != nil { + fmt.Printf("Retrieved SNMP Config:\n") + fmt.Printf(" System Contact: %s\n", snmpConfig.SysContact) + fmt.Printf(" System Location: %s\n", snmpConfig.SysLocation) + fmt.Printf(" Allowed Addresses: %v\n", snmpConfig.AllowedAddresses) + fmt.Println() + } +} + +func testSnmpConfigCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Config Create Operation ===") + + snmpConfig := &bigip.SnmpConfig{ + SysContact: "Network Admin ", + SysLocation: "Data Center 1", + AllowedAddresses: []string{"10.0.0.0/8", "172.18.0.0/16"}, + } + + fmt.Println("Creating SNMP Config...") + err := f5.CreateSnmpConfig(snmpConfig) + if err != nil { + log.Printf("Error creating SNMP Config: %v", err) + return + } + fmt.Printf("SNMP Config created successfully.\n") +} + +func testSnmpConfigUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Config Update Operation ===") + + snmpConfig := &bigip.SnmpConfig{ + SysContact: "Updated Admin ", + SysLocation: "Data Center 2", + AllowedAddresses: []string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, + } + + fmt.Println("Updating SNMP Config...") + err := f5.ModifySnmpConfig(snmpConfig) + if err != nil { + log.Printf("Error updating SNMP Config: %v", err) + return + } + fmt.Printf("SNMP Config updated successfully.\n") +} + +func testSnmpConfigDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Config Delete Operation ===") + + fmt.Println("Deleting (resetting) SNMP Config...") + err := f5.DeleteSnmpConfig() + if err != nil { + log.Printf("Error deleting SNMP Config: %v", err) + return + } + fmt.Printf("SNMP Config reset to defaults successfully.\n") +} diff --git a/sys.go b/sys.go index 4f46abe..563c766 100644 --- a/sys.go +++ b/sys.go @@ -1902,3 +1902,48 @@ func (b *BigIP) DeleteHTTPDConfig() error { } return b.patch(defaultConfig, uriSys, uriHttpd) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// SNMP Config //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// SnmpConfig represents the BIG-IP SNMP configuration settings. +type SnmpConfig struct { + SysContact string `json:"sysContact,omitempty"` + SysLocation string `json:"sysLocation,omitempty"` + AllowedAddresses []string `json:"allowedAddresses,omitempty"` +} + +// GetSnmpConfig retrieves the current SNMP configuration. +func (b *BigIP) GetSnmpConfig() (*SnmpConfig, error) { + var snmpConfig SnmpConfig + err, ok := b.getForEntity(&snmpConfig, uriSys, uriSnmp) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &snmpConfig, nil +} + +// CreateSnmpConfig sets the SNMP configuration. +func (b *BigIP) CreateSnmpConfig(config *SnmpConfig) error { + return b.patch(config, uriSys, uriSnmp) +} + +// ModifySnmpConfig updates the SNMP configuration. +func (b *BigIP) ModifySnmpConfig(config *SnmpConfig) error { + return b.patch(config, uriSys, uriSnmp) +} + +// DeleteSnmpConfig resets the SNMP configuration to default values. +func (b *BigIP) DeleteSnmpConfig() error { + defaultConfig := &SnmpConfig{ + SysContact: "Customer Name ", + SysLocation: "Network Closet 1", + AllowedAddresses: []string{"127.0.0.0/8"}, + } + return b.patch(defaultConfig, uriSys, uriSnmp) +} From 3d893641ca1ea98cbd8aab51a7849b8be765d646 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Tue, 16 Dec 2025 12:06:41 +0100 Subject: [PATCH 14/25] Implementing SNMP Communities support --- examples/sys/main.go | 12 +++- examples/sys/test_snmp_communities.go | 99 +++++++++++++++++++++++++++ sys.go | 76 ++++++++++++++++++++ 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_snmp_communities.go diff --git a/examples/sys/main.go b/examples/sys/main.go index 7e6fe11..c5d0308 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -43,7 +43,8 @@ func main() { globalSettingsTesting := false sshdTesting := false httpdTesting := false - snmpConfigTesting := true + snmpConfigTesting := false + snmpCommunitiesTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -144,5 +145,14 @@ func main() { testSnmpConfigDelete(f5) testSnmpConfigRead(f5) } + if snmpCommunitiesTesting { + testSnmpCommunitiesRead(f5) + testSnmpCommunityCreate(f5) + testSnmpCommunitiesRead(f5) + testSnmpCommunityUpdate(f5) + testSnmpCommunitiesRead(f5) + testSnmpCommunityDelete(f5) + testSnmpCommunitiesRead(f5) + } } diff --git a/examples/sys/test_snmp_communities.go b/examples/sys/test_snmp_communities.go new file mode 100644 index 0000000..f0dd698 --- /dev/null +++ b/examples/sys/test_snmp_communities.go @@ -0,0 +1,99 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// SNMP Communities Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testSnmpCommunitiesRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Communities Read Operation ===") + + fmt.Println("Getting all SNMP Communities...") + snmpCommunities, err := f5.GetSnmpCommunities() + if err != nil { + log.Printf("Error getting SNMP Communities: %v", err) + return + } + fmt.Printf("Found %d SNMP Communities\n", len(snmpCommunities.SnmpCommunities)) + + fmt.Println("\nGetting specific SNMP Communities...") + for i := 0; i < len(snmpCommunities.SnmpCommunities); i++ { + snmpCommunity, err := f5.GetSnmpCommunity(snmpCommunities.SnmpCommunities[i].Name) + if err != nil { + log.Printf("Error getting SNMP Community: %v", err) + continue + } + if snmpCommunity != nil { + fmt.Printf("Retrieved SNMP Community:\n") + fmt.Printf(" Name: %s\n", snmpCommunity.Name) + fmt.Printf(" Community Name: %s\n", snmpCommunity.CommunityName) + fmt.Printf(" Access: %s\n", snmpCommunity.Access) + fmt.Printf(" IPv6: %s\n", snmpCommunity.Ipv6) + fmt.Printf(" OID Subset: %s\n", snmpCommunity.OidSubset) + fmt.Printf(" Source: %s\n", snmpCommunity.Source) + fmt.Printf(" Description: %s\n", snmpCommunity.Description) + fmt.Println() + } + } +} + +func testSnmpCommunityCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Community Creation Operation ===") + + snmpCommunity := &bigip.SnmpCommunity{ + Name: "test_community", + CommunityName: "test_public", + Access: "ro", + Ipv6: "disabled", + OidSubset: ".1.3.6.1.4.1.3375.2.1.14.3.2", + Source: "default", + Description: "Test SNMP community created via API", + } + + fmt.Println("Creating SNMP Community...") + err := f5.CreateSnmpCommunity(snmpCommunity) + if err != nil { + log.Printf("Error creating SNMP Community: %v", err) + return + } + fmt.Printf("SNMP Community %s created successfully.\n", snmpCommunity.Name) +} + +func testSnmpCommunityUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Community Update Operation ===") + + snmpCommunity := &bigip.SnmpCommunity{ + Name: "test_community", + CommunityName: "test_public_updated", + Access: "rw", + OidSubset: ".1.3.6.1", + Source: "all", + Description: "Updated test SNMP community", + } + + fmt.Println("Updating SNMP Community...") + err := f5.ModifySnmpCommunity(snmpCommunity.Name, snmpCommunity) + if err != nil { + log.Printf("Error updating SNMP Community: %v", err) + return + } + fmt.Printf("SNMP Community %s updated successfully.\n", snmpCommunity.Name) +} + +func testSnmpCommunityDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Community Delete Operation ===") + + fmt.Println("Deleting SNMP Community test_community...") + err := f5.DeleteSnmpCommunity("test_community") + if err != nil { + log.Printf("Error deleting SNMP Community: %v", err) + return + } + fmt.Printf("SNMP Community test_community deleted successfully.\n") +} diff --git a/sys.go b/sys.go index 563c766..27811da 100644 --- a/sys.go +++ b/sys.go @@ -225,6 +225,7 @@ const ( uriGlobalSettings = "global-settings" uriSshd = "sshd" uriHttpd = "httpd" + uriCommunities = "communities" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -1947,3 +1948,78 @@ func (b *BigIP) DeleteSnmpConfig() error { } return b.patch(defaultConfig, uriSys, uriSnmp) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// SNMP Communities //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// SnmpCommunities represents a collection of SNMP community configurations. +type SnmpCommunities struct { + SnmpCommunities []SnmpCommunity `json:"items"` +} + +// SnmpCommunity represents an SNMP community string configuration. +type SnmpCommunity struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + Access string `json:"access,omitempty"` + CommunityName string `json:"communityName,omitempty"` + Description string `json:"description,omitempty"` + Ipv6 string `json:"ipv6,omitempty"` + OidSubset string `json:"oidSubset,omitempty"` + Source string `json:"source,omitempty"` +} + +// GetSnmpCommunities returns a list of all SNMP community configurations. +func (b *BigIP) GetSnmpCommunities() (*SnmpCommunities, error) { + var snmpCommunities SnmpCommunities + err, ok := b.getForEntity(&snmpCommunities, uriSys, uriSnmp, uriCommunities) + if err != nil { + if !ok { + return &SnmpCommunities{}, nil + } + return nil, err + } + + return &snmpCommunities, nil +} + +// GetSnmpCommunity returns a named SNMP community configuration. +func (b *BigIP) GetSnmpCommunity(name string) (*SnmpCommunity, error) { + var snmpCommunity SnmpCommunity + err, ok := b.getForEntity(&snmpCommunity, uriSys, uriSnmp, uriCommunities, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &snmpCommunity, nil +} + +func validateSnmpCommunity(config *SnmpCommunity) error { + if config.CommunityName == "" { + return errors.New("communityName is required") + } + return nil +} + +// CreateSnmpCommunity adds a new SNMP community configuration to the BIG-IP system. +func (b *BigIP) CreateSnmpCommunity(config *SnmpCommunity) error { + err := validateSnmpCommunity(config) + if err != nil { + return err + } + return b.post(config, uriSys, uriSnmp, uriCommunities) +} + +// ModifySnmpCommunity allows the change of any attribute in SNMP community configuration. +func (b *BigIP) ModifySnmpCommunity(name string, config *SnmpCommunity) error { + return b.put(config, uriSys, uriSnmp, uriCommunities, name) +} + +// DeleteSnmpCommunity removes an SNMP community configuration. +func (b *BigIP) DeleteSnmpCommunity(name string) error { + return b.delete(uriSys, uriSnmp, uriCommunities, name) +} From 27209f60e39f22369b69b16ccdfe8f667be02634 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Tue, 16 Dec 2025 15:53:31 +0100 Subject: [PATCH 15/25] Implementing SNMP Access v3 support --- examples/sys/main.go | 12 +++- examples/sys/test_snmp_users.go | 107 ++++++++++++++++++++++++++++++++ sys.go | 88 ++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_snmp_users.go diff --git a/examples/sys/main.go b/examples/sys/main.go index c5d0308..96e01e3 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -44,7 +44,8 @@ func main() { sshdTesting := false httpdTesting := false snmpConfigTesting := false - snmpCommunitiesTesting := true + snmpCommunitiesTesting := false + snmpUsersTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -154,5 +155,14 @@ func main() { testSnmpCommunityDelete(f5) testSnmpCommunitiesRead(f5) } + if snmpUsersTesting { + testSnmpUsersRead(f5) + testSnmpUserCreation(f5) + testSnmpUsersRead(f5) + testSnmpUserUpdate(f5) + testSnmpUsersRead(f5) + testSnmpUserDelete(f5) + testSnmpUsersRead(f5) + } } diff --git a/examples/sys/test_snmp_users.go b/examples/sys/test_snmp_users.go new file mode 100644 index 0000000..d9adb7a --- /dev/null +++ b/examples/sys/test_snmp_users.go @@ -0,0 +1,107 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// SNMP Users Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testSnmpUsersRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP Users Read Operation ===") + + fmt.Println("Getting all SNMP Users...") + snmpUsers, err := f5.GetSnmpUsers() + if err != nil { + log.Printf("Error getting SNMP Users: %v", err) + return + } + fmt.Printf("Found %d SNMP Users\n", len(snmpUsers.SnmpUsers)) + + fmt.Println("\nGetting specific SNMP Users...") + for i := 0; i < len(snmpUsers.SnmpUsers); i++ { + snmpUser, err := f5.GetSnmpUser(snmpUsers.SnmpUsers[i].Name) + if err != nil { + log.Printf("Error getting SNMP User: %v", err) + continue + } + if snmpUser != nil { + fmt.Printf("Retrieved SNMP User:\n") + fmt.Printf(" Name: %s\n", snmpUser.Name) + fmt.Printf(" Username: %s\n", snmpUser.Username) + fmt.Printf(" Access: %s\n", snmpUser.Access) + fmt.Printf(" Auth Protocol: %s\n", snmpUser.AuthProtocol) + fmt.Printf(" Privacy Protocol: %s\n", snmpUser.PrivacyProtocol) + fmt.Printf(" Security Level: %s\n", snmpUser.SecurityLevel) + fmt.Printf(" OID Subset: %s\n", snmpUser.OidSubset) + fmt.Printf(" Description: %s\n", snmpUser.Description) + fmt.Println() + } + } +} + +func testSnmpUserCreation(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP User Creation Operation ===") + + snmpUser := &bigip.SnmpUser{ + Name: "test_snmp_user", + Username: "testuser", + Access: "ro", + AuthPassword: "testpassword123", + AuthProtocol: "sha", + PrivacyPassword: "testpassword123", + PrivacyProtocol: "aes", + SecurityLevel: "auth-privacy", + OidSubset: ".1.3.6.1.4.1.3375.2.1.14.3.2", + Description: "Test SNMPv3 user created via API", + } + + fmt.Println("Creating SNMP User...") + err := f5.CreateSnmpUser(snmpUser) + if err != nil { + log.Printf("Error creating SNMP User: %v", err) + return + } + fmt.Printf("SNMP User %s created successfully.\n", snmpUser.Name) +} + +func testSnmpUserUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP User Update Operation ===") + + snmpUser := &bigip.SnmpUser{ + Name: "test_snmp_user", + Username: "testuser_updated", + Access: "rw", + AuthPassword: "newpassword456", + AuthProtocol: "sha", + PrivacyPassword: "newpassword456", + PrivacyProtocol: "aes", + SecurityLevel: "auth-privacy", + OidSubset: ".1.3.6.1.4.1.3375.2.1.14", + Description: "Updated test SNMPv3 user - changed to read-write", + } + + fmt.Println("Updating SNMP User...") + err := f5.ModifySnmpUser(snmpUser.Name, snmpUser) + if err != nil { + log.Printf("Error updating SNMP User: %v", err) + return + } + fmt.Printf("SNMP User %s updated successfully.\n", snmpUser.Name) +} + +func testSnmpUserDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing SNMP User Delete Operation ===") + + fmt.Println("Deleting SNMP User test_snmp_user...") + err := f5.DeleteSnmpUser("test_snmp_user") + if err != nil { + log.Printf("Error deleting SNMP User: %v", err) + return + } + fmt.Printf("SNMP User test_snmp_user deleted successfully.\n") +} diff --git a/sys.go b/sys.go index 27811da..fbc8c3b 100644 --- a/sys.go +++ b/sys.go @@ -226,6 +226,7 @@ const ( uriSshd = "sshd" uriHttpd = "httpd" uriCommunities = "communities" + uriSnmpUsers = "users" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -2023,3 +2024,90 @@ func (b *BigIP) ModifySnmpCommunity(name string, config *SnmpCommunity) error { func (b *BigIP) DeleteSnmpCommunity(name string) error { return b.delete(uriSys, uriSnmp, uriCommunities, name) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// SNMP Users //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// SnmpUsers represents a collection of SNMP user configurations. +type SnmpUsers struct { + SnmpUsers []SnmpUser `json:"items"` +} + +// SnmpUser represents an SNMPv3 user account configuration. +type SnmpUser struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + Access string `json:"access,omitempty"` + AuthPassword string `json:"authPassword,omitempty"` + AuthProtocol string `json:"authProtocol,omitempty"` + Description string `json:"description,omitempty"` + OidSubset string `json:"oidSubset,omitempty"` + PrivacyPassword string `json:"privacyPassword,omitempty"` + PrivacyProtocol string `json:"privacyProtocol,omitempty"` + SecurityLevel string `json:"securityLevel,omitempty"` + Username string `json:"username,omitempty"` +} + +// GetSnmpUsers returns a list of all SNMP user configurations. +func (b *BigIP) GetSnmpUsers() (*SnmpUsers, error) { + var snmpUsers SnmpUsers + err, ok := b.getForEntity(&snmpUsers, uriSys, uriSnmp, uriSnmpUsers) + if err != nil { + if !ok { + return &SnmpUsers{}, nil + } + return nil, err + } + + return &snmpUsers, nil +} + +// GetSnmpUser returns a named SNMP user configuration. +func (b *BigIP) GetSnmpUser(name string) (*SnmpUser, error) { + var snmpUser SnmpUser + err, ok := b.getForEntity(&snmpUser, uriSys, uriSnmp, uriSnmpUsers, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &snmpUser, nil +} + +func validateSnmpUser(config *SnmpUser) error { + if config.Username == "" { + return errors.New("username is required") + } + if config.AuthProtocol == "" { + return errors.New("authProtocol is required (e.g., 'sha', 'md5')") + } + if config.PrivacyProtocol == "" { + return errors.New("privacyProtocol is required (e.g., 'aes', 'des')") + } + return nil +} + +// CreateSnmpUser adds a new SNMP user configuration to the BIG-IP system. +func (b *BigIP) CreateSnmpUser(config *SnmpUser) error { + err := validateSnmpUser(config) + if err != nil { + return err + } + return b.post(config, uriSys, uriSnmp, uriSnmpUsers) +} + +// ModifySnmpUser allows you to change any attribute of an SNMP user configuration. +// We need to use PATCH method due to "authPasswordEncrypted" and "privacyPasswordEncrypted" attribute +// DOCUMENTATION: "privacyPasswordEncrypted": "Encrypted password used to encrypt traffic. +// NOTICE: This display only field is deprecated in TMOS 14.1.0" +func (b *BigIP) ModifySnmpUser(name string, config *SnmpUser) error { + return b.patch(config, uriSys, uriSnmp, uriSnmpUsers, name) +} + +// DeleteSnmpUser removes an SNMP user configuration. +func (b *BigIP) DeleteSnmpUser(name string) error { + return b.delete(uriSys, uriSnmp, uriSnmpUsers, name) +} From 6eb64734afb4a10ffd0de81efd2444cb7a009994 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Tue, 16 Dec 2025 21:22:59 +0100 Subject: [PATCH 16/25] Implementing HA Group support --- examples/sys/main.go | 12 +++- examples/sys/test_ha_group.go | 123 ++++++++++++++++++++++++++++++++++ sys.go | 109 ++++++++++++++++++++++++++++++ 3 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 examples/sys/test_ha_group.go diff --git a/examples/sys/main.go b/examples/sys/main.go index 96e01e3..8d1721a 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -45,7 +45,8 @@ func main() { httpdTesting := false snmpConfigTesting := false snmpCommunitiesTesting := false - snmpUsersTesting := true + snmpUsersTesting := false + haGroupTesting := true if mgmtRouteTesting { testManagementRouteCreation(f5) @@ -164,5 +165,14 @@ func main() { testSnmpUserDelete(f5) testSnmpUsersRead(f5) } + if haGroupTesting { + testHaGroupRead(f5) + testHaGroupCreation(f5) + testHaGroupRead(f5) + testHaGroupUpdate(f5) + testHaGroupRead(f5) + testHaGroupDelete(f5) + testHaGroupRead(f5) + } } diff --git a/examples/sys/test_ha_group.go b/examples/sys/test_ha_group.go new file mode 100644 index 0000000..9fb71e2 --- /dev/null +++ b/examples/sys/test_ha_group.go @@ -0,0 +1,123 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// HA Group Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testHaGroupRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HA Group Read Operation ===") + + fmt.Println("Getting all HA Groups...") + haGroups, err := f5.GetHaGroups() + if err != nil { + log.Printf("Error getting HA Groups: %v", err) + return + } + fmt.Printf("Found %d HA Groups\n", len(haGroups.HaGroups)) + + fmt.Println("\nGetting specific HA Groups...") + for i := 0; i < len(haGroups.HaGroups); i++ { + haGroup, err := f5.GetHaGroup(haGroups.HaGroups[i].Name) + if err != nil { + log.Printf("Error getting HA Group: %v", err) + continue + } + if haGroup != nil { + fmt.Printf("Retrieved HA Group:\n") + fmt.Printf(" Name: %s\n", haGroup.Name) + fmt.Printf(" Active Bonus: %d\n", haGroup.ActiveBonus) + fmt.Printf(" Enabled: %t\n", haGroup.Enabled) + fmt.Printf(" Description: %s\n", haGroup.Description) + fmt.Printf(" Pools: %d\n", len(haGroup.Pools)) + fmt.Printf(" Clusters: %d\n", len(haGroup.Clusters)) + fmt.Printf(" Trunks: %d\n", len(haGroup.Trunks)) + if len(haGroup.Pools) > 0 { + for _, pool := range haGroup.Pools { + fmt.Printf(" Pool: %s (Weight: %d, MinThreshold: %d, SufficientThreshold: %s)\n", + pool.Name, pool.Weight, pool.MinimumThreshold, pool.SufficientThreshold) + } + } + fmt.Println() + } + } +} + +func testHaGroupCreation(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HA Group Creation Operation ===") + + haGroup := &bigip.HaGroup{ + Name: "test_ha_group", + ActiveBonus: 10, + Description: "Test HA Group created via API", + Pools: []bigip.HaGroupPool{ + { + Name: "/Common/Pool_1", + Attribute: "percent-up-members", + MinimumThreshold: 1, + SufficientThreshold: "all", + Weight: 10, + }, + }, + } + + fmt.Println("Creating HA Group...") + err := f5.CreateHaGroup(haGroup) + if err != nil { + log.Printf("Error creating HA Group: %v", err) + return + } + fmt.Printf("HA Group %s created successfully.\n", haGroup.Name) +} + +func testHaGroupUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HA Group Update Operation ===") + + haGroup := &bigip.HaGroup{ + Name: "test_ha_group", + ActiveBonus: 20, + Description: "Updated test HA Group - changed active bonus", + Pools: []bigip.HaGroupPool{ + { + Name: "/Common/Pool_1", + Attribute: "percent-up-members", + MinimumThreshold: 1, + SufficientThreshold: "all", + Weight: 15, + }, + { + Name: "/Common/devdos_pool", + Attribute: "percent-up-members", + MinimumThreshold: 1, + SufficientThreshold: "all", + Weight: 20, + }, + }, + } + + fmt.Println("Updating HA Group...") + err := f5.ModifyHaGroup(haGroup.Name, haGroup) + if err != nil { + log.Printf("Error updating HA Group: %v", err) + return + } + fmt.Printf("HA Group %s updated successfully.\n", haGroup.Name) +} + +func testHaGroupDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing HA Group Delete Operation ===") + + fmt.Println("Deleting HA Group test_ha_group...") + err := f5.DeleteHaGroup("test_ha_group") + if err != nil { + log.Printf("Error deleting HA Group: %v", err) + return + } + fmt.Printf("HA Group test_ha_group deleted successfully.\n") +} diff --git a/sys.go b/sys.go index fbc8c3b..b83aa3b 100644 --- a/sys.go +++ b/sys.go @@ -227,6 +227,7 @@ const ( uriHttpd = "httpd" uriCommunities = "communities" uriSnmpUsers = "users" + uriHaGroup = "ha-group" uriSys = "sys" uriTm = "tm" uriCli = "cli" @@ -2111,3 +2112,111 @@ func (b *BigIP) ModifySnmpUser(name string, config *SnmpUser) error { func (b *BigIP) DeleteSnmpUser(name string) error { return b.delete(uriSys, uriSnmp, uriSnmpUsers, name) } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// HA Group ///////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// HaGroups represents a collection of HA Group configurations. +type HaGroups struct { + HaGroups []HaGroup `json:"items"` +} + +// HaGroupPool represents a pool configuration within an HA Group. +type HaGroupPool struct { + Name string `json:"name,omitempty"` + Attribute string `json:"attribute,omitempty"` + MinimumThreshold int `json:"minimumThreshold,omitempty"` + PercentUp int `json:"percentUp,omitempty"` + SufficientThreshold string `json:"sufficientThreshold,omitempty"` + Weight int `json:"weight,omitempty"` +} + +// HaGroupCluster represents a cluster configuration within an HA Group. +type HaGroupCluster struct { + Name string `json:"name,omitempty"` + Attribute string `json:"attribute,omitempty"` + MinimumThreshold int `json:"minimumThreshold,omitempty"` + PercentUp int `json:"percentUp,omitempty"` + SufficientThreshold string `json:"sufficientThreshold,omitempty"` + Weight int `json:"weight,omitempty"` +} + +// HaGroupTrunk represents a trunk configuration within an HA Group. +type HaGroupTrunk struct { + Name string `json:"name,omitempty"` + Attribute string `json:"attribute,omitempty"` + MinimumThreshold int `json:"minimumThreshold,omitempty"` + PercentUp int `json:"percentUp,omitempty"` + SufficientThreshold string `json:"sufficientThreshold,omitempty"` + Weight int `json:"weight,omitempty"` +} + +// HaGroup represents an HA Group configuration for failover scoring. +type HaGroup struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + ActiveBonus int `json:"activeBonus,omitempty"` + Description string `json:"description,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Pools []HaGroupPool `json:"pools,omitempty"` + Clusters []HaGroupCluster `json:"clusters,omitempty"` + Trunks []HaGroupTrunk `json:"trunks,omitempty"` +} + +// GetHaGroups returns a list of all HA Group configurations. +func (b *BigIP) GetHaGroups() (*HaGroups, error) { + var haGroups HaGroups + err, ok := b.getForEntity(&haGroups, uriSys, uriHaGroup) + if err != nil { + if !ok { + return &HaGroups{}, nil + } + return nil, err + } + + return &haGroups, nil +} + +// GetHaGroup returns a named HA Group configuration. +func (b *BigIP) GetHaGroup(name string) (*HaGroup, error) { + var haGroup HaGroup + err, ok := b.getForEntity(&haGroup, uriSys, uriHaGroup, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &haGroup, nil +} + +func validateHaGroupState(config *HaGroup) error { + if config.Enabled && config.Disabled { + return fmt.Errorf(`"disabled" should not be specified with "enabled"`) + } + return nil +} + +// CreateHaGroup adds a new HA Group configuration to the BIG-IP system. +func (b *BigIP) CreateHaGroup(config *HaGroup) error { + if err := validateHaGroupState(config); err != nil { + return err + } + return b.post(config, uriSys, uriHaGroup) +} + +// ModifyHaGroup allows you to change any attribute of an HA Group configuration. +func (b *BigIP) ModifyHaGroup(name string, config *HaGroup) error { + if err := validateHaGroupState(config); err != nil { + return err + } + return b.put(config, uriSys, uriHaGroup, name) +} + +// DeleteHaGroup removes an HA Group configuration. +func (b *BigIP) DeleteHaGroup(name string) error { + return b.delete(uriSys, uriHaGroup, name) +} From 33bcb1a7c03bb4f38a19b9f6442eabb9428e61ab Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Wed, 17 Dec 2025 10:50:02 +0100 Subject: [PATCH 17/25] Expanding Route Domain support --- examples/net/main.go | 48 ++++++++++ examples/net/test_route_domain.go | 104 +++++++++++++++++++++ net.go | 150 +++++++++++++++++------------- net_test.go | 56 ----------- 4 files changed, 237 insertions(+), 121 deletions(-) create mode 100644 examples/net/main.go create mode 100644 examples/net/test_route_domain.go diff --git a/examples/net/main.go b/examples/net/main.go new file mode 100644 index 0000000..e3dd122 --- /dev/null +++ b/examples/net/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + "os" + + "github.com/f5devcentral/go-bigip" +) + +func main() { + // Connect to the BIG-IP system. + // Replace with your actual BIG-IP credentials and hostname + config := &bigip.Config{ + //Address: "https://192.168.1.1", + Username: "admin", + //Password: "admin", + CertVerifyDisable: true, // Disable certificate verification for testing purposes + } + + config.Address = os.Getenv("BIGIP_ADDRESS") + if config.Address != "" { + fmt.Println("BIGIP_ADDRESS:", config.Address) + } else { + fmt.Println("BIGIP_ADDRESS is not set.") + } + + config.Password = os.Getenv("BIGIP_PASSWORD") + if config.Password != "" { + fmt.Println("BIGIP_PASSWORD:", config.Password) + } else { + fmt.Println("BIGIP_PASSWORD is not set.") + } + + f5 := bigip.NewSession(config) + + routeDomainTesting := true + + if routeDomainTesting { + testRouteDomainRead(f5) + testRouteDomainCreate(f5) + testRouteDomainRead(f5) + testRouteDomainUpdate(f5) + testRouteDomainRead(f5) + testRouteDomainDelete(f5) + testRouteDomainRead(f5) + } + +} diff --git a/examples/net/test_route_domain.go b/examples/net/test_route_domain.go new file mode 100644 index 0000000..4638d05 --- /dev/null +++ b/examples/net/test_route_domain.go @@ -0,0 +1,104 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Route Domain Extended Testing ////////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testRouteDomainRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Route Domain Read Operation ===") + + // READ: Get all Route Domains + fmt.Println("Getting all Route Domains...") + routedomains, err := f5.GetRouteDomains() + if err != nil { + log.Printf("Error getting Route Domains: %v", err) + return + } + fmt.Printf("Found %d Route Domains\n", len(routedomains.RouteDomains)) + + // READ: Get specific Route Domain + fmt.Println("\nGetting specific Route Domains...") + for i := 0; i < len(routedomains.RouteDomains); i++ { + routedomain, err := f5.GetRouteDomain(routedomains.RouteDomains[i].Name) + if err != nil { + log.Printf("Error getting Route Domain: %v", err) + continue + } + if routedomain != nil { + fmt.Printf("Retrieved Route Domain:\n") + fmt.Printf(" Name: %s\n", routedomain.Name) + fmt.Printf(" ID: %d\n", routedomain.ID) + fmt.Printf(" Strict: %s\n", routedomain.Strict) + fmt.Printf(" Parent: %s\n", routedomain.Parent) + fmt.Printf(" VLANs: %v\n", routedomain.Vlans) + fmt.Printf(" Description: %s\n", routedomain.Description) + fmt.Printf(" Connection Limit: %d\n", routedomain.ConnectionLimit) + fmt.Println() + } + } +} + +func testRouteDomainCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Route Domain Creation Operation ===") + + routeDomain := &bigip.RouteDomain{ + Name: "rd_test", + ID: 300, + Strict: "enabled", + Description: "Test route domain created via API", + //ConnectionLimit: 0, + //Vlans: []string{"/Common/vlan100", "/Common/vlan101"}, + //RoutingProtocol: []string{}, + //Parent: "", + } + + fmt.Println("Creating Route Domain...") + err := f5.CreateRouteDomain(routeDomain) + if err != nil { + log.Printf("Error creating Route Domain: %v", err) + return + } + fmt.Printf("Route Domain %s (ID: %d) created successfully.\n", routeDomain.Name, routeDomain.ID) +} + +func testRouteDomainUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Route Domain Update Operation ===") + + routeDomain := &bigip.RouteDomain{ + Name: "rd_test", + //ID: 100, + Strict: "disabled", + Description: "Updated test route domain - strict mode disabled", + ConnectionLimit: 5000, + //Vlans: []string{"/Common/vlan100", "/Common/vlan101", "/Common/vlan102"}, + } + + // MODIFY: Update Route Domain + fmt.Println("Updating Route Domain...") + err := f5.ModifyRouteDomain(routeDomain.Name, routeDomain) + if err != nil { + log.Printf("Error updating Route Domain: %v", err) + return + } + fmt.Printf("Route Domain %s updated successfully.\n", routeDomain.Name) +} + +func testRouteDomainDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Route Domain Delete Operation ===") + + // DELETE: Remove Route Domain + fmt.Println("Deleting Route Domain rd_test_100...") + err := f5.DeleteRouteDomain("rd_test") + if err != nil { + log.Printf("Error deleting Route Domain: %v", err) + return + } + fmt.Printf("Route Domain rd_test deleted successfully.\n") +} diff --git a/net.go b/net.go index 5bc3e4d..f1f33a6 100644 --- a/net.go +++ b/net.go @@ -11,6 +11,7 @@ See the License for the specific language governing permissions and limitations package bigip import ( + "fmt" "regexp" "strings" ) @@ -161,23 +162,6 @@ type Route struct { Network string `json:"network,omitempty"` } -// RouteDomains contains a list of every route domain on the BIG-IP system. -type RouteDomains struct { - RouteDomains []RouteDomain `json:"items"` -} - -// RouteDomain contains information about each individual route domain. You can use all -// of these fields when modifying a route domain. -type RouteDomain struct { - Name string `json:"name,omitempty"` - Partition string `json:"partition,omitempty"` - FullPath string `json:"fullPath,omitempty"` - Generation int `json:"generation,omitempty"` - ID int `json:"id,omitempty"` - Strict string `json:"strict,omitempty"` - Vlans []string `json:"vlans,omitempty"` -} - // Tunnels contains a list of tunnel objects on the BIG-IP system. type Tunnels struct { Tunnels []Tunnel `json:"items"` @@ -566,54 +550,6 @@ func (b *BigIP) ModifyRoute(name string, config *Route) error { return b.put(config, uriNet, uriRoute, name) } -// RouteDomains returns a list of route domains. -func (b *BigIP) RouteDomains() (*RouteDomains, error) { - var rd RouteDomains - err, _ := b.getForEntity(&rd, uriNet, uriRouteDomain) - - if err != nil { - return nil, err - } - - return &rd, nil -} - -// CreateRouteDomain adds a new route domain to the BIG-IP system. must be separated -// by a comma, i.e.: "vlan1010, vlan1020". -func (b *BigIP) CreateRouteDomain(name string, id int, strict bool, vlans string) error { - strictIsolation := "enabled" - vlanMembers := []string{} - rawVlans := strings.Split(vlans, ",") - - for _, v := range rawVlans { - vlanMembers = append(vlanMembers, strings.Trim(v, " ")) - } - - if !strict { - strictIsolation = "disabled" - } - - config := &RouteDomain{ - Name: name, - ID: id, - Strict: strictIsolation, - Vlans: vlanMembers, - } - - return b.post(config, uriNet, uriRouteDomain) -} - -// DeleteRouteDomain removes a route domain. -func (b *BigIP) DeleteRouteDomain(name string) error { - return b.delete(uriNet, uriRouteDomain, name) -} - -// ModifyRouteDomain allows you to change any attribute of a route domain. Fields that -// can be modified are referenced in the RouteDomain struct. -func (b *BigIP) ModifyRouteDomain(name string, config *RouteDomain) error { - return b.put(config, uriNet, uriRouteDomain, name) -} - // Tunnels returns a list of tunnels. func (b *BigIP) Tunnels() (*Tunnels, error) { var tunnels Tunnels @@ -823,3 +759,87 @@ func (b *BigIP) GetIPSecProfile(name string) (*IPSecProfile, error) { return &ipsec, nil } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Route Domain //////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// RouteDomains represents a collection of BIG-IP route domains with all available attributes. +type RouteDomains struct { + RouteDomains []RouteDomain `json:"items"` +} + +// RouteDomain represents a BIG-IP route domain configuration with all available attributes. +// This includes fields for firewall policies, bandwidth control, NAT, and other advanced features. +type RouteDomain struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + ID int `json:"id,omitempty"` + Partition string `json:"partition,omitempty"` + Description string `json:"description,omitempty"` + Strict string `json:"strict,omitempty"` + Parent string `json:"parent,omitempty"` + Vlans []string `json:"vlans,omitempty"` + RoutingProtocol []string `json:"routingProtocol,omitempty"` + BwcPolicy string `json:"bwcPolicy,omitempty"` + ConnectionLimit int `json:"connectionLimit,omitempty"` + FlowEvictionPolicy string `json:"flowEvictionPolicy,omitempty"` + FwEnforcedPolicy string `json:"fwEnforcedPolicy,omitempty"` + FwStagedPolicy string `json:"fwStagedPolicy,omitempty"` + IpIntelligencePolicy string `json:"ipIntelligencePolicy,omitempty"` + SecurityNatPolicy string `json:"securityNatPolicy,omitempty"` + SecurityPacketFilterPolicy string `json:"securityPacketFilterPolicy,omitempty"` + ServicePolicy string `json:"servicePolicy,omitempty"` + ThroughputCapacity string `json:"throughputCapacity,omitempty"` +} + +// GetRouteDomains returns a list of all route domains with all available attributes. +func (b *BigIP) GetRouteDomains() (*RouteDomains, error) { + var routedomains RouteDomains + err, ok := b.getForEntity(&routedomains, uriNet, uriRouteDomain) + if err != nil { + if !ok { + return &RouteDomains{}, nil + } + return nil, err + } + + return &routedomains, nil +} + +// GetRouteDomain returns a named route domain with all available attributes. +func (b *BigIP) GetRouteDomain(name string) (*RouteDomain, error) { + var routedomain RouteDomain + err, ok := b.getForEntity(&routedomain, uriNet, uriRouteDomain, name) + if err != nil { + if !ok { + return nil, nil + } + return nil, err + } + + return &routedomain, nil +} + +// CreateRouteDomain adds a new route domain to the BIG-IP system. +func (b *BigIP) CreateRouteDomain(config *RouteDomain) error { + if config.ID == 0 { + return fmt.Errorf("route domain ID is required and cannot be 0") + } + if config.Name == "" { + return fmt.Errorf("route domain name is required") + } + + return b.post(config, uriNet, uriRouteDomain) +} + +// DeleteRouteDomain removes a route domain. +func (b *BigIP) DeleteRouteDomain(name string) error { + return b.delete(uriNet, uriRouteDomain, name) +} + +// ModifyRouteDomain allows you to change any attribute of a route domain. +// Fields that can be modified are referenced in the RouteDomain struct. +func (b *BigIP) ModifyRouteDomain(name string, config *RouteDomain) error { + return b.patch(config, uriNet, uriRouteDomain, name) +} diff --git a/net_test.go b/net_test.go index bf493e8..1cdcf1e 100644 --- a/net_test.go +++ b/net_test.go @@ -323,62 +323,6 @@ func (s *NetTestSuite) TestModifyRoute() { assertRestCall(s, "PUT", "/mgmt/tm/net/route/default_route", `{"gw":"1.1.1.1"}`) } -func (s *NetTestSuite) TestRouteDomains() { - s.ResponseFunc = func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(`{ - "kind": "tm:net:route-domain:route-domaincollectionstate", - "selfLink": "https://localhost/mgmt/tm/net/route-domain?ver=11.5.1", - "items": [ - { - "kind": "tm:net:route-domain:route-domainstate", - "name": "0", - "partition": "Common", - "fullPath": "/Common/0", - "generation": 1, - "selfLink": "https://localhost/mgmt/tm/net/route-domain/~Common~0?ver=11.5.1", - "id": 0, - "strict": "enabled", - "vlans": [ - "/Common/http-tunnel", - "/Common/socks-tunnel" - ] - } - ] -}`)) - } - - routes, err := s.Client.RouteDomains() - - assert.Nil(s.T(), err) - assertRestCall(s, "GET", "/mgmt/tm/net/route-domain", "") - assert.Equal(s.T(), 1, len(routes.RouteDomains)) - assert.Equal(s.T(), 2, len(routes.RouteDomains[0].Vlans)) - assert.Equal(s.T(), "0", routes.RouteDomains[0].Name) -} - -func (s *NetTestSuite) TestCreateRouteDomain() { - err := s.Client.CreateRouteDomain("name", 1, false, "vlan1,vlan2") - - assert.Nil(s.T(), err) - assertRestCall(s, "POST", "/mgmt/tm/net/route-domain", `{"name":"name", "id":1, "vlans":["vlan1","vlan2"], "strict":"disabled"}`) -} - -func (s *NetTestSuite) TestDeleteRouteDomain() { - err := s.Client.DeleteRouteDomain("name") - - assert.Nil(s.T(), err) - assertRestCall(s, "DELETE", "/mgmt/tm/net/route-domain/name", "") -} - -func (s *NetTestSuite) TestModifyRouteDomain() { - route := &RouteDomain{Name: "name", ID: 1, Strict: "enabled"} - - err := s.Client.ModifyRouteDomain("name", route) - - assert.Nil(s.T(), err) - assertRestCall(s, "PUT", "/mgmt/tm/net/route-domain/name", `{"name":"name", "id": 1, "strict" : "enabled"}`) -} - func assertRestCall(s *NetTestSuite, method, path, body string) { assert.Equal(s.T(), method, s.LastRequest.Method) assert.Equal(s.T(), path, s.LastRequest.URL.Path) From be7b99785271d08611fc371e2e7cbee3224e9ba7 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 2 Jan 2026 16:58:55 +0100 Subject: [PATCH 18/25] Removing FipsCipherVersion from defaults (read-only attribute) --- sys.go | 1 - 1 file changed, 1 deletion(-) diff --git a/sys.go b/sys.go index b83aa3b..4584ace 100644 --- a/sys.go +++ b/sys.go @@ -1874,7 +1874,6 @@ func (b *BigIP) DeleteHTTPDConfig() error { AuthPamIdleTimeout: 1200, AuthPamValidateIp: "on", FastcgiTimeout: 300, - FipsCipherVersion: 0, HostnameLookup: "off", Include: "none", LogLevel: "warn", From d07040297a5d589469fb521a2b68f9aa05139b7d Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 2 Jan 2026 17:01:21 +0100 Subject: [PATCH 19/25] SSHD - removing omitempty for attributes that can contain 0 value --- sys.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys.go b/sys.go index 4584ace..a98f6fd 100644 --- a/sys.go +++ b/sys.go @@ -1752,8 +1752,8 @@ type SSHDConfig struct { Allow []string `json:"allow,omitempty"` Banner string `json:"banner,omitempty"` BannerText string `json:"bannerText,omitempty"` - FipsCipherVersion int `json:"fipsCipherVersion,omitempty"` - InactivityTimeout int `json:"inactivityTimeout,omitempty"` + FipsCipherVersion int `json:"fipsCipherVersion"` + InactivityTimeout int `json:"inactivityTimeout"` Include string `json:"include,omitempty"` LogLevel string `json:"logLevel,omitempty"` Login string `json:"login,omitempty"` From 7dc25de229244831b65d0a7a9d57662dd0c4d5a1 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 2 Jan 2026 18:01:04 +0100 Subject: [PATCH 20/25] HTTPD - removing omitempty for attributes that can contain 0 value --- sys.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sys.go b/sys.go index a98f6fd..5154263 100644 --- a/sys.go +++ b/sys.go @@ -1817,12 +1817,12 @@ type HTTPDConfig struct { LogLevel string `json:"logLevel,omitempty"` MaxClients int `json:"maxClients,omitempty"` RedirectHttpToHttps string `json:"redirectHttpToHttps,omitempty"` - RequestBodyMaxTimeout int `json:"requestBodyMaxTimeout,omitempty"` - RequestBodyMinRate int `json:"requestBodyMinRate,omitempty"` - RequestBodyTimeout int `json:"requestBodyTimeout,omitempty"` - RequestHeaderMaxTimeout int `json:"requestHeaderMaxTimeout,omitempty"` - RequestHeaderMinRate int `json:"requestHeaderMinRate,omitempty"` - RequestHeaderTimeout int `json:"requestHeaderTimeout,omitempty"` + RequestBodyMaxTimeout int `json:"requestBodyMaxTimeout"` + RequestBodyMinRate int `json:"requestBodyMinRate"` + RequestBodyTimeout int `json:"requestBodyTimeout"` + RequestHeaderMaxTimeout int `json:"requestHeaderMaxTimeout"` + RequestHeaderMinRate int `json:"requestHeaderMinRate"` + RequestHeaderTimeout int `json:"requestHeaderTimeout"` SslCaCertFile string `json:"sslCaCertFile,omitempty"` SslCertchainfile string `json:"sslCertchainfile,omitempty"` SslCertfile string `json:"sslCertfile,omitempty"` @@ -1832,9 +1832,9 @@ type HTTPDConfig struct { SslOcspDefaultResponder string `json:"sslOcspDefaultResponder,omitempty"` SslOcspEnable string `json:"sslOcspEnable,omitempty"` SslOcspOverrideResponder string `json:"sslOcspOverrideResponder,omitempty"` - SslOcspResponderTimeout int `json:"sslOcspResponderTimeout,omitempty"` - SslOcspResponseMaxAge int `json:"sslOcspResponseMaxAge,omitempty"` - SslOcspResponseTimeSkew int `json:"sslOcspResponseTimeSkew,omitempty"` + SslOcspResponderTimeout int `json:"sslOcspResponderTimeout"` + SslOcspResponseMaxAge int `json:"sslOcspResponseMaxAge"` + SslOcspResponseTimeSkew int `json:"sslOcspResponseTimeSkew"` SslPort int `json:"sslPort,omitempty"` SslProtocol string `json:"sslProtocol,omitempty"` SslVerifyClient string `json:"sslVerifyClient,omitempty"` From f296fd4daacaf7af8c999bd0a4f9957d25538dcf Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Fri, 2 Jan 2026 19:14:19 +0100 Subject: [PATCH 21/25] HTTPD - FipsCipherVersion removing omitempty for consistency --- sys.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys.go b/sys.go index 5154263..a9ff961 100644 --- a/sys.go +++ b/sys.go @@ -1811,7 +1811,7 @@ type HTTPDConfig struct { AuthPamIdleTimeout int `json:"authPamIdleTimeout,omitempty"` AuthPamValidateIp string `json:"authPamValidateIp,omitempty"` FastcgiTimeout int `json:"fastcgiTimeout,omitempty"` - FipsCipherVersion int `json:"fipsCipherVersion,omitempty"` + FipsCipherVersion int `json:"fipsCipherVersion"` HostnameLookup string `json:"hostnameLookup,omitempty"` Include string `json:"include,omitempty"` LogLevel string `json:"logLevel,omitempty"` From 0aef070dbadf5248f8baece9f121375f077f6ba9 Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Wed, 7 Jan 2026 15:59:36 +0100 Subject: [PATCH 22/25] Adjusting type structures to support zero values and empty lists where needed --- net.go | 6 +++--- sys.go | 34 +++++++++++++++++----------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/net.go b/net.go index f1f33a6..23384e0 100644 --- a/net.go +++ b/net.go @@ -779,10 +779,10 @@ type RouteDomain struct { Description string `json:"description,omitempty"` Strict string `json:"strict,omitempty"` Parent string `json:"parent,omitempty"` - Vlans []string `json:"vlans,omitempty"` - RoutingProtocol []string `json:"routingProtocol,omitempty"` + Vlans []string `json:"vlans,omitzero"` + RoutingProtocol []string `json:"routingProtocol,omitzero"` BwcPolicy string `json:"bwcPolicy,omitempty"` - ConnectionLimit int `json:"connectionLimit,omitempty"` + ConnectionLimit int `json:"connectionLimit"` FlowEvictionPolicy string `json:"flowEvictionPolicy,omitempty"` FwEnforcedPolicy string `json:"fwEnforcedPolicy,omitempty"` FwStagedPolicy string `json:"fwStagedPolicy,omitempty"` diff --git a/sys.go b/sys.go index a9ff961..51cf16a 100644 --- a/sys.go +++ b/sys.go @@ -1913,7 +1913,7 @@ func (b *BigIP) DeleteHTTPDConfig() error { type SnmpConfig struct { SysContact string `json:"sysContact,omitempty"` SysLocation string `json:"sysLocation,omitempty"` - AllowedAddresses []string `json:"allowedAddresses,omitempty"` + AllowedAddresses []string `json:"allowedAddresses,omitzero"` } // GetSnmpConfig retrieves the current SNMP configuration. @@ -2039,11 +2039,11 @@ type SnmpUser struct { Name string `json:"name,omitempty"` FullPath string `json:"fullPath,omitempty"` Access string `json:"access,omitempty"` - AuthPassword string `json:"authPassword,omitempty"` + AuthPassword string `json:"authPassword"` AuthProtocol string `json:"authProtocol,omitempty"` Description string `json:"description,omitempty"` OidSubset string `json:"oidSubset,omitempty"` - PrivacyPassword string `json:"privacyPassword,omitempty"` + PrivacyPassword string `json:"privacyPassword"` PrivacyProtocol string `json:"privacyProtocol,omitempty"` SecurityLevel string `json:"securityLevel,omitempty"` Username string `json:"username,omitempty"` @@ -2125,8 +2125,8 @@ type HaGroups struct { type HaGroupPool struct { Name string `json:"name,omitempty"` Attribute string `json:"attribute,omitempty"` - MinimumThreshold int `json:"minimumThreshold,omitempty"` - PercentUp int `json:"percentUp,omitempty"` + MinimumThreshold int `json:"minimumThreshold"` + PercentUp int `json:"percentUp"` SufficientThreshold string `json:"sufficientThreshold,omitempty"` Weight int `json:"weight,omitempty"` } @@ -2135,8 +2135,8 @@ type HaGroupPool struct { type HaGroupCluster struct { Name string `json:"name,omitempty"` Attribute string `json:"attribute,omitempty"` - MinimumThreshold int `json:"minimumThreshold,omitempty"` - PercentUp int `json:"percentUp,omitempty"` + MinimumThreshold int `json:"minimumThreshold"` + PercentUp int `json:"percentUp"` SufficientThreshold string `json:"sufficientThreshold,omitempty"` Weight int `json:"weight,omitempty"` } @@ -2145,8 +2145,8 @@ type HaGroupCluster struct { type HaGroupTrunk struct { Name string `json:"name,omitempty"` Attribute string `json:"attribute,omitempty"` - MinimumThreshold int `json:"minimumThreshold,omitempty"` - PercentUp int `json:"percentUp,omitempty"` + MinimumThreshold int `json:"minimumThreshold"` + PercentUp int `json:"percentUp"` SufficientThreshold string `json:"sufficientThreshold,omitempty"` Weight int `json:"weight,omitempty"` } @@ -2155,13 +2155,13 @@ type HaGroupTrunk struct { type HaGroup struct { Name string `json:"name,omitempty"` FullPath string `json:"fullPath,omitempty"` - ActiveBonus int `json:"activeBonus,omitempty"` + ActiveBonus int `json:"activeBonus"` Description string `json:"description,omitempty"` - Enabled bool `json:"enabled,omitempty"` - Disabled bool `json:"disabled,omitempty"` - Pools []HaGroupPool `json:"pools,omitempty"` - Clusters []HaGroupCluster `json:"clusters,omitempty"` - Trunks []HaGroupTrunk `json:"trunks,omitempty"` + Enabled bool `json:"enabled"` + Disabled bool `json:"disabled"` + Pools []HaGroupPool `json:"pools,omitzero"` + Clusters []HaGroupCluster `json:"clusters,omitzero"` + Trunks []HaGroupTrunk `json:"trunks,omitzero"` } // GetHaGroups returns a list of all HA Group configurations. @@ -2193,8 +2193,8 @@ func (b *BigIP) GetHaGroup(name string) (*HaGroup, error) { } func validateHaGroupState(config *HaGroup) error { - if config.Enabled && config.Disabled { - return fmt.Errorf(`"disabled" should not be specified with "enabled"`) + if config.Enabled == config.Disabled { + return fmt.Errorf(`"enabled" and "disabled" cannot have the same value`) } return nil } From c1b5d4e30a5e4e36db4c2e456bf1c69268f6ffba Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Tue, 17 Feb 2026 16:36:58 +0100 Subject: [PATCH 23/25] Adding more verbosity for db_var resource --- db_vars.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/db_vars.go b/db_vars.go index 5ed94dd..77300a8 100644 --- a/db_vars.go +++ b/db_vars.go @@ -2586,13 +2586,12 @@ type DBVariable struct { } // GetDBVariable returns a named DB variable. +// Returns the error from the API call if any error occurs. +// This allows callers to properly handle API unavailability (502/503) vs not found. func (b *BigIP) GetDBVariable(name string) (*DBVariable, error) { var dbVar DBVariable - err, ok := b.getForEntity(&dbVar, uriSys, uriDb, name) + err, _ := b.getForEntity(&dbVar, uriSys, uriDb, name) if err != nil { - if !ok { - return nil, nil - } return nil, err } From 6c7e5f0b866f373813485516ec4dea9c65aa6d8d Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Tue, 17 Feb 2026 16:40:30 +0100 Subject: [PATCH 24/25] Adding support for Device Name change and Self Device configuration --- device.go | 115 ++++++++++++++++++++++++++++ examples/device/main.go | 58 ++++++++++++++ examples/device/test_device_name.go | 80 +++++++++++++++++++ examples/device/test_device_self.go | 110 ++++++++++++++++++++++++++ examples/sys/main.go | 5 +- 5 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 examples/device/main.go create mode 100644 examples/device/test_device_name.go create mode 100644 examples/device/test_device_self.go diff --git a/device.go b/device.go index c243c82..56f4724 100644 --- a/device.go +++ b/device.go @@ -12,6 +12,7 @@ package bigip import ( "encoding/json" + "fmt" ) // LIC contains device license for BIG-IP system. @@ -365,3 +366,117 @@ func (b *BigIP) DevicegroupsDevices(name, rname string) (*Devicegroup, error) { return &devicegroup, nil } + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Device Self ///////////////// +////////////////////////////////////////////////////////////////////////////////////// + +type DeviceSelf struct { + Name string `json:"name,omitempty"` + MirrorIp string `json:"mirrorIp,omitempty"` + MirrorSecondaryIp string `json:"mirrorSecondaryIp,omitempty"` + ConfigsyncIp string `json:"configsyncIp,omitempty"` + MulticastInterface string `json:"multicastInterface"` + MulticastIp string `json:"multicastIp,omitempty"` + MulticastPort int `json:"multicastPort"` + UnicastAddress []UnicastAddress `json:"unicastAddress"` +} + +func (b *BigIP) CreateDeviceSelf(config *DeviceSelf) error { + return b.patch(config, uriCm, uriDiv, config.Name) +} + +func (b *BigIP) GetDeviceSelf(name string) (*DeviceSelf, error) { + var device DeviceSelf + err, _ := b.getForEntity(&device, uriCm, uriDiv, name) + if err != nil { + return nil, err + } + return &device, nil +} + +func (b *BigIP) ModifyDeviceSelf(config *DeviceSelf) error { + return b.patch(config, uriCm, uriDiv, config.Name) +} + +func (b *BigIP) DeleteDeviceSelf(name string) error { + defaultConfig := &DeviceSelf{ + MirrorIp: "any6", + MirrorSecondaryIp: "any6", + ConfigsyncIp: "none", + MulticastInterface: "", + MulticastIp: "any6", + MulticastPort: 0, + UnicastAddress: []UnicastAddress{}, + } + return b.patch(defaultConfig, uriCm, uriDiv, name) +} + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////// Device Name (Self) ///////////////// +////////////////////////////////////////////////////////////////////////////////////// + +// GetSelfDeviceName returns the name of the local BIG-IP device. +// It queries all devices and finds the one marked as selfDevice. +func (b *BigIP) GetSelfDeviceName() (string, error) { + devices, err := b.GetDevices() + if err != nil { + return "", err + } + + for _, d := range devices { + if d.SelfDevice == "true" { + return d.Name, nil + } + } + + return "", fmt.Errorf("no self device found") +} + +// CreateDeviceName renames the BIG-IP device to the specified target name. +func (b *BigIP) CreateDeviceName(target string) error { + currentName, err := b.GetSelfDeviceName() + if err != nil { + return fmt.Errorf("unable to get current device name: %v", err) + } + + config := &Devicename{ + Command: "mv", + Name: currentName, + Target: target, + } + + return b.post(config, uriCm, uriDiv) +} + +// ModifyDeviceName renames the BIG-IP device to the specified target name. +func (b *BigIP) ModifyDeviceName(target string) error { + currentName, err := b.GetSelfDeviceName() + if err != nil { + return fmt.Errorf("unable to get current device name: %v", err) + } + + config := &Devicename{ + Command: "mv", + Name: currentName, + Target: target, + } + + return b.post(config, uriCm, uriDiv) +} + +// DeleteDeviceName resets the BIG-IP device name to the default "bigip1". +func (b *BigIP) DeleteDeviceName() error { + currentName, err := b.GetSelfDeviceName() + if err != nil { + return fmt.Errorf("unable to get current device name: %v", err) + } + + config := &Devicename{ + Command: "mv", + Name: currentName, + Target: "bigip1", + } + + return b.post(config, uriCm, uriDiv) +} diff --git a/examples/device/main.go b/examples/device/main.go new file mode 100644 index 0000000..05b32f4 --- /dev/null +++ b/examples/device/main.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "os" + + "github.com/f5devcentral/go-bigip" +) + +func main() { + // Connect to the BIG-IP system. + // Replace with your actual BIG-IP credentials and hostname + config := &bigip.Config{ + //Address: "https://192.168.1.1", + Username: "admin", + //Password: "admin", + CertVerifyDisable: true, // Disable certificate verification for testing purposes + } + + config.Address = os.Getenv("BIGIP_ADDRESS") + if config.Address != "" { + fmt.Println("BIGIP_ADDRESS:", config.Address) + } else { + fmt.Println("BIGIP_ADDRESS is not set.") + } + + config.Password = os.Getenv("BIGIP_PASSWORD") + if config.Password != "" { + fmt.Println("BIGIP_PASSWORD:", config.Password) + } else { + fmt.Println("BIGIP_PASSWORD is not set.") + } + + f5 := bigip.NewSession(config) + + deviceSelfTesting := false + deviceNameTesting := true + + if deviceSelfTesting { + testDeviceSelfRead(f5) + testDeviceSelfCreate(f5) + testDeviceSelfRead(f5) + testDeviceSelfUpdate(f5) + testDeviceSelfRead(f5) + testDeviceSelfDelete(f5) + testDeviceSelfRead(f5) + } + if deviceNameTesting { + testDeviceNameRead(f5) + testDeviceNameCreate(f5) + testDeviceNameRead(f5) + testDeviceNameUpdate(f5) + testDeviceNameRead(f5) + testDeviceNameDelete(f5) + testDeviceNameRead(f5) + } + +} diff --git a/examples/device/test_device_name.go b/examples/device/test_device_name.go new file mode 100644 index 0000000..65a471e --- /dev/null +++ b/examples/device/test_device_name.go @@ -0,0 +1,80 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Device Name Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testDeviceNameRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Name Read Operation ===") + + fmt.Println("Getting Device Name...") + name, err := f5.GetSelfDeviceName() + if err != nil { + log.Printf("Error getting Device Name: %v", err) + return + } + + fmt.Printf(" Current Device Name: %s\n", name) +} + +func testDeviceNameCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Name Create Operation ===") + + targetName := "ltm02.f5lab.com" + + fmt.Printf("Renaming device to %s...\n", targetName) + err := f5.CreateDeviceName(targetName) + if err != nil { + log.Printf("Error creating Device Name: %v", err) + return + } + fmt.Printf("Device renamed successfully.\n") +} + +func testDeviceNameUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Name Update Operation ===") + + targetName := "ltm02-updated.f5lab.com" + + fmt.Printf("Renaming device to %s...\n", targetName) + err := f5.ModifyDeviceName(targetName) + if err != nil { + log.Printf("Error updating Device Name: %v", err) + return + } + fmt.Printf("Device renamed successfully.\n") +} + +func testDeviceNameDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Name Delete Operation ===") + + fmt.Println("Resetting device name to default (bigip1)...") + err := f5.DeleteDeviceName() + if err != nil { + log.Printf("Error deleting Device Name: %v", err) + return + } + fmt.Printf("Device name reset to default successfully.\n") + + // Verify default name after reset + fmt.Println("\nVerifying default name after reset...") + name, err := f5.GetSelfDeviceName() + if err != nil { + log.Printf("Error getting Device Name after reset: %v", err) + return + } + + fmt.Printf(" Device Name after reset: %s (expected: bigip1)\n", name) + if name == "bigip1" { + fmt.Println("Default name verified successfully.") + } else { + log.Println("Warning: Device name does not match expected default.") + } +} diff --git a/examples/device/test_device_self.go b/examples/device/test_device_self.go new file mode 100644 index 0000000..7bc7e9a --- /dev/null +++ b/examples/device/test_device_self.go @@ -0,0 +1,110 @@ +package main + +import ( + "fmt" + "log" + + "github.com/f5devcentral/go-bigip" +) + +///////////////////////////////////////////////////////////////////////////////// +////////////// Device Self Testing ///////////////// +///////////////////////////////////////////////////////////////////////////////// + +func testDeviceSelfRead(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Self Read Operation ===") + + fmt.Println("Getting Device Self...") + deviceSelf, err := f5.GetDeviceSelf("ltm02.f5lab.com") + if err != nil { + log.Printf("Error getting Device Self: %v", err) + return + } + + if deviceSelf != nil { + fmt.Printf("Retrieved Device Self:\n") + fmt.Printf(" Name: %s\n", deviceSelf.Name) + fmt.Printf(" Mirror IP: %s\n", deviceSelf.MirrorIp) + fmt.Printf(" Mirror Secondary IP: %s\n", deviceSelf.MirrorSecondaryIp) + fmt.Printf(" Configsync IP: %s\n", deviceSelf.ConfigsyncIp) + fmt.Printf(" Unicast Addresses:\n") + for i, addr := range deviceSelf.UnicastAddress { + fmt.Printf(" [%d] IP: %s, Port: %d, EffectiveIP: %s, EffectivePort: %d\n", + i, addr.IP, addr.Port, addr.EffectiveIP, addr.EffectivePort) + } + fmt.Println() + } +} + +func testDeviceSelfCreate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Self Create Operation ===") + + deviceSelf := &bigip.DeviceSelf{ + Name: "ltm02.f5lab.com", + MirrorIp: "any6", + MirrorSecondaryIp: "any6", + ConfigsyncIp: "10.1.131.38", + UnicastAddress: []bigip.UnicastAddress{ + { + IP: "10.1.131.38", + Port: 1026, + EffectiveIP: "10.1.131.38", + EffectivePort: 1026, + }, + { + IP: "management-ip", + Port: 1026, + EffectiveIP: "management-ip", + EffectivePort: 1026, + }, + }, + } + + fmt.Println("Creating Device Self...") + err := f5.CreateDeviceSelf(deviceSelf) + if err != nil { + log.Printf("Error creating Device Self: %v", err) + return + } + fmt.Printf("Device Self created successfully.\n") +} + +func testDeviceSelfUpdate(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Self Update Operation ===") + + deviceSelf := &bigip.DeviceSelf{ + Name: "ltm02.f5lab.com", + MirrorIp: "any6", + MirrorSecondaryIp: "any6", + ConfigsyncIp: "10.1.131.38", + UnicastAddress: []bigip.UnicastAddress{ + { + IP: "10.1.131.38", + Port: 1026, + EffectiveIP: "10.1.131.38", + EffectivePort: 1026, + }, + }, + } + + fmt.Println("Updating Device Self...") + err := f5.ModifyDeviceSelf(deviceSelf) + if err != nil { + log.Printf("Error updating Device Self: %v", err) + return + } + fmt.Printf("Device Self updated successfully.\n") +} + +func testDeviceSelfDelete(f5 *bigip.BigIP) { + fmt.Println("\n=== Testing Device Self Delete Operation ===") + + fmt.Println("Deleting (resetting) Device Self...") + err := f5.DeleteDeviceSelf("ltm02.f5lab.com") + if err != nil { + log.Printf("Error deleting Device Self: %v", err) + return + } + fmt.Printf("Device Self reset to defaults successfully.\n") + +} diff --git a/examples/sys/main.go b/examples/sys/main.go index 8d1721a..c7e9066 100644 --- a/examples/sys/main.go +++ b/examples/sys/main.go @@ -36,7 +36,7 @@ func main() { mgmtRouteTesting := false mgmtFwRuleTesting := false remoteRoleTesting := false - ldapAuthTesting := false + ldapAuthTesting := true authSourceTesting := false remoteUserTesting := false syslogTesting := false @@ -46,9 +46,10 @@ func main() { snmpConfigTesting := false snmpCommunitiesTesting := false snmpUsersTesting := false - haGroupTesting := true + haGroupTesting := false if mgmtRouteTesting { + testManagementRouteRead(f5) testManagementRouteCreation(f5) testManagementRouteRead(f5) testManagementRouteUpdate(f5) From f2dfaca963ed4c769531d2a9b3661ef2b3b2120c Mon Sep 17 00:00:00 2001 From: Ante Gavran Date: Tue, 17 Feb 2026 20:15:41 +0100 Subject: [PATCH 25/25] Allow zero values for db variables --- db_vars.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_vars.go b/db_vars.go index 77300a8..8d6b47d 100644 --- a/db_vars.go +++ b/db_vars.go @@ -2582,7 +2582,7 @@ var DefaultDBValues = map[string]interface{}{ type DBVariable struct { Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` + Value string `json:"value"` } // GetDBVariable returns a named DB variable.