TMSH
34 TopicsiControl REST Cookbook - Virtual Server (ltm virtual)
This cookbook lists selected ready-to-use iControl REST curl commands for virtual-server related resources. Each recipe consists of the curl command, it's tmsh equivalent, and sample output. In this cookbook, the following curl options are used. Option Meaning ______________________________________________________________________________________ -s Suppress progress meter. Handy when you want to pipe the output. ______________________________________________________________________________________ -k Allows "insecure" SSL connections. ______________________________________________________________________________________ -u Specify user ID and password. For the start, you should use the "admin" account that you normally use to access the Configuration Utility. When you specify the password at the same time, concatenate with ":". e.g., admin:admin. ______________________________________________________________________________________ -X <method> Specify the HTTP method. When omitted, the default is GET. In the REST framework, POST means create (tmsh create), PATCH means overwriting the existing resource with the data sent (tmsh modify), and PATCH is for merging (ditto). ______________________________________________________________________________________ -H <Header> Specify the request header. When you send (POST, PATCH, PUT) data, you need to tell the server that the data is in JSON format. i.e., -H "Content-Type: application/json. ______________________________________________________________________________________ -d 'data' The JSON data to send. Note that you need to quote the entire json blob, and each "name":"value" pairs must be quoted. When you have nested quotes, make sure you escape (\) them. Get information of the virtual <vs> tmsh list ltm <vs> curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs> Sample Output { kind: 'tm:ltm:virtual:virtualstate', name: 'vs', fullPath: 'vs', generation: 1109, selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs?ver=12.1.0', addressStatus: 'yes', autoLasthop: 'default', cmpEnabled: 'yes', connectionLimit: 0, description: 'TestData', destination: '/Common/192.168.184.226:80', enabled: true, gtmScore: 0, ipProtocol: 'tcp', mask: '255.255.255.255', mirror: 'disabled', mobileAppTunnel: 'disabled', nat64: 'disabled', pool: '/Common/vs-pool', poolReference: { link: 'https://localhost/mgmt/tm/ltm/pool/~Common~vs-pool?ver=12.1.0' }, rateLimit: 'disabled', rateLimitDstMask: 0, rateLimitMode: 'object', rateLimitSrcMask: 0, serviceDownImmediateAction: 'none', source: '0.0.0.0/0', sourceAddressTranslation: { type: 'automap' }, sourcePort: 'preserve', synCookieStatus: 'not-activated', translateAddress: 'enabled', translatePort: 'enabled', vlansDisabled: true, vsIndex: 4, rules: [ '/Common/irule' ], rulesReference: [ { link: 'https://localhost/mgmt/tm/ltm/rule/~Common~iRuleTest?ver=12.1.0' } ], policiesReference: { link: 'https://localhost/mgmt/tm/ltm/virtual/~Common~vs/policies?ver=12.1.0', isSubcollection: true }, profilesReference: { link: 'https://localhost/mgmt/tm/ltm/virtual/~Common~vs/profiles?ver=12.1.0', isSubcollection: true } } Get only specfic field of the virtual <vs> The naming convension for the parameters is slightly different from the ones on tmsh, so look for the familiar names in the GET response above. The example below queris the Default Pool (pool). tmsh list ltm <vs> pool curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs>?options=pool Sample Output { kind: 'tm:ltm:virtual:virtualstate', name: 'vs', fullPath: 'vs', generation: 1, selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs?options=pool&ver=12.1.1', pool: '/Common/vs-pool', poolReference: { link: 'https://localhost/mgmt/tm/ltm/pool/~Common~vs-pool?ver=12.1.1' } } Get all the information of the virtual <vs> Unlike the tmsh equivalent, iControl REST GET does not return the configuration information of the attached policies and profiles. To see them, use expandSubcollections tmsh list ltm <vs> curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs>?expandSubcollections=true Sample Output { "addressStatus": "yes", "autoLasthop": "default", "cmpEnabled": "yes", "connectionLimit": 0, "destination": "/Common/192.168.184.240:80", "enabled": true, "fullPath": "vs", "generation": 291, "gtmScore": 0, "ipProtocol": "tcp", "kind": "tm:ltm:virtual:virtualstate", "mask": "255.255.255.255", "mirror": "disabled", "mobileAppTunnel": "disabled", "name": "vs", "nat64": "disabled", "policiesReference": { "isSubcollection": true, "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~vs/policies?ver=13.1.0" }, "pool": "/Common/CentOS-all80", "poolReference": { "link": "https://localhost/mgmt/tm/ltm/pool/~Common~CentOS-all80?ver=13.1.0" }, "profilesReference": { "isSubcollection": true, "items": [ { "context": "all", "fullPath": "/Common/http", "generation": 291, "kind": "tm:ltm:virtual:profiles:profilesstate", "name": "http", "nameReference": { "link": "https://localhost/mgmt/tm/ltm/profile/http/~Common~http?ver=13.1.0" }, "partition": "Common", "selfLink": "https://localhost/mgmt/tm/ltm/virtual/~Common~vs/profiles/~Common~http?ver=13.1.0" }, { "context": "all", "fullPath": "/Common/tcp", "generation": 287, "kind": "tm:ltm:virtual:profiles:profilesstate", "name": "tcp", "nameReference": { "link": "https://localhost/mgmt/tm/ltm/profile/tcp/~Common~tcp?ver=13.1.0" }, "partition": "Common", "selfLink": "https://localhost/mgmt/tm/ltm/virtual/~Common~vs/profiles/~Common~tcp?ver=13.1.0" } ], "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~vs/profiles?ver=13.1.0" }, "rateLimit": "disabled", "rateLimitDstMask": 0, "rateLimitMode": "object", "rateLimitSrcMask": 0, "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vs?expandSubcollections=true&ver=13.1.0", "serviceDownImmediateAction": "none", "source": "0.0.0.0/0", "sourceAddressTranslation": { "type": "automap" }, "sourcePort": "preserve", "synCookieStatus": "not-activated", "translateAddress": "enabled", "translatePort": "enabled", "vlansDisabled": true, "vsIndex": 2 } Get stats of the virtual <vs> tmsh show ltm <vs> curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs>/stats Sample Output { kind: 'tm:ltm:virtual:virtualstats', generation: 1109, selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs/stats?ver=12.1.0', entries: { 'https://localhost/mgmt/tm/ltm/virtual/vs/~Common~vs/stats': { nestedStats: { kind: 'tm:ltm:virtual:virtualstats', selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs/~Common~vs/stats?ver=12.1.0', entries: { 'clientside.bitsIn': { value: 12880 }, 'clientside.bitsOut': { value: 34592 }, 'clientside.curConns': { value: 0 }, 'clientside.evictedConns': { value: 0 }, 'clientside.maxConns': { value: 2 }, 'clientside.pktsIn': { value: 26 }, 'clientside.pktsOut': { value: 26 }, 'clientside.slowKilled': { value: 0 }, 'clientside.totConns': { value: 6 }, cmpEnableMode: { description: 'all-cpus' }, cmpEnabled: { description: 'enabled' }, csMaxConnDur: { value: 37 }, csMeanConnDur: { value: 29 }, csMinConnDur: { value: 17 }, destination: { description: '192.168.184.226:80' }, 'ephemeral.bitsIn': { value: 0 }, 'ephemeral.bitsOut': { value: 0 }, 'ephemeral.curConns': { value: 0 }, 'ephemeral.evictedConns': { value: 0 }, 'ephemeral.maxConns': { value: 0 }, 'ephemeral.pktsIn': { value: 0 }, 'ephemeral.pktsOut': { value: 0 }, 'ephemeral.slowKilled': { value: 0 }, 'ephemeral.totConns': { value: 0 }, fiveMinAvgUsageRatio: { value: 0 }, fiveSecAvgUsageRatio: { value: 0 }, tmName: { description: '/Common/vs' }, oneMinAvgUsageRatio: { value: 0 }, 'status.availabilityState': { description: 'available' }, 'status.enabledState': { description: 'enabled' }, 'status.statusReason': { description: 'The virtual server is available' }, syncookieStatus: { description: 'not-activated' }, 'syncookie.accepts': { value: 0 }, 'syncookie.hwAccepts': { value: 0 }, 'syncookie.hwSyncookies': { value: 0 }, 'syncookie.hwsyncookieInstance': { value: 0 }, 'syncookie.rejects': { value: 0 }, 'syncookie.swsyncookieInstance': { value: 0 }, 'syncookie.syncacheCurr': { value: 0 }, 'syncookie.syncacheOver': { value: 0 }, 'syncookie.syncookies': { value: 0 }, totRequests: { value: 4 } } } } } } Change one of the configuration options of the virtual <vs> The command below changes the Description field of the virtual ("description" in tmsh and iControl REST). tmsh modify ltm virtual <vs> description "Hello World!" curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs> \ -X PATCH -H "Content-Type: application/json" \ -d '{"description": "Hello World!"}' Sample Output { kind: 'tm:ltm:virtual:virtualstate', name: 'vs', ... description: 'Hello World!', <==== Changed. ... } Disable the virtual <vs> The command syntax is same as above: To change the state of a virtual from "enabled" to "disabled", send "disabled":true. For enabling the virtual, use "enabled":true. Note that the Boolean type true/false does not require quotations. tmsh modify ltm virtual <vs> disabled curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs> \ -X PATCH -H "Content-Type: application/json" \ -d '{"disabled": true}' \ Sample Output { kind: 'tm:ltm:virtual:virtualstate', name: 'vs', fullPath: 'vs', ... disabled: true, <== Changed ... } Add another iRule to <vs> When the virtual has iRules already attached, you need to send the existing ones too along with the additional one. For example, to add /Common/testRule1 to the virtual with /Common/testRule1, specify both in an array (square brackets). Note that the /Common/testRule2 iRule object should be already created. tmsh modify ltm virtual <vs> rules {testRule1 testRule2} curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs> \ -X PATCH -H "Content-Type: application/json" \ -d '{"rules": ["/Common/testRule1", "/Common/testRule2"] }' Sample Output { kind: 'tm:ltm:virtual:virtualstate', name: 'vs', fullPath: 'vs', ... rules: [ '/Common/test1', '/Common/test2' ], <== Changed rulesReference: [ { link: 'https://localhost/mgmt/tm/ltm/rule/~Common~test1?ver=12.1.1' }, { link: 'https://localhost/mgmt/tm/ltm/rule/~Common~test2?ver=12.1.1' } ], ... } Create a new virtual <vs> You can create a skeleton virtual by specifying only Destination Address and Mask. The remaining parameters such as profiles are set to default. You can later modify the parameters by PATCH-ing. tmsh create ltm virtual <vs> destination <ip:port> mask <ip> curl -sku admin:admin -X POST -H "Content-Type: application/json" \ -d '{"name": "vs", "destination":"192.168.184.230:80", "mask":"255.255.255.255"}' \ https://<host>/mgmt/tm/ltm/virtual Sample Output { kind: 'tm:ltm:virtual:virtualstate', name: 'vs', partition: 'Common', fullPath: '/Common/vs', ... destination: '/Common/192.168.184.230:80', <== Created ... mask: '255.255.255.255', <== Created ... } Create a new virtual <vs> with a lot of parameters You can specify all the essential parameters upon creation. This example creates a new virtual with pool, default persistence profile, profiles, iRule, and source address translation. The call fails if any of the parameters conflicts. For example, you cannot specify "Cookie Persistence" without specifying appropriate profiles. If you do not specify any profile, it falls back to the default fastL4 , which is not compatible with Cookie Persistence. tmsh create ltm virtual <vs> destination <ip:port> mask <ip> pool <pool> persist replace-all-with { cookie } profiles add { tcp http clientssl } rules { <rule> } source-address-translation { type automap } curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual -H "Content-Type: application/json" -X POST -d '{"name": "vs", \ "destination": "10.10.10.10:10", \ "mask": "255.255.255.255", \ "pool": "CentOS-all80", \ "persist": [ {"name": "cookie"} ], \ "profilesReference": {"items": [ {"context": "all", "name": "http"}, {"context": "all", "name": "tcp"}, {"context": "clientside", "name": "clientssl"}] }, \ "rules": [ "ShowVersion" ], \ "sourceAddressTranslation": {"type": "automap"} }' Sample Output { "addressStatus": "yes", "autoLasthop": "default", "cmpEnabled": "yes", "connectionLimit": 0, "destination": "/Common/10.10.10.10:10", "enabled": true, "fullPath": "/Common/test", "generation": 592, "gtmScore": 0, "ipProtocol": "tcp", "kind": "tm:ltm:virtual:virtualstate", "mask": "255.255.255.255", "mirror": "disabled", "mobileAppTunnel": "disabled", "name": "vs", "nat64": "disabled", "partition": "Common", "persist": [ { "name": "cookie", "nameReference": { "link": "https://localhost/mgmt/tm/ltm/persistence/cookie/~Common~cookie?ver=13.1.0" }, "partition": "Common", "tmDefault": "yes" } ], "policiesReference": { "isSubcollection": true, "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~test/policies?ver=13.1.0" }, "pool": "/Common/CentOS-all80", "poolReference": { "link": "https://localhost/mgmt/tm/ltm/pool/~Common~CentOS-all80?ver=13.1.0" }, "profilesReference": { "isSubcollection": true, "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~test/profiles?ver=13.1.0" }, "rateLimit": "disabled", "rateLimitDstMask": 0, "rateLimitMode": "object", "rateLimitSrcMask": 0, "rules": [ "/Common/ShowVersion" ], "rulesReference": [ { "link": "https://localhost/mgmt/tm/ltm/rule/~Common~ShowVersion?ver=13.1.0" } ], "selfLink": "https://localhost/mgmt/tm/ltm/virtual/~Common~test?ver=13.1.0", "serviceDownImmediateAction": "none", "source": "0.0.0.0/0", "sourceAddressTranslation": { "type": "automap" }, "sourcePort": "preserve", "synCookieStatus": "not-activated", "translateAddress": "enabled", "translatePort": "enabled", "vlansDisabled": true, "vsIndex": 52 } Delete a virtual <vs> tmsh delete ltm virtual <vs> curl -sku admin:admin https://192.168.226.55/mgmt/tm/ltm/virtual/<vs> -X DELETE Sample Output No output (just 200 OK and no response body) References curl.1 the man page curl Releases and Downloads ... including the port for Windows Jason Rahm's "Demystifying iControl REST" series(DevCentral) -- This is Part I of 7 at the time of this article. iControl REST API reference (DevCentral) iControl® REST API User Guide (DevCentral) -- Link is for 12.1. Search for the older versions.17KViews3likes13Commentsimport f5!
We are super excited to announce a preview of the F5 SDK, a set of client tools which facilitate consuming some of our popular APIs/Services, and currently consists of the following: f5-sdk-python - a new python client library f5-cli - a remote CLI that is built-off the f5-sdk-python Getting existential, as the old saying goes, the most valuable commodity in the world is time. Our short time here on earth is finite, the average lifespan is only around 70-71 years (according to Wikipedia), and if we’re not doing everything we can to try to save you every sliver of time possible, we’re not doing one of our fiduciary duties as a technology company. As software developers know, code is the ultimate embodiment of saving time (after all, a “for loop” is nothing but a modern marvel that repeats something dutifully to save time). So, as a convenience to developers and system integrators, vendors / platforms provide Software Development Kits (SDKs) to help them save even more time on that last mile. Developers/Integrators also hate having to re-invent the wheel (which often translates to code “not related” to their business logic) and look to leverage something that already exists. In hardware, you may leverage drivers. In software, you import libraries/modules. In this case, these SDK client libraries provide objects in their own language to help abstract you from low level implementation details like having to know the service’s exact URLs, authentication mechanisms, transport required (ex. REST, SOAP, GRPC), file download/uploads, etc. and let you focus on your business logic.Here at F5, we rely on SDKs like the Broadcom SDK, Octeon SDK, Intel DPDK (for hardware), Cloud SDKs (for software), etc. and the age-old value of offering an SDK hasn’t gone anywhere. SDKs are getting released and making headlines every day. ex. https://www.engadget.com/2020/01/24/boston-dynamics-robotic-dog-spot-sdk/ We’ve actually had an unofficial SDK for a while with a project called the f5-common-python. It was a “common” library for the core underlying component in one our integrations (LBaaS driver for Openstack) but, when looking at it from a more current end-user’s perspective, there were some significant enough changes we wanted to implement that mandated a fresh start. Nevertheless, it gathered a fair amount of traction and the value of a generic reusable client library was a great pattern we wanted to officially expand upon. And now what’s this CLI?I thought it was all about the API now and clients didn't matter? Yes, the main value is obviously in the API itself since that is what scales and where you deliver your main value proposition. However, there is still a client user experience (UX) to your APIs and doing everything you can to optimize / enhance the overall client experience is key to firing on all cylinders. SDKs/CLIs are like the client browser UX to your service … but for programmatic access and automation. From articles like below, you can see some of the traditional values of having a CLI component. https://www.zdnet.com/article/good-news-for-developers-the-cli-is-back/ "CLI is arguably better for ad hoc tasksorquick exploratory operations since it is more human-readable." Source: https://nordicapis.com/the-return-of-the-cli-clis-being-used-by-api-related-companies/ The familiar CLI UX is a common entry point for everyone, whether it is developers testing/exploring your API or network/system admins automating common tasks. And don’t you already have a CLI called TMSH? Well, this is a little different. Everyone today knows how useful *remote* CLIs like AWS’s aws-cli, Azure’s az, Google's gcloud, Openstack’s osc, Kubernete’s kubectl, etc. are in consuming and developing against a service or platform. Instead of SSH’ing to a single device, remote CLIs use transports/protocols like HTTP or GRPC to talk to a service’s remote APIs. The f5-cli, inspired by popular public cloud shells (which are all built on python SDKs) will focus on providing the same ease and convenience to some our most popular APIs/Services and aims to be demand/use case driven (high usage APIs vs. exposing the entire portfolio of APIs). For example, the Automation Tool Chain APIs. For some of you that may have not heard about them yet, those are some of the powerful declarative APIs that allow you to provision entire configurations in a single API call / JSON payload. Application Services 3 (AS3) = Virtual Services Declarative Onboarding (DO) = System related config like licensing, provisioning, networking,clustering, etc. Telemetry Streaming (TS) – Analytics, Logging That would normally require 10s to 100s of imperative API calls.As with any API(s), however, there is some amount of overhead (authentication, async transaction handling, best practices, etc.) in consuming them that can be optimized and captured via client libraries. Probably the most common use case: "I want to create a Virtual Service" (using AS3). Putting the CLI in debug, you can see some of the low level details the SDK is handling: Managing Authentication (dependencies on other APIs) Managing Tasks for Async Operations Retry Attempt logic Even convenience functions like installing the required extension package (an RPM) if not already installed > export F5_SDK_LOG_LEVEL=DEBUG > f5 bigip extension service create --component as3 --install-component --declaration as3.json user1@desktop: f5-cli $ f5 bigip extension service create --component as3 --declaration as3.json --install-component 2020-03-10 00:17:49,779 - f5sdk.bigip.mgmt_client - DEBUG: Performing ready check using port 8443 2020-03-10 00:17:49,810 - f5sdk.bigip.mgmt_client - DEBUG: Logging in using user + password 2020-03-10 00:17:49,810 - f5sdk.bigip.mgmt_client - DEBUG: Getting authentication token 2020-03-10 00:17:49,814 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/authn/login 2020-03-10 00:17:50,009 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:17:50,010 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: PATCH /mgmt/shared/authz/tokens/EEPEH4IXVKX7TVP27NECH76VQJ 2020-03-10 00:17:50,131 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:17:50,134 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/iapp/package-management-tasks 2020-03-10 00:17:50,252 - f5sdk.utils.http_utils - DEBUG: HTTP response: 202 Accepted 2020-03-10 00:17:50,253 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: GET /mgmt/shared/iapp/package-management-tasks/11fc9258-a2c2-495b-8687-2e427fd64091 2020-03-10 00:17:50,363 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:17:59,798 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:01,605 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:01,608 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:03,814 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:03,815 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:05,678 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:05,680 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:07,905 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:07,908 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:09,642 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:09,644 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:11,707 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:11,709 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:13,915 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:13,918 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:16,050 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:16,052 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:18,042 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:18,044 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:20,623 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:20,625 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:22,823 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:22,826 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:24,864 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:24,866 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:26,624 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:26,625 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:28,922 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:28,924 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:31,068 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:31,070 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/file-transfer/uploads/f5-appsvcs-3.17.1-1.noarch.rpm 2020-03-10 00:18:31,503 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:31,508 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/iapp/package-management-tasks 2020-03-10 00:18:32,618 - f5sdk.utils.http_utils - DEBUG: HTTP response: 202 Accepted 2020-03-10 00:18:32,618 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: GET /mgmt/shared/iapp/package-management-tasks/a7c839c3-b340-4497-a520-437a237aef30 2020-03-10 00:18:32,727 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:33,733 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: GET /mgmt/shared/iapp/package-management-tasks/a7c839c3-b340-4497-a520-437a237aef30 2020-03-10 00:18:33,865 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:33,866 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: GET /mgmt/shared/appsvcs/declare 2020-03-10 00:18:37,066 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: GET /mgmt/shared/appsvcs/declare 2020-03-10 00:18:37,877 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/iapp/package-management-tasks 2020-03-10 00:18:37,998 - f5sdk.utils.http_utils - DEBUG: HTTP response: 202 Accepted 2020-03-10 00:18:37,999 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: GET /mgmt/shared/iapp/package-management-tasks/093dfa5a-eb52-4002-a3d8-88d3edf4ad71 2020-03-10 00:18:38,116 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK 2020-03-10 00:18:38,125 - f5sdk.utils.http_utils - DEBUG: Making HTTP request: POST /mgmt/shared/appsvcs/declare 2020-03-10 00:18:56,120 - f5sdk.utils.http_utils - DEBUG: HTTP response: 200 OK { "declaration": { "Sample_app_sec_Tenant": { "HTTPS_Service": { "Pool1": { "class": "Pool", "members": [ { "serverAddresses": [ "10.0.1.11" ], "servicePort": 80 } ], "monitors": [ "http" ] }, "WAFPolicy": { "class": "WAF_Policy", "ignoreChanges": true, "url": "https://raw.githubusercontent.com/f5devcentral/f5-asm-policy-templates/master/owasp_ready_template/owasp-no-auto-tune-v1.1.xml" }, "class": "Application", "serviceMain": { "class": "Service_HTTPS", "policyWAF": { "use": "WAFPolicy" }, "pool": "Pool1", "redirect80": false, "serverTLS": { "bigip": "/Common/clientssl" }, "snat": "auto", "virtualAddresses": [ "0.0.0.0" ] }, "template": "https" }, "class": "Tenant" }, "class": "ADC", "controls": { "archiveTimestamp": "2020-03-10T00:18:55.759Z" }, "id": "autogen_3a78cbd8-7aa4-4fb6-8db9-3e458f583513", "label": "ASM_VS1", "remark": "ASM_VS1", "schemaVersion": "3.0.0", "updateMode": "selective" }, "results": [ { "code": 200, "host": "localhost", "lineCount": 28, "message": "success", "runTime": 16658, "tenant": "Sample_app_sec_Tenant" } ] } That’s actually quite a bit of work offloaded to accelerate getting you up and going on an API. As our portfolio expands to offer more and more products and services, this will hopefully save our users some extra time. DISCLAIMER:it’s in public preview and we have many enhancements already planned F5 SDK Documentation: https://clouddocs.f5.com/sdk/f5-sdk-python/ Github repo: https://github.com/f5devcentral/f5-sdk-python F5 CLI Documentation: https://clouddocs.f5.com/sdk/f5-cli/ Github repo: https://github.com/f5devcentral/f5-cli Please take look soon and provide any feedback by filing an issue on Github repos.727Views3likes1CommentiControl REST Cookbook - Virtual Server Profile (LTM Virtual Profiles)
This cookbook lists selected ready-to-use iControl REST curl commands for virtual serverprofilerelated resources (the tmsh command xxx ltm virtual <vs> profiles not xxx ltm profile ). Each recipe consists of the curl command, it's tmsh equivallent, and sample output (default hidden: toggle "Expand to see sample output" (may not work on some browsers)). Please refer toiControl REST Cookbook - Virtual Server (ltm virtual) for the list of curl options. Get the profiles of the virtual <vss> list ltm virtual <vss> profiles curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vss>/profiles Expand to see sample output (may not work on some browsers) { "items": [ { "context": "all", "fullPath": "/Common/http", "generation": 405, "kind": "tm:ltm:virtual:profiles:profilesstate", "name": "http", "partition": "Common", "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vss/profiles/~Common~http?ver=13.1.0" }, { "context": "all", "fullPath": "/Common/tcp", "generation": 405, "kind": "tm:ltm:virtual:profiles:profilesstate", "name": "tcp", "partition": "Common", "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vss/profiles/~Common~tcp?ver=13.1.0" } ], "kind": "tm:ltm:virtual:profiles:profilescollectionstate", "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vss/profiles?ver=13.1.0" } Show only the specific profile <profile> of the virtual <vss> list ltm virtual <vss> profiles { <profile> } curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vss>/profiles/<profile> Expand to see sample output (may not work on some browsers) { "context": "all", "fullPath": "http", "generation": 454, "kind": "tm:ltm:virtual:profiles:profilesstate", "name": "http", "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vss/profiles/http?ver=13.1.0" } Add theprofile <profile> to the virtual <vss> modify ltm virtual <vss> profiles add { <profile> } curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vss>/profiles \ -X POST -H "Content-Type: application/json" \ -d '{"name":"<profile>"}' Expand to see sample output (may not work on some browsers) { "context": "clientside", "fullPath": "clientssl", "generation": 409, "kind": "tm:ltm:virtual:profiles:profilesstate", "name": "clientssl", "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vss/profiles/clientssl?ver=13.1.0" } You will get an error if the specified profile is not compatible with the existing ones. For example, you cannot add clientssl to a virtual with fastL4 (if you have created a virtual without explicitly specifying the profiles, it defaults to fastL4). Expand to see sample output (may not work on some browsers) { "code":400, "message":"01070734:3: Configuration error: Found disallowed profile on /Common/vss: Not Any Of (FastL4 Profile, FastHTTP Profile)", "errorStack":[],"apiError":3 } Replace all the existing profiles of the virtual <vss> Unlike the above, the endpoint is not .../<vss>/profiles but .../<vss>. The method is PATCH because you are overwriting the existing components of the virtual. The data is nested deeply: Each profile is represented as an object {key:value, ...}; the profiles are stored in a list []; and the profiles list is the value for the key 'items' in the 'profilesReference'. modify ltm virtual <vss> profiles replace-all-with { clientssl http } curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vss> \ -X PATCH -H "Content-Type: application/json" \ -d '{"profilesReference":{"items":[{"name":"clientssl"}, {"name":"http"}]}}' Expand to see sample output (may not work on some browsers) { "addressStatus": "yes", "autoLasthop": "default", "cmpEnabled": "yes", "connectionLimit": 0, "destination": "/Common/192.168.184.242:80", "enabled": true, "fullPath": "vss", "generation": 422, "gtmScore": 0, "ipProtocol": "tcp", "kind": "tm:ltm:virtual:virtualstate", "mask": "255.255.255.255", "mirror": "disabled", "mobileAppTunnel": "disabled", "name": "vss", "nat64": "disabled", "policiesReference": { "isSubcollection": true, "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~vss/policies?ver=13.1.0" }, "pool": "/Common/CentOS-all80", "poolReference": { "link": "https://localhost/mgmt/tm/ltm/pool/~Common~CentOS-all80?ver=13.1.0" }, "profilesReference": { "isSubcollection": true, "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~vss/profiles?ver=13.1.0" }, "rateLimit": "disabled", "rateLimitDstMask": 0, "rateLimitMode": "object", "rateLimitSrcMask": 0, "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vss?ver=13.1.0", "serviceDownImmediateAction": "none", "source": "0.0.0.0/0", "sourceAddressTranslation": { "type": "automap" }, "sourcePort": "preserve", "synCookieStatus": "not-activated", "translateAddress": "enabled", "translatePort": "enabled", "vlansDisabled": true, "vsIndex": 44 } You can add more fields to the request. e.g., context and partition. {"name":"clientssl", "context":"clientside", "partition":"Common"} Changing the protocol and profile of the virtual <vss> To change either protocol or profile, you need to change both in one shot because some profiles are not compatible with some protocols ( ip-protocol in tmsh; e.g., Any, TCP or UDP). modify ltm virtual <vss> ip-protocol udp profiles replace-all-with { fastL4 } curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vss> \ -X PATCH -H "Content-Type: application/json" \ -d '{"ipProtocol":"udp", "profilesReference":{"items":[{"name":"fastL4"}]}}' Expand to see sample output (may not work on some browsers) { "addressStatus": "yes", "autoLasthop": "default", "cmpEnabled": "yes", "connectionLimit": 0, "destination": "/Common/192.168.184.242:80", "enabled": true, "fullPath": "vss", "generation": 448, "gtmScore": 0, "ipProtocol": "udp", "kind": "tm:ltm:virtual:virtualstate", "mask": "255.255.255.255", "mirror": "disabled", "mobileAppTunnel": "disabled", "name": "vss", "nat64": "disabled", "policiesReference": { "isSubcollection": true, "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~vss/policies?ver=13.1.0" }, "pool": "/Common/CentOS-all80", "poolReference": { "link": "https://localhost/mgmt/tm/ltm/pool/~Common~CentOS-all80?ver=13.1.0" }, "profilesReference": { "isSubcollection": true, "link": "https://localhost/mgmt/tm/ltm/virtual/~Common~vss/profiles?ver=13.1.0" }, "rateLimit": "disabled", "rateLimitDstMask": 0, "rateLimitMode": "object", "rateLimitSrcMask": 0, "selfLink": "https://localhost/mgmt/tm/ltm/virtual/vss?ver=13.1.0", "serviceDownImmediateAction": "none", "source": "0.0.0.0/0", "sourceAddressTranslation": { "type": "automap" }, "sourcePort": "preserve", "synCookieStatus": "not-activated", "translateAddress": "enabled", "translatePort": "enabled", "vlansDisabled": true, "vsIndex": 44 } Deleting the profile <profile> from the virtual <vss> modify ltm virtual <vss> delete { <profile> } curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vss>/profiles/<profile> -X DELETE Expand to see sample output (may not work on some browsers) No output Remove all the profiles from the virtual <vss> There is no 'all' keyword in iControl REST. Use an empty object to indicate 'no data'. In this case, the profiles are represented as a list, so use the empty list []. modify ltm virtual <vss> delete { all } curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vss> \ -X PATCH -H "Content-Type: application/json" \ -d '{"profiles":[]}}' Note that the call will leave one profile because a virtual should have at least one profile.3.9KViews2likes0CommentsWorking with MasterKeys
Author : Arnaud Fauvel (Obiane – Orange Group – France) Introduction : As explained in “SOL9420: Installing a UCS file containing an encrypted passphrase”: Passphrases used for configuration items, such as monitors, profiles, and Secure Sockets Layer (SSL) keys, are stored in the configuration file in encrypted format. The BIG-IP system uses a hardware-key encrypted master key to encrypt and decrypt passphrases contained in the configuration file. These hardware-key encrypted passwords can be identified with a prefix of $M$. Prior to BIG-IP 11.5.0, only the passphrases used for SSL private keys are stored in encrypted format. In BIG-IP 11.5.0 and later, passphrases used for other configuration objects, such as monitors and profiles, are also stored in encrypted format. To complete the description, the master key unit is: - Different on each standalone device but shared within a cluster. - Different on each vCMP guest and is dissociated from vCMP host. How to modify MasterKey As explained in the SOL it’s possible to modify the master key of the device with the following command: f5mku -r There are two bad behaviors of this command: - If there are already configuration items with encrypted parameter, the bigip is unable to load the configuration. We have to remove SSL key passphrase encryption as explained in the SOL14302: Replacing a VIPRION chassis that has one or more blades installed. - On a vCMP Host or Guest after executing the command the device become unstable. F5 support provides me the following commands explained in the following “SOL13508: ConfigSync operations fail to complete and generate a validation message”: modify /sys crypto master-key prompt-for-password This command is magic: - A new masterkey is defined based on a provided password - Saving the configuration automatically re-encrypts any encrypted-SSL-key passphrases, using the new master key, prior to saving them in the configuration file. - It works on BIGIP or vCMP guest. Considering the masterkey of the vCMP Host it’s not so simple. The precedent command can be used but all vCMP Guest will be unable to retrieve their master key: notice mcpd[6230]: 01071029:5: Cannot open unit key store notice mcpd[6230]: 01070406:5: Removed publication with publisher id ha_table_publish warning mcpd[6230]: 012a0004:4: halStorageRead: unable to read storage on this platform The masterkey of the vCMP host seems to be used for a unit key store shared with all vCMP Guest. You will find bellow a scheme which tries to represent the master key architecture: How to restore archive configuration without removing SSL key passphrase encryption The “SOL9420: Installing a UCS file containing an encrypted passphrase” is not really satisfactory because as explained before the f5mku -r commands doesn’t work with vCMP guest. But by using the magic commands it’s works very well J. 1. After installing a BIGIP or vCMP Guest, log in on to de device and force the master key with a password by typing the following command: # tmsh # modify /sys crypto master-key prompt-for-password enter password: password again: # save /sys config Saving running configuration... /config/bigip.conf /config/bigip_base.conf /config/bigip_user.conf 2. Save regulary the configuration (using iApp or remote expect script): save /sys ucs passphrase 3. Log in to the RMA BIG-IP system command line. 4. Install the master key with the password you enter in step 1 to the RMA BIG-IP system using the following command syntax: # tmsh # modify /sys crypto master-key prompt-for-password enter password: password again: # save /sys config Saving running configuration... /config/bigip.conf /config/bigip_base.conf /config/bigip_user.conf 5.Restore the UCS file to the RMA BIG-IP system using the following command syntax: tmsh load sys ucs .ucs no-license7.2KViews1like2CommentsConfiguring Decision Logging for the F5 BIG-IP Global Traffic Manager
I was working on a GTM solution and with my limited lab I wanted to make sure that the decisions that F5 BIG-IP Global Traffic Manager made at the wideIP and pool level were as evident in the logs as they were consistent in my test results. It turns out there are some fancy little checkboxes in the wideIP configuration that you can check to enable such logs. You might notice, however, that upon enabling these checkboxes the logs are nowhere to be found. This is because there are other necessary steps. You need to configure a few objects to get those logs flowing. Log Publisher The first object is the log publisher. For as much detail as flows in the decision logging, I’d highly recommend using an HSL profile to log to a remote server, but for the purposes of testing I used the local syslog. This can also be done with tmsh. sys log-config publisher gtm_decision_logging { destinations { local-syslog { } } } DNS Logging Profile Next, create a DNS logging profile, make sure to select the Log Publisher you created in the previous step. For testing purpose I enabled the log responses and query ID as well, but those are disabled by default. This also can be created in tmsh. ltm profile dns-logging gtm_decision_logging { enable-response-logging yes include-query-id yes log-publisher gtm_decision_logging } Custom DNS Profile Now create a custom DNS profile. The only custom properties necessary are at the bottom of the profile where you enable logging and select the logging profile. This can also be configured in tmsh. ltm profile dns gtm_decision_logging { app-service none defaults-from dns enable-logging yes log-profile gtm_decision_logging } Apply the DNS Profile Now that all the objects are created, you can reference the DNS profile in the listener. in tmsh, you can modify the listener by adding the profile or if one already exists, replacing it. modify gtm listener gtmlistener profiles replace-all-with { udp_gtm_dns gtm_decision_logging } Log Details Once you have all the objects configured and the DNS profile referenced in your listener, the logging should be hitting /var/log/ltm now. For this first query, the emea pool is selected, but there is no probe data for my primary load balancing method, and the none alternate method skips to the fallback, which uses the configured fallback IP to respond to the client. 2015-06-03 08:54:21 ltm1.dc.test qid 11139 from 192.168.102.1#64536: view none: query: my.example.com IN A + (192.168.102.5%0) 2015-06-03 08:54:21 ltm1.dc.test qid 11139 from 192.168.102.1#64536 [my.example.com A] [round robin selected pool (emea)] [pool member check succeeded (vip3:192.168.103.12) - pool member state is available (green)] [QoS skipped pool member (vip3:192.168.103.12) - path has unmeasured RTT] [pool member check succeeded (vip4:192.168.103.13) - pool member state is available (green)] [QoS skipped pool member (vip4:192.168.103.13) - path has unmeasured RTT] [failed to select pool member by preferred load balancing method] [Using none load balancing method] [failed to select pool member by alternate load balancing method] [selected configured fallback IP] 2015-06-03 08:54:21 ltm1.dc.test qid 11139 to 192.168.102.1#64536: [NOERROR qr,aa,rd] response: my.example.com. 30 IN A 192.168.103.99; In this second request, the emea pool is again selected, but now there is probe data, so the pool member is selected as appropriate. 2015-06-03 08:55:43 ltm1.dc.test qid 6201 from 192.168.102.1#61503: view none: query: my.example.com IN A + (192.168.102.5%0) 2015-06-03 08:55:43 ltm1.dc.test qid 6201 from 192.168.102.1#61503 [my.example.com A] [round robin selected pool (emea)] [pool member check succeeded (vip3:192.168.103.12) - pool member state is available (green)] [QoS selected pool member (vip3:192.168.103.12) - QoS score (2082756232) is higher] [pool member check succeeded (vip4:192.168.103.13) - pool member state is available (green)] [QoS skipped pool member (vip4:192.168.103.13) from two pool members with equal scores] [QoS selected pool member (vip3:192.168.103.12)] 2015-06-03 08:55:43 ltm1.dc.test qid 6201 to 192.168.102.1#61503: [NOERROR qr,aa,rd] response: my.example.com. 30 IN A 192.168.103.12; In this final request, the americas pool is selected, but there is no valid topology score for the pool members, so query is refused. 2015-06-03 08:55:53 ltm1.dc.test qid 23580 from 192.168.102.1#59437: view none: query: my.example.com IN A + (192.168.102.5%0) 2015-06-03 08:55:53 ltm1.dc.test qid 23580 from 192.168.102.1#59437 [my.example.com A] [round robin selected pool (americas)] [pool member check succeeded (vip1:192.168.103.10) - pool member state is available (green)] [QoS selected pool member (vip1:192.168.103.10) - QoS score (0) is higher] [pool member check succeeded (vip2:192.168.103.11) - pool member state is available (green)] [QoS skipped pool member (vip2:192.168.103.11) from two pool members with equal scores] [QoS selected pool member (vip1:192.168.103.10)] [topology load balancing method failed to select pool member (vip1:192.168.103.10) - topology score is 0] [failed to select pool member by preferred load balancing method] [selected configured option Return To DNS] 2015-06-03 08:55:53 ltm1.dc.test qid 23580 to 192.168.102.1#59437: [REFUSED qr,rd] response: empty Yeah, yeah, skip all that and give me the good stuff If you want to test it quickly, you can save the config below to a file (/var/tmp/gtmlogging.txt in this example) and then merge it in. Finally, modify the wideIP and listener and you’re good to go! ### ### configuration: /var/tmp/gtmlogging.txt ### sys log-config publisher gtm_decision_logging { destinations { local-syslog { } } } ltm profile dns-logging gtm_decision_logging { enable-response-logging yes include-query-id yes log-publisher gtm_decision_logging } ltm profile dns gtm_decision_logging { app-service none defaults-from dns enable-logging yes log-profile gtm_decision_logging } ### ### Merge Command ### tmsh load sys config merge file /var/tmp/gtmlogging.txt ### ### Modify wideIP and Listener ### tmsh modify gtm wideip my.example.com load-balancing-decision-log-verbosity { pool-member-selection pool-member-traversal pool-selection pool-traversal } tmsh modify gtm listener gtmlistener profiles replace-all-with { udp_gtm_dns gtm_decision_logging } tmsh save sys config2KViews1like3CommentsMigrating to iSeries From Older Platforms: It's About Time
Migrating to iSeries From Older Platforms: It’s About Time Imagine this situation: It’s a great day because the new F5 gear has come in and you can take advantage of the years of software and hardware advancements that have been included in the latest iSeries models. Decommissioning old gear is a great way to save space, power, and administrative costs. Applications can run faster, smoother, more reliably. The future is bright with the flexibility of TurboFlex for use case-oriented FPGA acceleration at line rate. There’s a great opportunity to clean up old configurations, getting rid of redundant virtual servers and profiles which were necessary on older gear due to performance limitations. Overall, change can be a really good time to update troubleshooting and shake down the whole incident resolution process. There’s still a little bit of unease that comes with change. Moving applications to the new gear means migration. Migration can mean a large change window and the potential for regressions and having to back out the change. Memories of migrations past (and the accompanying all-nighters) cause shudders when scheduling a maintenance window. Copy and paste errors, incomplete certificate bundles, missing files, and incompatible interface numbering are all hallmarks of a long outage during a platform migration. What if there was a way to reduce the work and increase the accuracy of a migration? How much would you pay? What about removing any doubts that migration could be done within a maintenance window? What about now? Ladies and Gentlemen, allow me to introduce the platform-migrate flag, taking the load ucs command into new territory. Best thing about it, if you’ve got TMOS 12.1.1 or later, it’sbuilt right in! Amazing! (Not as amazing as winning the lottery, but go with it for the moment…) What is ‘platform-migrate’? What does it do? Will it make a difference? The full command we’re discussing is ‘ load ucs platform-migrate ’. Here’s a quick overview of how easy it is to use the command once you’ve uploaded the source User Configuration Set (UCS) to the new platform. This screenshot is from a real-time video capture: The configuration import took about 75 seconds (might have been faster without my slow typing). The UCS used was rather simple (only a few nodes, virtual servers, profiles), so it becomes a Your Mileage May Vary (YMMV) situation with larger configurations. However, the process is easily documented so administrators of all levels can easily follow the process and ensure it completes properly for each migration. This screenshot shows the migration of a configuration from a BIG-IP 8800 (D88) to a vCMP guest (Z101), demonstrating a leap-frog of two full generations of BIG-IP hardware in one quick keystroke. The actual platform migration takes a very short time, but the upfront preparation, as with any activity related to upgrading or migrating, is the key to making this work smoothly. There are several prerequisites to accomplish, but these are not any different than setting up a new device or vCMP guest For those familiar with some of the other flags for the load ucs command, platform-migrate is a combination of the no-license and no-platform-check along with the capability to ignore the L2 configuration stanzas which may not import properly when moving from one platform to another. A not-so-secret secret: Some of the interface numbers are different between platforms, meaning the L2 configuration, at best, needs to be renumbered, though most commonly recreated. Here’s a basic list of the things it does and does not do: Included in platform-migrate Not included in platform-migrate Functionality in ‘no-license’ and ‘no-platform-check’ (see: AskF5 K14096 and K16795) Migration of unencrypted UCS files from 10.2.4+ and encrypted UCS files with user-set passphrases from 11.0+ to 12.1.1talk-26316 Ignorance of the L2 portion of the configuration, meaning differences in interface numbering don’t block configurations from loading Automatic import and necessary conversion of configuration items such as: Virtual Server information Node information Profile information Any db variables that have been manually set Certificate bundles Monitors/EAV/Alerting configuration (alertd) Remote Authentication Credentials (LDAP, etc.) Migration of basic L2 configuration, as listed at K8240512, such as: VLANs (both host and guest) Management and Self-IP addresses Config sync trust group information Trunk group configuration Migration of module configurations other than those for LTM and GTM Migration of 10.2.4 configurations which are encrypted (because they are encrypted based on the appliance’s master key, not a user-specified passphrase)talk-26321 Reestablishing Device Trust relationships vCMP Host configuration (there’s a different method for that, contained in K13132, though it restores everything, including guests which may or may not be wanted) For platform-migrateto work well, there are a few prerequisites that must be accomplished on the destination system: 1) Prepare destination platform (provision vCMP if migrating to a vCMP guest) 2) Configure (and publish, for vCMP) VLANs 3 Ensure that Self-IP addresses and VLANs have the same name on the source and destination platforms If using vCMP, create guest and assign VLANs to guest 4) Copy UCS from source BIG-IP to destination platform 5)Run migration command on new platform 6) Make source BIG-IP stop serving traffic 7) Test virtuals and other config on destination platform If you are migrating from other platforms, such as from an older appliance to a iSeries appliance or from an older appliance to a BIG-IP Virtual Edition (VE), the initial configuration is similar to the migration to a vCMP guest, listed above. You need to set up Self-IP addresses, a Management address, and have VLANs that are similarly named for the migration to work properly. The platform-migrate option is best used with configurations that are relatively straightforward but would be time-consuming to replicate by hand. This can be a time saver with configurations that have hundreds of nodes, monitors, profiles, and VIPs. Sure, you could recreate them to some degree by using a script such as “create ltm pool members” on DevCentral, but that doesn’t really do much for specific config items for each node. Summary: platform-migrate saves time, period. A Word On Encrypted UCS Files… Since UCS files contain quite a bit of important information about a BIG-IP, such as user credentials, SSL Certificates, etc., it’s important to store them in as secure a manner as possible. UCS files can be encrypted with a passphrase which allows them to be stored on an accessible server for quick restorations or reversions to prior configurations. Because they contain all the files needed to recreate a BIG-IP, they’re very convenient. Just one small item that must be considered: UCS files from before 11.0 cannot be moved from one machine to another if they contain SSL certificates generated on a BIG-IP. Makes platform migration a bit more difficult without a portable archive. Why? Between 10.x and 11.0, a change was made as to the source of the encryption passphrase used to create SSL certificates. Before 11.0, the passphrase was set by the machine itself, using the machine-generated master key of the device. This solution was convenient in that you didn’t need to write down or remember the passphrase to any SSL certificates from those devices, since the machine itself was the passphrase, so to speak. Unfortunately, with that convenience came an inability to use the UCS on any other device. After 11.0, you could specify your own passphrase, thereby removing some of the portability issues that came with encrypting UCS files. Where does that leave the platform-migrate process? If you plan to migrate a device from 10.2.4 to 12.1.1+, you must create an unencrypted UCS archive to do so. This action is well-documented in the overview of UCS files available on AskF5.com. It also involves having the source platform up and running to do so. If you are working with 11.0+, you can specify a user-defined passphrase when you export and import the UCS as documented in the overview of the platform-migrate capability. Are There Other Options To Migrate From One Platform To Another? There most certainly are other options for migration. BIG-IP’s reputation as a “Swiss Army Knife” extends into the possible methods of moving from one platform to another. Similar to a Swiss Army Knife, each one of these methods is great for solving a specific problem or concern but may not cover off every instance or use case that may occur during a migration. Here are some of the other methods possible: Using a Single Configuration File (SCF) with Tarball of Additional Files:K13408 The SCF was originally developed as an easy way to present an overview of a configuration in one place, enabling easier auditing and change tracking using tools likediff and the like. It is entirely ASCII text and includes unencrypted hash blocks for device certificates as well as sections which have encrypted tokens, such as the password hashes for the different users on the device. As such, it’s not ideal for insecure storage, such as on unauthenticated file shares or FTP, but is great to use for simple search-and-replace operations to move configurations or configuration stanzas. With some scripting, SCF templates could be used to create new configurations almost dynamically. Pros Cons Can be used to migrate from one platform to another; has nothing that links it to a specific device aside from hostnames Configuration is laid out in a plain-text file which can be printed for offline review Templates can be created by copying and pasting or merging stanzas into new configurations via scripting or other command-line text manipulation Platform-to-Platform migration requires hand editing of the SCF and other files in the accompanying archive which opens the process to errors Does not handle differences in L2 configuration, such as a different management IP address but instead will try to overwrite the running config instead, possibly causing IP address collisions if on the same VLAN as the source device Device trust for sync groups will have to be rebuilt as with other methods Doesn’t include SSL keys, license information, external monitors Any device trust keys are included in the SCF in an unencrypted manner Cannot be secured with a passphrase for encrypted storage As is mentioned in the platform-migrate overview document, SCF files may be useful for simple configurations or where additional modules beyond LTM and DNS(ne é GTM) need to be migrated to the new platform. Loading a UCS From the Source Platform Directly on the New Platform:K13132 As mentioned above, the UCS was originally meant to be a great way to archive configurations and ensure that everything needed to restore a device is present in one place. Loading a UCS by itself onto a BIG-IP device without the platform-migrate flagdoes have the issue of interface numbering incompatibility when moving from one platform to another. Pros Cons Ensures all important files are collected in a single archive so they are not missing at startup after being loaded File list can be modified to add customized files into the UCS archive that are not part of the standard manifest Can move configuration from all modules including the supporting data stores and policies Encrypted UCS files either need to have a user-defined passphrase or no passphrase for successful migration (changes between 10.x and 11.0, as noted above) Requires hand editing of configuration files Using the “no-license” flag (formerly known as the RMA option) requires console access because the appliance or guest must be restored to factory defaults before the new UCS can be applied (K16795) Using Config Sync with an Existing Device to Copy Configuration Items There is a feature within the device service clustering and Device Group capabilities known as ConfigSync. When you’ve created a cluster of BIG-IPs, VEs, or vCMP guests to share the workload of an application, this is a great way to create high-availability across platforms of different speeds and capabilities. In the background, configuration changes to the clustered applications are replicated automatically, ensuring that all devices supporting that application are in lock-step and there won’t be any discrepancy between them as far as performance and capabilities are concerned. Synchronizing configuration objects you say? Wouldn’t that be a great way to replicate a configuration from one platform to another? Configurations are copied in the background and ensured that they are kept up to date from trusted sources– that sounds almost ideal! Well, no. It really isn’t ideal. ConfigSync has its limitations, and for good reason. If allof the items in a UCS or SCF were synchronized to another device, the Management IP and its related settings, the hostname, and other information that is best used when its unique, would be overwritten, causing address collisions and general mayhem. Device trust between the hosts needs to be established for synchronization to work. This may be a manageable situation if you’re setting up 2 discrete devices with different hostnames, etc. where there could be a period where both platforms could run simultaneously without issue. If you’re decommissioning an old device and want to keep the hostname and IP addresses on a new device, you’l have a more difficult time, since the trust certificates are X.509 certificates with the hostname in them. Aside from that mess, the list of things that, by design, don’t synchronize between devices is essentially the list of items you’d have to recreate on a new vCMP guest or other platform regardless of the method you used to migrate. Add on top of that the remaining need to import SSL certificates and other config files by hand which would be in the UCS or SCF and ConfigSync isn’t really the answer. I’m not going to have aPro and Con section here, because it’s not the right tool for platform migration. I did want to mention it in the interest of completeness and of avoiding a large mistake which could eat up a maintenance window quite quickly. There’s a link in the Resources section which has all the items that don’t get synchronized, if you’re interested. Manually Entering Configuration Pros Cons It’s a great use of a weekend to bond with your co-workers, especially one that’s sunny and warm The satisfaction of knowing you and your team typed in each and every node of the several thousand nodes and profiles that make up each of your data centers… You find yourself not wanting it to end! Seriously? You wouldn’t be looking at any automation or other ways to make things faster if this was they way you wanted things to run. I’m not judging you, but someone else may be… The Best Way To Migrate Configurations From Platform To Platform Is…? The one that ticks as many boxes as it can. There is no single right way to do it, similar to programming in Perl (cue the Programming Language Flame Wars, episode 27 ). The most important part of any migration is preparation. Make some dry runs if possible and time the dry runs of the migrations for more accurate change window estimation. Regardless of how configuration and consolidation happens, the fact is that the new iSeries provides many advancements that make getting off of older devices is more appealing than ever. That, and they’re fast. Really, really fast. Resources Replacing or migrating a BIG-IP or BIG-IQ hosted on a CSP (discusses considerations for moving a VE to a physical device including licensing) Overview of vCMP configuration considerations Device Trust Certificate overview Overview of Single Configuration Files Overview of User Configuration Sets Creating LTM Pool Members in tmsh Overview of platform-migrate3.3KViews1like0Comments