devops

803 Topics
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Beta_MetaNav\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Beta_Footer\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[],\"name\":\"TagPage\",\"props\":{},\"url\":\"https://community.f5.com/tag/devops\"}}})":{"__typename":"ComponentRenderResult","html":"
 
 
 
 
 

\"F5 Β©2024 F5, Inc. All rights reserved.
Trademarks Policies Privacy California Privacy Do Not Sell My Personal Information
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Beta_Footer\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[],\"name\":\"TagPage\",\"props\":{},\"url\":\"https://community.f5.com/tag/devops\"}}})":{"__typename":"ComponentRenderResult","html":" "}},"componentScriptGroups({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[],\"name\":\"TagPage\",\"props\":{},\"url\":\"https://community.f5.com/tag/devops\"}}})":{"__typename":"ComponentRenderResult","html":"
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageListTabs\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageListTabs-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageView/MessageViewInline\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/Pager/PagerLoadMore\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/customComponent/CustomComponent\"]})":[{"__ref":"CachedAsset:text:en_US-components/customComponent/CustomComponent-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/OverflowNav\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageUnreadCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageViewCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageViewCount-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/kudos/KudosCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/kudos/KudosCount-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRepliesCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1751558338022"}],"cachedText({\"lastModified\":\"1751558338022\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1751558338022"}]},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"User:user:-1":{"__typename":"User","id":"user:-1","entityType":"USER","eventPath":"community:zihoc95639/user:-1","uid":-1,"login":"Former Member","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"dd-MMM-yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US","en-GB","fr-FR","de-DE","ja-JP","pt-PT","pt-BR","es-ES"]},"repliesSortOrder":{"__typename":"InheritableStringSettingWithPossibleValues","key":"config.user_replies_sort_order","value":"DEFAULT","localValue":"DEFAULT","possibleValues":["DEFAULT","LIKES","PUBLISH_TIME","REVERSE_PUBLISH_TIME"]}},"deleted":false},"CachedAsset:pages-1751560861975":{"__typename":"CachedAsset","id":"pages-1751560861975","value":[{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.MvpProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/mvp-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.AdvocacyProgram","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/advocacy-program","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetHelp.NonCustomer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/non-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Customer","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-customer","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"WorkstreamsPage","type":"COMMUNITY","urlPath":"/workstreams","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetInvolved","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.Learn","type":"COMMUNITY","urlPath":"/c/how-do-i/learn","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1739501996000,"localOverride":null,"page":{"id":"Test","type":"CUSTOM","urlPath":"/custom-test-2","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetHelp.Community","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/community","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetInvolved.ContributeCode","type":"COMMUNITY","urlPath":"/c/how-do-i/get-involved/contribute-code","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.Learn.AboutIrules","type":"COMMUNITY","urlPath":"/c/how-do-i/learn/about-irules","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetHelp.F5Support","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/f5-support","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetHelp","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI.GetHelp.SecurityIncident","type":"COMMUNITY","urlPath":"/c/how-do-i/get-help/security-incident","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1751560861975,"localOverride":null,"page":{"id":"HowDoI","type":"COMMUNITY","urlPath":"/c/how-do-i","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}","userBanned":"We're sorry, but you have been banned from using this site.","userBannedReason":"You have been banned for the following reason: {reason}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:theme:customTheme1-1751558338886":{"__typename":"CachedAsset","id":"theme:customTheme1-1751558338886","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["custom"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"android-chrome-512x512-1748534255255.png","imageLastModified":"1748534256856","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"F5-devCentral-HR-color-reverse-1750868999153.png","imageLastModified":"1750869001512","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"fluid","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_PAGE_CONTENT","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"5px","borderRadius":"5px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"14px","paddingXHero":"42px","fontStyle":"NORMAL","fontWeight":"500","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"#0072B0","primaryBgHoverColor":"hsl(201.10000000000002, 100%, 29.3%)","primaryBgActiveColor":"hsl(201.10000000000002, 100%, 24.2%)","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px #0072B0, 0 0 0 4px rgba(0, 114, 176, 0.2)","secondaryTextColor":"var(--lia-bs-white)","secondaryTextHoverColor":"var(--lia-bs-white)","secondaryTextActiveColor":"var(--lia-bs-white)","secondaryBgColor":"#0072B0","secondaryBgHoverColor":"hsl(201.10000000000002, 100%, 29.3%)","secondaryBgActiveColor":"hsl(201.10000000000002, 100%, 24.2%)","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px #0072B0, 0 0 0 4px rgba(0, 114, 176, 0.2)","tertiaryTextColor":"#0072B0","tertiaryTextHoverColor":"hsl(201.10000000000002, 100%, 32.8%)","tertiaryTextActiveColor":"hsl(201.10000000000002, 100%, 31.1%)","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"rgba(0, 114, 176, 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid rgba(0, 114, 176, 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px #0072B0, 0 0 0 4px rgba(0, 114, 176, 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-300)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px #0072B0, 0 0 0 4px rgba(0, 114, 176, 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"DARK","sideContent":"DARK","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-primary)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"500","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","defaultMessageFontFamily":"var(--lia-bs-font-family-base)","forumColor":"#0C5C8D","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#62C026","blogColor":"#730015","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#C20025","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#F3704B","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#EE4B5B","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#491B62","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#949494","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0072B0","secondary":"#333333","bodyText":"#222222","bodyBg":"#F5F5F5","info":"#1D9CD3","success":"#62C026","warning":"#FFD651","danger":"#C20025","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#C20025","#081B85","#009639","#B3C6D7","#7CC0EB","#F29A36","#B2D7EB","#66AFD7","#007ABC","#343434","#0E6EB9","#0072B0"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Neusa Next Pro Wide Bold","fontStyle":"NORMAL","fontWeight":"700","h1FontSize":"30px","h2FontSize":"25px","h3FontSize":"20px","h4FontSize":"18px","h5FontSize":"16px","h6FontSize":"16px","lineHeight":"1.1","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":null,"imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"14px","defaultMessageHeaderMarginBottom":"10px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"14px","specialMessageHeaderMarginBottom":"10px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","tableBgColor":"transparent","tableBorderColor":"var(--lia-bs-gray-700)","tableBorderStyle":"solid","tableCellPaddingX":"5px","tableCellPaddingY":"5px","tableTextColor":"var(--lia-bs-body-color)","tableVerticalAlign":"middle","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Proxima Nova A Medium","fontStyleBase":"NORMAL","fontWeightBase":"500","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.2","fontSizeBase":"15px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"13px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Proxima Nova A Medium","styles":[{"style":"NORMAL","weight":"500","__typename":"FontStyleData"}],"assetNames":["ProximaNovaAMedium-normal-500.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"Neusa Next Pro Wide Bold","styles":[{"style":"NORMAL","weight":"700","__typename":"FontStyleData"}],"assetNames":["NeusaNextProWideBold-normal-700.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1751558338022","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1751558338022","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/tags/TagPage-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-pages/tags/TagPage-1751558338022","value":{"tagPageTitle":"Tag:\"{tagName}\" | {communityTitle}","tagPageForNodeTitle":"Tag:\"{tagName}\" in \"{title}\" | {communityTitle}","name":"Tags Page","tag":"Tag: {tagName}"},"localOverride":false},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bi04Ni01UWNVTmk\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bi04Ni01UWNVTmk","mimeType":"image/svg+xml"},"Category:category:top":{"__typename":"Category","id":"category:top","entityType":"CATEGORY","displayId":"top","nodeType":"category","depth":0,"title":"Top","shortTitle":"Top"},"Category:category:CrowdSRC":{"__typename":"Category","id":"category:CrowdSRC","entityType":"CATEGORY","displayId":"CrowdSRC","nodeType":"category","depth":1,"title":"CrowdSRC","description":"The category for community sourced content including CodeShare and Community Articles.","avatar":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bi04Ni01UWNVTmk\"}"},"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:top"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:zihoc95639"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"theme":{"__ref":"Theme:customTheme1"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"tagPolicies":{"__typename":"TagPolicies","canSubscribeTagOnNode":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.labels.action.corenode.subscribe_labels.allow.accessDenied","key":"error.lithium.policies.labels.action.corenode.subscribe_labels.allow.accessDenied","args":[]}},"canManageTagDashboard":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.labels.action.corenode.admin_labels.allow.accessDenied","key":"error.lithium.policies.labels.action.corenode.admin_labels.allow.accessDenied","args":[]}}}},"CachedAsset:quilt:f5.prod:pages/tags/TagPage:category:CrowdSRC-1751558337035":{"__typename":"CachedAsset","id":"quilt:f5.prod:pages/tags/TagPage:category:CrowdSRC-1751558337035","value":{"id":"TagPage","container":{"id":"Common","headerProps":{"removeComponents":["community.widget.bannerWidget"],"__typename":"QuiltContainerSectionProps"},"items":[{"id":"tag-header-widget","layout":"ONE_COLUMN","bgColor":"var(--lia-bs-white)","showBorder":"BOTTOM","sectionEditLevel":"LOCKED","columnMap":{"main":[{"id":"tags.widget.TagsHeaderWidget","__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"},{"id":"messages-list-for-tag-widget","layout":"ONE_COLUMN","columnMap":{"main":[{"id":"messages.widget.messageListForNodeByRecentActivityWidget","props":{"viewVariant":{"type":"inline","props":{"useUnreadCount":true,"useViewCount":true,"useAuthorLogin":true,"clampBodyLines":3,"useAvatar":true,"useBoardIcon":false,"useKudosCount":true,"usePreviewMedia":true,"useTags":false,"useNode":true,"useNodeLink":true,"useTextBody":true,"truncateBodyLength":-1,"useBody":true,"useRepliesCount":true,"useSolvedBadge":true,"timeStampType":"conversation.lastPostingActivityTime","useMessageTimeLink":true,"clampSubjectLines":2}},"panelType":"divider","useTitle":false,"hideIfEmpty":false,"pagerVariant":{"type":"loadMore"},"style":"list","showTabs":true,"tabItemMap":{"default":{"mostRecent":true,"mostRecentUserContent":false,"newest":false},"additional":{"mostKudoed":true,"mostViewed":true,"mostReplies":false,"noReplies":false,"noSolutions":false,"solutions":false}}},"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"}],"__typename":"QuiltContainer"},"__typename":"Quilt"},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1751558338022","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:quiltWrapper:f5.prod:Common:1751558337547":{"__typename":"CachedAsset","id":"quiltWrapper:f5.prod:Common:1751558337547","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"#343434","items":[{"id":"custom.widget.GainsightShared","props":{"widgetVisibility":"signedInOnly","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Beta_MetaNav","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"community.widget.navbarWidget","props":{"showUserName":false,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","linkFontWeight":"700","controllerHighlightColor":"#F29A36","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkFontSize":"15px","linkBoxShadowHover":"none","backgroundOpacity":1,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","linkTextBorderBottom":"none","hamburgerColor":"var(--lia-nav-controller-icon-color)","brandLogoHeight":"48px","linkLetterSpacing":"normal","linkBgHoverColor":"transparent","collapseMenuDividerOpacity":0.16,"paddingBottom":"10px","dropdownPaddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"unset","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","linkJustifyContent":"center","linkColor":"var(--lia-bs-white)","collapseMenuDividerBg":"var(--lia-nav-link-color)","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-body-color)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-white)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-white)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","linkPaddingX":"10px","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","paddingTop":"10px","linkPaddingY":"5px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.1)","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkBgColor":"transparent","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-white)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-white)"},"links":{"sideLinks":[],"logoLinks":[],"mainLinks":[{"children":[{"linkType":"INTERNAL","id":"migrated-link-1","params":{"boardId":"TechnicalForum","categoryId":"Forums"},"routeName":"ForumBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-2","params":{"boardId":"WaterCooler","categoryId":"Forums"},"routeName":"ForumBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-0","params":{"categoryId":"Forums"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-4","params":{"boardId":"codeshare","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-5","params":{"boardId":"communityarticles","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-3","params":{"categoryId":"CrowdSRC"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-7","params":{"boardId":"TechnicalArticles","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"article-series","params":{"boardId":"article-series","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"security-insights","params":{"boardId":"security-insights","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-8","params":{"boardId":"DevCentralNews","categoryId":"Articles"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-6","params":{"categoryId":"Articles"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-10","params":{"categoryId":"CommunityGroups"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"migrated-link-11","params":{"categoryId":"F5-Groups"},"routeName":"CategoryPage"}],"linkType":"INTERNAL","id":"migrated-link-9","params":{"categoryId":"GroupsCategory"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-12","params":{"boardId":"Events","categoryId":"top"},"routeName":"EventBoardPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-13","params":{"boardId":"Suggestions","categoryId":"top"},"routeName":"IdeaBoardPage"},{"children":[],"linkType":"EXTERNAL","id":"Common-external-link","url":"https://community.f5.com/c/how-do-i","target":"SELF"}]},"className":"QuiltComponent_lia-component-edit-mode__lQ9Z6","showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.bannerWidget","props":{"backgroundColor":"#343434","visualEffects":{"showBottomBorder":false},"backgroundImageProps":{"backgroundSize":"COVER","backgroundPosition":"CENTER_CENTER","backgroundRepeat":"NO_REPEAT"},"fontColor":"var(--lia-bs-white)"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"#343434","linkHighlightColor":"#FFFFFF","visualEffects":{"showBottomBorder":true},"backgroundOpacity":100,"linkTextColor":"#FFFFFF"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"var(--lia-bs-body-color)","items":[{"id":"custom.widget.Beta_Footer","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Tag_Manager_Helper","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Consent_Blackbar","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:component:custom.widget.GainsightShared-en-us-1751558364843":{"__typename":"CachedAsset","id":"component:custom.widget.GainsightShared-en-us-1751558364843","value":{"component":{"id":"custom.widget.GainsightShared","template":{"id":"GainsightShared","markupLanguage":"HTML","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"Shared functions for Gainsight integration","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.GainsightShared","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"TEXTHTML","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Shared functions for Gainsight integration","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Beta_MetaNav-en-us-1751558364843":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_MetaNav-en-us-1751558364843","value":{"component":{"id":"custom.widget.Beta_MetaNav","template":{"id":"Beta_MetaNav","markupLanguage":"HANDLEBARS","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_MetaNav","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Beta_Footer-en-us-1751558364843":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_Footer-en-us-1751558364843","value":{"component":{"id":"custom.widget.Beta_Footer","template":{"id":"Beta_Footer","markupLanguage":"HANDLEBARS","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"DevCentralΒ΄s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_Footer","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"DevCentralΒ΄s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Tag_Manager_Helper-en-us-1751558364843":{"__typename":"CachedAsset","id":"component:custom.widget.Tag_Manager_Helper-en-us-1751558364843","value":{"component":{"id":"custom.widget.Tag_Manager_Helper","template":{"id":"Tag_Manager_Helper","markupLanguage":"HANDLEBARS","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Tag_Manager_Helper","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Consent_Blackbar-en-us-1751558364843":{"__typename":"CachedAsset","id":"component:custom.widget.Consent_Blackbar-en-us-1751558364843","value":{"component":{"id":"custom.widget.Consent_Blackbar","template":{"id":"Consent_Blackbar","markupLanguage":"HTML","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Consent_Blackbar","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"TEXTHTML","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1751558338022","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagsHeaderWidget-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagsHeaderWidget-1751558338022","value":{"tag":"{tagName}","topicsCount":"{count} {count, plural, one {Topic} other {Topics}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1751558338022","value":{"title@userScope:other":"Recent Content","title@userScope:self":"Contributions","title@board:FORUM@userScope:other":"Recent Discussions","title@board:BLOG@userScope:other":"Recent Blogs","emptyDescription":"No content to show","MessageListForNodeByRecentActivityWidgetEditor.nodeScope.label":"Scope","title@instance:1706288370055":"Content Feed","title@instance:1743095186784":"Most Recent Updates","title@instance:1704317906837":"Content Feed","title@instance:1743095018194":"Most Recent Updates","title@instance:1702668293472":"Community Feed","title@instance:1743095117047":"Most Recent Updates","title@instance:1704319314827":"Blog Feed","title@instance:1743095235555":"Most Recent Updates","title@instance:1704320290851":"My Contributions","title@instance:1703720491809":"Forum Feed","title@instance:1743095311723":"Most Recent Updates","title@instance:1703028709746":"Group Content Feed","title@instance:VTsglH":"Content Feed"},"localOverride":false},"Category:category:Forums":{"__typename":"Category","id":"category:Forums","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:TechnicalForum":{"__typename":"Forum","id":"board:TechnicalForum","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:WaterCooler":{"__typename":"Forum","id":"board:WaterCooler","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Articles":{"__typename":"Category","id":"category:Articles","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:TechnicalArticles":{"__typename":"Tkb","id":"board:TechnicalArticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:DevCentralNews":{"__typename":"Tkb","id":"board:DevCentralNews","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:GroupsCategory":{"__typename":"Category","id":"category:GroupsCategory","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:F5-Groups":{"__typename":"Category","id":"category:F5-Groups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CommunityGroups":{"__typename":"Category","id":"category:CommunityGroups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Occasion:board:Events":{"__typename":"Occasion","id":"board:Events","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"occasionPolicies":{"__typename":"OccasionPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Idea:board:Suggestions":{"__typename":"Idea","id":"board:Suggestions","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"ideaPolicies":{"__typename":"IdeaPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:codeshare":{"__typename":"Tkb","id":"board:codeshare","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"displayId":"codeshare","nodeType":"board","conversationStyle":"TKB","title":"CodeShare","shortTitle":"CodeShare","parent":{"__ref":"Category:category:CrowdSRC"}},"Tkb:board:communityarticles":{"__typename":"Tkb","id":"board:communityarticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"displayId":"communityarticles","nodeType":"board","conversationStyle":"TKB","title":"Community Articles","shortTitle":"Community Articles","parent":{"__ref":"Category:category:CrowdSRC"}},"Tkb:board:security-insights":{"__typename":"Tkb","id":"board:security-insights","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:article-series":{"__typename":"Tkb","id":"board:article-series","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Conversation:conversation:341937":{"__typename":"Conversation","id":"conversation:341937","topic":{"__typename":"TkbTopicMessage","uid":341937},"lastPostingActivityTime":"2025-06-30T01:18:20.945-07:00","solved":false},"User:user:112466":{"__typename":"User","uid":112466,"login":"lnxgeek","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0xMTI0NjYtMjE0NzNpOEM2MThGODRCN0JDRDBFNQ"},"id":"user:112466"},"TkbTopicMessage:message:341937":{"__typename":"TkbTopicMessage","subject":"NGINX App Protect v5 Signature Notifications","conversation":{"__ref":"Conversation:conversation:341937"},"id":"message:341937","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:341937","revisionNum":5,"uid":341937,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:112466"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":118},"postTime":"2025-06-12T01:42:41.470-07:00","lastPublishTime":"2025-06-12T02:17:46.905-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" When working with NAP (NGINX App Protect) you don't have an easy way of knowing when any of the signatures are updated. \n As an old BigIP guy I find that rather strange. Here you have build-in automatic updates and notifications. \n Unfortunately there isn't any API's you can probe which would have been the best way of doing it. Hopefully it will come one day. \n   \n However, \"friction\" and \"hard\" will not keep me from finding a solution πŸ˜† \n   \n I have previously made a solution for NAPv4 and I have tried mentally to get me going on a NAPv5 version. The reason for the delay is in the different way NAPv4 and NAPv5 are designed. Where NAPv4 is one module loaded in NGINX, NAPv5 is completely detached from NGINX (well almost, you still need to load a small module to get the traffic from NGINX to NAP) and only works with containers. \n NAPv5 has moved the signature \"storage\" from the actual host it is running on (e.g. an installed package) to the policy. This has the consequence that finding a valid \"source of truth\", for the latest signature versions, is not as simple as building a new image and see which versions got installed. \n There are very good reasons for this design that I will come back to later. \n When you fire up NAPv5 you got three containers for the data plane (NGINX, waf-enforcer and waf-config-mgr) and one for the \"control plane\" (waf-compiler). For this solution the \"control plane\" is the useful one. It isn't really a control plane but it gives a nice picture of how it is detached from the actual processing of traffic. \n When you update your signatures you are actually doing it through the waf-compiler. The waf-compiler is a container hosting the actual signature databases and every time a new verison is released you need to rebuild this container and compile your policies into a new version and reload NGINX. \n And this is what I take advantage of when I look for signature updates. It has the upside that you only need the waf-compiler to get the information you need. My solution will take care of the entire process and make sure that you are always running with the latest signatures. \n Back to the reason why the split of functions is a very good thing. When you build a new version of the NGINX image and deploy it into production, NAP needs to compile the policies as they load. During the compilation NGINX is not moving any traffic! This becomes a annoying problem even when you have a low number of policies. I have installations where it takes 5 to 10 minutes from deployment of the new image until it starts moving traffic. That is a crazy long time when you are used to working with micro-services and expect everything to flip within seconds. If you have your NAPv4 hooked up to a NGINX Instance Manager (NIM) the problem is somewhat mitigated as NIM will compile the policies before sending them to the gateways. NIM is not a nimble piece of software so it doesn't always fit into the environment. \n   \n And now here is my hack to the notification problem: \n The solution consist of two bash scripts and one html template. The template is used when sending a notification mail. I wanted it to be pretty and that was easiest with html. Strictly speaking you could do with just a simple text based mail. \n Save all three in the same directory. \n The main script is called \"waf_policy_auto_compile.sh\"and is the one you put into crontab. \n The main script will build a new waf-compiler image and compile a test policy. The outcome of that is information about what versions are the newest. It will then extract versions from an old policy and simply see if any of the versions differ. For this to work you need to have an uncompiled policy (you can just use the default one) and a compiled version of it ready beforehand. \n   \n When a diff has been identified the notification logic is executed and a second script is called: \"compile_waf_policies.sh\". \n It basically just trawls through the directory of you policies and logging profiles and compiles a new version of them all. It is not necessary to recompile the logging profiles, so this will probably change in the next version. \n   \n As the compilation completes the main script will nudge NGINX to reload thus implement all the new versions. \n You can run \"waf_policy_auto_compile.sh\" with a verbose flag (-v) and a debug flag (-d). The verbose flag is intended to be used when you run it on a terminal and want the information displayed there. Debug is, well, for debug 😝  \n The construction of the scripts are based on my own needs but they should be easy to adjust for any need. \n I will be happy for any feedback, so please don't hold back πŸ˜„ \n   \n version_report_template.html: \n <!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>WAF Policy Version Report</title>\n <style>\n body { font-family: system-ui, sans-serif; }\n .ok { color: #28a745; font-weight: bold; }\n .warn { color: #f0ad4e; font-weight: bold; }\n .section { margin-bottom: 1.2em; }\n .label { font-weight: bold; }\n </style>\n</head>\n<body>\n <h2>WAF Policy Version Report</h2>\n <div class=\"section\">\n <div class=\"label\">Attack Signatures:</div>\n <div>Current: <span>{{ATTACK_OLD}}</span></div>\n <div>New: <span>{{ATTACK_NEW}}</span></div>\n <div>Status: <span class=\"{{ATTACK_CLASS}}\">{{ATTACK_STATUS}}</span></div>\n </div>\n <div class=\"section\">\n <div class=\"label\">Bot Signatures:</div>\n <div>Current: <span>{{BOT_OLD}}</span></div>\n <div>New: <span>{{BOT_NEW}}</span></div>\n <div>Status: <span class=\"{{BOT_CLASS}}\">{{BOT_STATUS}}</span></div>\n </div>\n <div class=\"section\">\n <div class=\"label\">Threat Campaigns:</div>\n <div>Current: <span>{{THREAT_OLD}}</span></div>\n <div>New: <span>{{THREAT_NEW}}</span></div>\n <div>Status: <span class=\"{{THREAT_CLASS}}\">{{THREAT_STATUS}}</span></div>\n </div>\n <div>Run completed: {{RUN_DATETIME}}</div>\n</body>\n</html>\n\n \n compile_waf_policies.sh: \n #!/bin/bash\n# ==============================================================================\n# Script Name: compile_waf_policies.sh\n#\n# Description:\n# Compiles:\n# 1. WAF policy JSON files from the 'policies' directory\n# 2. WAF logging JSON files from the 'logging' directory\n# using the 'waf-compiler-latest:custom' Docker image. Output goes to\n# '/opt/napv5/app_protect_etc_config' where NGINX and waf-config-mgr\n# can reach them.\n#\n# Requirements:\n# - Docker installed and accessible\n# - Docker image 'waf-compiler-latest:custom' present locally\n#\n# Usage:\n# ./compile_waf_policies.sh\n# ==============================================================================\n\nset -euo pipefail\nIFS=$'\\n\\t'\nSECONDS=0 # Track total execution time\n\n# ========================\n# CONFIGURABLE VARIABLES\n# ========================\n\nBASE_DIR=\"/root/napv5/waf-compiler\"\nOUTPUT_DIR=\"/opt/napv5/app_protect_etc_config\"\n\nPOLICY_INPUT_DIR=\"$BASE_DIR/policies\"\nPOLICY_OUTPUT_DIR=\"$OUTPUT_DIR\"\n\nLOGGING_INPUT_DIR=\"$BASE_DIR/logging\"\nLOGGING_OUTPUT_DIR=\"$OUTPUT_DIR\"\n\nGLOBAL_SETTINGS=\"$BASE_DIR/global_settings.json\"\nDOCKER_IMAGE=\"waf-compiler-latest:custom\"\n\n# ========================\n# VALIDATION\n# ========================\n\necho \"πŸ”§ Validating paths...\"\n\n[[ -d \"$POLICY_INPUT_DIR\" ]] || { echo \"❌ Error: Policy input directory '$POLICY_INPUT_DIR' does not exist.\"; exit 1; }\n[[ -f \"$GLOBAL_SETTINGS\" ]] || { echo \"❌ Error: Global settings file '$GLOBAL_SETTINGS' not found.\"; exit 1; }\n\nmkdir -p \"$POLICY_OUTPUT_DIR\"\nmkdir -p \"$LOGGING_OUTPUT_DIR\"\n\n# ========================\n# POLICY COMPILATION\n# ========================\n\necho \"πŸ“¦ Compiling WAF policies from: $POLICY_INPUT_DIR\"\nfor POLICY_FILE in \"$POLICY_INPUT_DIR\"/*.json; do\n [[ -f \"$POLICY_FILE\" ]] || continue\n\n BASENAME=$(basename \"$POLICY_FILE\" .json)\n OUTPUT_FILE=\"$POLICY_OUTPUT_DIR/${BASENAME}.tgz\"\n\n echo \"βš™οΈ [Policy] Compiling $(basename \"$POLICY_FILE\") -> $(basename \"$OUTPUT_FILE\")\"\n\n docker run --rm \\\n -v \"$POLICY_INPUT_DIR\":\"$POLICY_INPUT_DIR\" \\\n -v \"$POLICY_OUTPUT_DIR\":\"$POLICY_OUTPUT_DIR\" \\\n -v \"$(dirname \"$GLOBAL_SETTINGS\")\":\"$(dirname \"$GLOBAL_SETTINGS\")\" \\\n \"$DOCKER_IMAGE\" \\\n -g \"$GLOBAL_SETTINGS\" \\\n -p \"$POLICY_FILE\" \\\n -o \"$OUTPUT_FILE\"\ndone\n\n# ========================\n# LOGGING COMPILATION\n# ========================\n\necho \"πŸ“ Compiling WAF logging configs from: $LOGGING_INPUT_DIR\"\nif [[ -d \"$LOGGING_INPUT_DIR\" ]]; then\n for LOG_FILE in \"$LOGGING_INPUT_DIR\"/*.json; do\n [[ -f \"$LOG_FILE\" ]] || continue\n\n BASENAME=$(basename \"$LOG_FILE\" .json)\n OUTPUT_FILE=\"$LOGGING_OUTPUT_DIR/${BASENAME}.tgz\"\n\n echo \"βš™οΈ [Logging] Compiling $(basename \"$LOG_FILE\") -> $(basename \"$OUTPUT_FILE\")\"\n\n docker run --rm \\\n -v \"$LOGGING_INPUT_DIR\":\"$LOGGING_INPUT_DIR\" \\\n -v \"$LOGGING_OUTPUT_DIR\":\"$LOGGING_OUTPUT_DIR\" \\\n \"$DOCKER_IMAGE\" \\\n -l \"$LOG_FILE\" \\\n -o \"$OUTPUT_FILE\"\n done\nelse\n echo \"⚠️ Skipping logging config compilation: directory '$LOGGING_INPUT_DIR' does not exist.\"\nfi\n\n# ========================\n# COMPLETION MESSAGE\n# ========================\n\nRUNTIME=$SECONDS\nprintf \"\\nβœ… Compilation complete.\\n\"\necho \" - Policies output: $POLICY_OUTPUT_DIR\"\necho \" - Logging output: $LOGGING_OUTPUT_DIR\"\necho\nprintf \"⏱️ Total time taken: %02d minutes %02d seconds\\n\" $((RUNTIME / 60)) $((RUNTIME % 60))\necho\n\n \n waf_policy_auto_compile.sh: \n #!/bin/bash\n\n###############################################################################\n# waf_policy_auto_compile.sh\n#\n# - Only prints colorized summary output to terminal if -v/--verbose is used\n# - Mails a styled HTML report using a template, substituting version numbers/status/colors\n# - Debug output (step_log) only to syslog if -d/--debug is used\n# - Otherwise: completely silent except for errors\n# - All main blocks are modularized in functions\n###############################################################################\n\nset -euo pipefail\nIFS=$'\\n\\t'\n\n# ===== CONFIGURABLE VARIABLES =====\n\nWORKROOT=\"/root/napv5\"\nWORKDIR=\"$WORKROOT/waf-compiler\"\nDOCKERFILE=\"$WORKDIR/Dockerfile\"\nBUNDLE_DIR=\"$WORKDIR/test\"\nNEW_BUNDLE=\"$BUNDLE_DIR/test_new.tgz\"\nOLD_BUNDLE=\"$BUNDLE_DIR/test_old.tgz\"\nNEW_META=\"$BUNDLE_DIR/test_new_meta.json\"\nCOMPILER_IMAGE=\"waf-compiler-latest:custom\"\nEMAIL_RECIPIENT=\"example@example.com\"\nEMAIL_SUBJECT=\"WAF Compiler Update Notification\"\nNGINX_RELOAD_CMD=\"docker exec nginx-plus nginx -s reload\"\nHTML_TEMPLATE=\"$WORKDIR/version_report_template.html\"\nHTML_REPORT=\"$WORKDIR/version_report.html\"\nVERBOSE=0\nDEBUG=0\n\n# ===== DEBUG AND ERROR LOGGING =====\n\nexec 2> >(tee -a /tmp/waf_policy_auto_compile_error.log | /usr/bin/logger -t waf_policy_auto_compile_error)\n\nstep_log() {\n if [ \"$DEBUG\" -eq 1 ]; then\n echo \"DEBUG: $1\" | /usr/bin/logger -t waf_policy_auto_compile\n fi\n}\n\n# ===== ARGUMENT PARSING =====\n\nwhile [[ $# -gt 0 ]]; do\n case \"$1\" in\n -v|--verbose)\n VERBOSE=1\n shift\n ;;\n -d|--debug)\n DEBUG=1\n echo \"Debug log can be found in the syslog...\"\n shift\n ;;\n -*)\n echo \"Unknown option: $1\" >&2\n exit 1\n ;;\n *)\n shift\n ;;\n esac\ndone\n\n# ----- LOG INITIAL ENVIRONMENT IF DEBUG -----\nstep_log \"waf_policy_auto_compile starting (PID $$)\"\nstep_log \"Script PATH: $PATH\"\nstep_log \"which docker: $(which docker 2>/dev/null)\"\nstep_log \"which jq: $(which jq 2>/dev/null)\"\n\n# ===== COLOR DEFINITIONS =====\n\ncolor_reset=\"\\033[0m\"\ncolor_green=\"\\033[1;32m\"\ncolor_yellow=\"\\033[1;33m\"\n\n# ===== LOGGING FUNCTIONS =====\n\nlog() {\n # Only log to terminal if VERBOSE is enabled\n if [ \"$VERBOSE\" -eq 1 ]; then\n echo \"[$(date --iso-8601=seconds)] $*\"\n fi\n}\n\n# ===== HTML REPORT GENERATOR =====\n\ngenerate_html_report() {\n local attack_old=\"$1\"\n local attack_new=\"$2\"\n local attack_status=\"$3\"\n local attack_class=\"$4\"\n local bot_old=\"$5\"\n local bot_new=\"$6\"\n local bot_status=\"$7\"\n local bot_class=\"$8\"\n local threat_old=\"$9\"\n local threat_new=\"${10}\"\n local threat_status=\"${11}\"\n local threat_class=\"${12}\"\n local datetime\n datetime=$(date --iso-8601=seconds)\n cp \"$HTML_TEMPLATE\" \"$HTML_REPORT\"\n\n sed -i \"s|{{ATTACK_OLD}}|$attack_old|g\" \"$HTML_REPORT\"\n sed -i \"s|{{ATTACK_NEW}}|$attack_new|g\" \"$HTML_REPORT\"\n sed -i \"s|{{ATTACK_STATUS}}|$attack_status|g\" \"$HTML_REPORT\"\n sed -i \"s|{{ATTACK_CLASS}}|$attack_class|g\" \"$HTML_REPORT\"\n sed -i \"s|{{BOT_OLD}}|$bot_old|g\" \"$HTML_REPORT\"\n sed -i \"s|{{BOT_NEW}}|$bot_new|g\" \"$HTML_REPORT\"\n sed -i \"s|{{BOT_STATUS}}|$bot_status|g\" \"$HTML_REPORT\"\n sed -i \"s|{{BOT_CLASS}}|$bot_class|g\" \"$HTML_REPORT\"\n sed -i \"s|{{THREAT_OLD}}|$threat_old|g\" \"$HTML_REPORT\"\n sed -i \"s|{{THREAT_NEW}}|$threat_new|g\" \"$HTML_REPORT\"\n sed -i \"s|{{THREAT_STATUS}}|$threat_status|g\" \"$HTML_REPORT\"\n sed -i \"s|{{THREAT_CLASS}}|$threat_class|g\" \"$HTML_REPORT\"\n sed -i \"s|{{RUN_DATETIME}}|$datetime|g\" \"$HTML_REPORT\"\n \n}\n\n# ===== BUILD COMPILER IMAGE =====\n\nbuild_compiler() {\n step_log \"about to build_compiler\"\n docker build --no-cache --platform linux/amd64 \\\n --secret id=nginx-crt,src=\"$WORKROOT/nginx-repo.crt\" \\\n --secret id=nginx-key,src=\"$WORKROOT/nginx-repo.key\" \\\n -t \"$COMPILER_IMAGE\" \\\n -f \"$DOCKERFILE\" \"$WORKDIR\" > \"$WORKDIR/waf_compiler_build.log\" 2>&1 || {\n echo \"ERROR: docker build failed. Dumping build log:\" | /usr/bin/logger -t waf_policy_auto_compile_error\n cat \"$WORKDIR/waf_compiler_build.log\" | /usr/bin/logger -t waf_policy_auto_compile_error\n exit 1\n }\n step_log \"after build_compiler\"\n}\n\n# ===== COMPILE TEST POLICY =====\n\ncompile_test_policy() {\n step_log \"about to compile_test_policy\"\n docker run --rm -v \"$BUNDLE_DIR:/bundle\" \"$COMPILER_IMAGE\" \\\n -p /bundle/test.json -o /bundle/test_new.tgz > \"$NEW_META\"\n step_log \"after compile_test_policy\"\n if [ -f \"$NEW_META\" ]; then\n step_log \"$(cat \"$NEW_META\")\"\n else\n step_log \"NEW_META does not exist\"\n fi\n}\n\n# ===== CHECK OLD_BUNDLE =====\n\ncheck_old_bundle() {\n step_log \"about to check OLD_BUNDLE\"\n if [ -f \"$OLD_BUNDLE\" ]; then\n step_log \"$(ls -l \"$OLD_BUNDLE\")\"\n else\n step_log \"OLD_BUNDLE does not exist\"\n fi\n}\n\n# ===== GET NEW VERSIONS FUNCTION =====\n\nget_new_versions() {\n jq -r '\n {\n \"attack\": .attack_signatures_package.version,\n \"bot\": .bot_signatures_package.version,\n \"threat\": .threat_campaigns_package.version\n }' \"$NEW_META\"\n}\n\n# ===== VERSION EXTRACTION FROM OLD BUNDLE =====\n\nextract_bundle_versions() {\n docker run --rm -v \"$BUNDLE_DIR:/bundle\" \"$COMPILER_IMAGE\" \\\n -dump -bundle \"/bundle/test_old.tgz\"\n}\n\nextract_versions_from_dump() {\n extract_bundle_versions | awk '\n BEGIN { print \"{\" }\n /attack-signatures:/ { in_attack=1; next }\n /bot-signatures:/ { in_bot=1; next }\n /threat-campaigns:/ { in_threat=1; next }\n in_attack && /version:/ {\n gsub(\"version: \", \"\")\n printf \"\\\"attack\\\":\\\"%s\\\",\\n\", $1\n in_attack=0\n }\n in_bot && /version:/ {\n gsub(\"version: \", \"\")\n printf \"\\\"bot\\\":\\\"%s\\\",\\n\", $1\n in_bot=0\n }\n in_threat && /version:/ {\n gsub(\"version: \", \"\")\n printf \"\\\"threat\\\":\\\"%s\\\"\\n\", $1\n in_threat=0\n }\n END { print \"}\" }\n '\n}\n\nget_old_versions() {\n extract_versions_from_dump\n}\n\n# ===== GET & PRINT VERSIONS =====\n\nget_versions() {\n step_log \"about to get_new_versions\"\n new_versions=$(get_new_versions)\n step_log \"new_versions: $new_versions\"\n step_log \"after get_new_versions\"\n\n step_log \"about to get_old_versions\"\n old_versions=$(get_old_versions)\n step_log \"old_versions: $old_versions\"\n step_log \"after get_old_versions\"\n}\n\n# ===== VERSION COMPARISON =====\n\ncompare_versions() {\n step_log \"compare_versions start\"\n attack_old=$(echo \"$old_versions\" | jq -r .attack)\n attack_new=$(echo \"$new_versions\" | jq -r .attack)\n bot_old=$(echo \"$old_versions\" | jq -r .bot)\n bot_new=$(echo \"$new_versions\" | jq -r .bot)\n threat_old=$(echo \"$old_versions\" | jq -r .threat)\n threat_new=$(echo \"$new_versions\" | jq -r .threat)\n\n attack_status=$([[ \"$attack_old\" != \"$attack_new\" ]] && echo \"Updated\" || echo \"No Change\")\n bot_status=$([[ \"$bot_old\" != \"$bot_new\" ]] && echo \"Updated\" || echo \"No Change\")\n threat_status=$([[ \"$threat_old\" != \"$threat_new\" ]] && echo \"Updated\" || echo \"No Change\")\n\n attack_class=$([[ \"$attack_status\" == \"Updated\" ]] && echo \"warn\" || echo \"ok\")\n bot_class=$([[ \"$bot_status\" == \"Updated\" ]] && echo \"warn\" || echo \"ok\")\n threat_class=$([[ \"$threat_status\" == \"Updated\" ]] && echo \"warn\" || echo \"ok\")\n\n echo \"Attack:$attack_status Bot:$bot_status Threat:$threat_status\" > \"$WORKDIR/status_flags.txt\"\n\n [[ \"$attack_status\" == \"Updated\" ]] && attack_status_colored=\"${color_yellow}*** Updated ***${color_reset}\" || attack_status_colored=\"${color_green}No Change${color_reset}\"\n [[ \"$bot_status\" == \"Updated\" ]] && bot_status_colored=\"${color_yellow}*** Updated ***${color_reset}\" || bot_status_colored=\"${color_green}No Change${color_reset}\"\n [[ \"$threat_status\" == \"Updated\" ]] && threat_status_colored=\"${color_yellow}*** Updated ***${color_reset}\" || threat_status_colored=\"${color_green}No Change${color_reset}\"\n\n {\n echo -e \"Version comparison for container \\033[1mNAPv5\\033[0m:\\n\"\n echo -e \"Attack Signatures:\"\n echo -e \" Current Version: $attack_old\"\n echo -e \" New Version: $attack_new\"\n echo -e \" Status: $attack_status_colored\\n\"\n echo -e \"Threat Campaigns:\"\n echo -e \" Current Version: $threat_old\"\n echo -e \" New Version: $threat_new\"\n echo -e \" Status: $threat_status_colored\\n\"\n echo -e \"Bot Signatures:\"\n echo -e \" Current Version: $bot_old\"\n echo -e \" New Version: $bot_new\"\n echo -e \" Status: $bot_status_colored\"\n } > \"$WORKDIR/version_report.ansi\"\n\n sed 's/\\x1B\\[[0-9;]*[mK]//g' \"$WORKDIR/version_report.ansi\" > \"$WORKDIR/version_report.txt\"\n\n step_log \"Calling log_versions_syslog\"\n log_versions_syslog \"$attack_old\" \"$attack_new\" \"$attack_status\" \"$attack_class\" \\\n \"$bot_old\" \"$bot_new\" \"$bot_status\" \"$bot_class\" \\\n \"$threat_old\" \"$threat_new\" \"$threat_status\" \"$threat_class\"\n step_log \"compare_versions finished\"\n}\n\n# ===== SYSLOG VERSION LOGGING and HTML REPORT GEN =====\n\nlog_versions_syslog() {\n # Args:\n # 1-attack_old 2-attack_new 3-attack_status 4-attack_class\n # 5-bot_old 6-bot_new 7-bot_status 8-bot_class\n # 9-threat_old 10-threat_new 11-threat_status 12-threat_class\n\n local msg\n msg=\"AttackSig (current: $1, latest: $2), BotSig (current: $5, latest: $6), ThreatCamp (current: $9, latest: $10)\"\n /usr/bin/logger -t waf_policy_auto_compile \"$msg\"\n # Also print to terminal if VERBOSE is enabled\n if [ \"$VERBOSE\" -eq 1 ]; then\n echo \"$msg\"\n fi\n\n # Always (re)generate HTML for the mail at this point\n generate_html_report \"$@\"\n}\n\n# ===== RESPONSE ACTIONS =====\n\ncompile_all_policies() {\n log \"Change detected – compiling all policies...\"\n if [ \"$VERBOSE\" -eq 1 ]; then\n \"$WORKDIR/compile_waf_policies.sh\"\n else\n \"$WORKDIR/compile_waf_policies.sh\" > /dev/null 2>&1\n fi\n}\n\nreload_nginx() {\n log \"Reloading NGINX...\"\n eval \"$NGINX_RELOAD_CMD\"\n}\n\nrotate_bundles() {\n log \"Archiving new test bundle as old...\"\n mv \"$NEW_BUNDLE\" \"$OLD_BUNDLE\"\n rm -f \"$NEW_META\"\n}\n\nsend_report_email() {\n local html_report=\"$1\"\n mail -s \"$EMAIL_SUBJECT\" -a \"Content-Type: text/html\" \"$EMAIL_RECIPIENT\" < \"$html_report\"\n}\n\n# ===== MAIN LOGIC =====\n\nmain() {\n build_compiler\n compile_test_policy\n check_old_bundle\n get_versions\n compare_versions\n\n if [[ \"$VERBOSE\" -eq 1 ]]; then\n cat \"$WORKDIR/version_report.ansi\"\n fi\n\n if grep -q \"Updated\" \"$WORKDIR/status_flags.txt\"; then\n if [[ \"$VERBOSE\" -eq 1 ]]; then\n echo \"Detected updates. Recompiling policies, reloading NGINX, sending report.\"\n fi\n compile_all_policies\n reload_nginx\n rotate_bundles\n send_report_email \"$HTML_REPORT\"\n else\n log \"No changes detected – nothing to do.\"\n fi\n\n log \"Done.\"\n}\n\nmain \"$@\"\n\n \n And should be it. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"20440","kudosSumWeight":2,"repliesCount":3,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:339724":{"__typename":"Conversation","id":"conversation:339724","topic":{"__typename":"TkbTopicMessage","uid":339724},"lastPostingActivityTime":"2025-06-26T01:24:59.793-07:00","solved":false},"User:user:305752":{"__typename":"User","uid":305752,"login":"Nikoolayy1","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0zMDU3NTItd2tMWnln?image-coordinates=3%2C3%2C176%2C176"},"id":"user:305752"},"TkbTopicMessage:message:339724":{"__typename":"TkbTopicMessage","subject":"Trigger js challenge/Captcha for ip reputation/ip intelligence categories","conversation":{"__ref":"Conversation:conversation:339724"},"id":"message:339724","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:339724","revisionNum":8,"uid":339724,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:305752"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"The F5 devices use brightcloud as a source for detected bad ip addresses but a lot of times categories like \"Spam Sources\" or \"Windows Exploits\" need to be stopped. This code provides compromise between security and availability.","metrics":{"__typename":"MessageMetrics","views":224},"postTime":"2025-02-12T05:22:12.276-08:00","lastPublishTime":"2025-06-26T01:24:59.793-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Problem solved by this Code Snippet \n   \n Because some ISP or cloud providers do not monitor their users a lot of times client ip addresses are marked as \"spam sources\"  or \"windows exploits\" and as the ip addresses are dynamic and after time a legitimate user can use this ip addresses the categories are often stopped in the IP intelligence profile or under the ASM/AWAF policy. This usually happens in Public Clouds that do not monitor what their users do and the IP gets marked as bad then another good user after a day or two has this ip address and this causes the issue. \n   \n For many of my clients I had to stop the ip reputation/ip intelligence category \"spam sources\" and in some cases \"windows exploits\" so having a javascript/captcha checks seems a nice compromise 😎 \n   \n To still make use of this categories the users coming from those ip addresses can be forced to solve captcha checks or at least to be checked for javascript support! \n   \n How to use this Code Snippet \n \n Have AWAF/ASM and ip intelligence licensed \n Add AWAF/ASM policy with irule support option (by default not enabled under the policy) or/and Bot profile under the Virtual server  \n Optionally add IP intelligence profile or enable the Ip intelligence under the WAF policy without the categories that cause a lot of false positives, \n Add the irule and if needed modify the categories for which it triggers \n Do not forget to first create the data group, used in the code or delete that part of the code and to uncomment the Bot part of the code, if you plan to do js check and not captcha and maybe comment the captcha part ! \n \n Code Snippet Meta Information \n \n Version: 17.1.3 \n Coding Language: TCL \n \n Code \n You can find the code and further documentation in my GitHub repository: \n reputation-javascript-captcha-challlenge/ at main Β· Nikoolayy1/reputation-javascript-captcha-challlenge \n   \n   \n when HTTP_REQUEST { \n # Take the ip address for ip reputation/intelligence check from the XFF header if it comes from the whitelisted source ip addresses in data group \"client_ip_class\" \n if { [HTTP::header exists \"X-Forwarded-For\"] && [class match [IP::client_addr] equals \"/Common/client_ip_class\"] } {     set trueIP [HTTP::header \"X-Forwarded-For\"] } else {     set trueIP [IP::client_addr] } \n # Check if IP reputation is triggered and it is containing \"Spam Sources\" \n   if { ([llength [IP::reputation $trueIP]] != 0) && ([IP::reputation $trueIP] contains \"Spam Sources\") }{                   log local0. \"The category is [IP::reputation $trueIP] from [IP::client_addr]\" \n # Set the variable 1 or bulean true as to trigger ASM captcha or bot defense javascript                set js_ch 1              } else {          set js_ch 0      } \n #  Custom response page just for testing if there is no real backend origin server for testing \n     if {!$js_ch} {             HTTP::respond 200 content {       <html>          <head>             <title>Apology Page</title>          </head>          <body>             We are sorry, but the site you are looking for is temporarily out of service<br>             If you feel you have reached this page in error, please try again.          </body>       </html>               }             } \n } \n #  when BOTDEFENSE_ACTION { \n     # Trigger bot defense action javascript check for Spam Sources        #    if {$js_ch && (not ([BOTDEFENSE::reason] starts_with \"passed browser challenge\")) && ([BOTDEFENSE::action] eq \"allow\") }{      \n #        BOTDEFENSE::action browser_challenge              #    }       #  } \n   \n when ASM_REQUEST_DONE { \n   \n # Trigger ASM captcha check only for users comming from Spam sources that have not already passed the captcha check (don't have the captcha cookie) \n     if {$js_ch && [ASM::captcha_status] ne \"correct\"} {             set res [ASM::captcha]                    if {$res ne \"ok\"} {                 log local0. \"Cannot send captcha_challenge: \\\"$res\\\"\"            } \n     } } \n   \n Extra References:  \n   \n BOTDEFENSE::action \n ASM::captcha \n ASM::captcha_status \n   ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"5127","kudosSumWeight":1,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:284339":{"__typename":"Conversation","id":"conversation:284339","topic":{"__typename":"TkbTopicMessage","uid":284339},"lastPostingActivityTime":"2025-05-16T07:30:00.542-07:00","solved":false},"User:user:48814":{"__typename":"User","uid":48814,"login":"John_Beckmann","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-6.svg?time=0"},"id":"user:48814"},"TkbTopicMessage:message:284339":{"__typename":"TkbTopicMessage","subject":"Modify UCS Archive so it doesn't backup epsec images","conversation":{"__ref":"Conversation:conversation:284339"},"id":"message:284339","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:284339","revisionNum":1,"uid":284339,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:48814"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":513},"postTime":"2016-09-08T21:36:52.000-07:00","lastPublishTime":"2016-09-08T21:36:52.000-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Problem this snippet solves: Currently, if you have APM installed, the UCS Archive process, also backs up the epsec images. \n I have written a bash script, which modifies the UCS Archive process, so that it does not include these in the UCS Archive process, and it also modifies the bigip.conf that is archived, so that it does not contain references to these images. \n By default, APM has it's own epsec image in /var/sam/images so when your UCS Archive is loaded to a new system, or a rebuilt system, it will just use the default epsec image for that system. \n This means that if you have upload a new epsec image to fix an issue, you will need to ensure that this is done on any system you restore the UCS Archive too. How to use this snippet: Just save the bash script to a file like /shared/bin/modify_ucs.sh \n Then run the script:- \n # sh /shared/bin/modify_ucs.sh \n The script modifies /usr/libdata/configsync/cs.dat and creates two files config_save_pre and config_save_post in the same folder. It also creates a backup of cs.dat as cs.YYYY_MM_DD_HH_MM.bak \n The /usr filesystem is mounted RO, so I remount it RW to do this. \n To remove changes: \n mount -o remount,rw /usr \n cd /usr/libdata/configsync/ \n mv -f `ls -1t cs.dat.[0-9][0-9][0-9][0-9]*.bak|head -1` cs.dat \n rm -f config_save_p[or][se]* \n mount -o remount,ro /usr \n This modification does not survive a upgrade, so you will need to run the script again after any upgrade \n If you are running a cron job to create a daily/weekly backup, you can just call this script before you run the tmsh save sys ucs command, as it checks to see if the modification has already been done. Code : 70454 ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"1665","kudosSumWeight":0,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:291002":{"__typename":"Conversation","id":"conversation:291002","topic":{"__typename":"TkbTopicMessage","uid":291002},"lastPostingActivityTime":"2025-05-05T07:32:32.644-07:00","solved":false},"User:user:325109":{"__typename":"User","uid":325109,"login":"youssef1","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-4.svg?time=0"},"id":"user:325109"},"TkbTopicMessage:message:291002":{"__typename":"TkbTopicMessage","subject":"Ultimate irule debug - Capture and investigate","conversation":{"__ref":"Conversation:conversation:291002"},"id":"message:291002","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:291002","revisionNum":2,"uid":291002,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:325109"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":5445},"postTime":"2018-12-06T03:09:12.000-08:00","lastPublishTime":"2023-06-05T21:51:52.395-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Problem this snippet solves: I decided to share this Irule for different reasons. When I help our community on devcentral, I regularly see people making recurring requests: \n How do I do to capture the queries header. How do I do to capture the response header. How do I check the information in the POST Request. How do I check response data (body). What cypher/protocol I use (SSL/TLS). I set up client certificate authentication but I do not know if it works and if I pass my certificate auth. I want to retrieve information from my authentication certificate (subject, issuer, …). My authenticating by certificate does not work and I get an error of what I have to do. I have latencies when dealing with my request. where does the latency come from (F5, server,..). I set up sso (kerberos delegation, json post, Form sso). I do not feel that my request is sent to the backend (or the kerberos token). Does F5 add information or modify the request/response. Which pool member has been selected My VS don’t answer (where does the problem come from) … \n instead of having an Irule for each request why not consolidate everything and provide a compact Irule.\nthis Irule can help you greatly during your investigations and allows you to capture these different items: How to use this snippet: you have a function that allows you to activate the desired logs (1 to activate and 0 to disable) as describe below: \n array set app_arrway_referer {\n client_dest_ip_port 1\n client_cert 1\n http_request 1\n http_request_release 1\n http_request_payload 0\n http_lb_selected 1\n http_response 0\n http_response_release 0\n http_response_payload 0\n http_time_process 0\n}\n \n\n the posted logs will be preceded by a UID which will allow you to follow from the beginning to the end of the process of your request / answer. you can for example make a grep on the log to follow the complete process (request / answer). \n the UID is generated in the following way: `set uid [string range [AES::key 256] 15 23] \n client_dest_ip_port: \n this section will allow you to see source IP/Port and destination IP/Port. \n <CLIENT_ACCEPTED>: ----------- client_dest_ip_port -----------\n<CLIENT_ACCEPTED>: uid: 382951fe9 - Client IP Src: 10.20.30.4:60419\n<CLIENT_ACCEPTED>: uid: 382951fe9 - Client IP Dest:192.168.30.45:443\n<CLIENT_ACCEPTED>: ----------- client_dest_ip_port -----------\n \n\n client_cert: \n this section will allow you to check the result code for peer certificate verification ( and also if you have provide a certificate auth). moreover you will be able to recover the information of your authentication certficat (issuer, subject, …). \n if your authentication certificate that you provid is not valid an error message will be returned (ex: certificate chain too long, invalid CA certificate, …). all errors are listed in the link below: \n https://devcentral.f5.com/wiki/iRules.SSL__verify_result.ashx \n <HTTP_REQUEST>: ----------- client_cert -----------\n<HTTP_REQUEST>: uid: 382951fe9 - cert number: 0\n<HTTP_REQUEST>: uid: 382951fe9 - subject: OU=myOu, CN=youssef\n<HTTP_REQUEST>: uid: 382951fe9 - Issuer Info: DC=com, DC=domain, CN=MobIssuer\n<HTTP_REQUEST>: uid: 382951fe9 - cert serial: 22:00:30:5c:de:dd:ec:23:6e:b5:e6:77:bj:01:00:00:22:3c:dc\n<HTTP_REQUEST>: ----------- client_cert -----------\n \n\n OR \n <HTTP_REQUEST>: ----------- client_cert -----------\n<HTTP_REQUEST>: uid: 382951fe9 - No client certificate provided\n<HTTP_REQUEST>: ----------- client_cert -----------\n \n\n http_request: \n This section allow you to retrieve the complete client HTTP request headers (that is, the method, URI, version, and all headers). I also added the protocol, the ciphers and the name of the vs used. \n <HTTP_REQUEST>: ----------- http_request -----------\n<HTTP_REQUEST>: uid: 382951fe9 - protocol: https\n<HTTP_REQUEST>: uid: 382951fe9 - cipher name: ECDHE-RSA-AES128-GCM-SHA256\n<HTTP_REQUEST>: uid: 382951fe9 - cipher version: TLSv1.2\n<HTTP_REQUEST>: uid: 382951fe9 - VS Name: /Common/vs-myapp-443\n<HTTP_REQUEST>: uid: 382951fe9 - Request: POST myapp.mydomain.com/browser-management/users/552462/playlist/play/api\n<HTTP_REQUEST>: uid: 382951fe9 - Host: myapp.mydomain.com\n<HTTP_REQUEST>: uid: 382951fe9 - Connection: keep-alive\n<HTTP_REQUEST>: uid: 382951fe9 - Content-Length: 290\n<HTTP_REQUEST>: uid: 382951fe9 - Accept: application/json, text/javascript, */*; q=0.01\n<HTTP_REQUEST>: uid: 382951fe9 - X-Requested-With: XMLHttpRequest\n<HTTP_REQUEST>: uid: 382951fe9 - User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36\n<HTTP_REQUEST>: uid: 382951fe9 - Referer: https://myapp.mydomain.com/\n<HTTP_REQUEST>: uid: 382951fe9 - Accept-Encoding: gzip, deflate, sdch, br\n<HTTP_REQUEST>: uid: 382951fe9 - Accept-Language: en-US,en;q=0.8\n<HTTP_REQUEST>: uid: 382951fe9 - Cookie: RLT=SKjpfdkFDKjkufd976HJhldds=; secureauth=true; STT=\"LKJSDKJpjslkdjslkjKJSHjfdskjhoLHkjh78dshjhd980szKJH\"; ASP.SessionId=dsliulpoiukj908798dsjkh\n<HTTP_REQUEST>: uid: 382951fe9 - X-Forwarded-For: 10.10.10.22\n<HTTP_REQUEST>: ----------- http_request -----------\n \n\n http_request_release: \n This section triggered when the system is about to release HTTP data on the serverside of the connection. This event is triggered after modules process the HTTP request. So it will allow you to check request after F5 process. suppose that you have put APM with SSO kerberos, you will be able to see the kerberos token insert by F5. Or XFF insert by HTTP profile… \n <HTTP_REQUEST_RELEASE>: ----------- http_request_release -----------\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - VS Name: /Common/vs-myapp-443\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Request: GET myapp.mydomain.com/browser-management/users/552462/playlist/play/api\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Host: myapp.mydomain.com\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Connection: keep-alive\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Accept: application/json, text/javascript, */*; q=0.01\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - X-Requested-With: XMLHttpRequest\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Referer: https://myapp.mydomain.com/\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Accept-Encoding: gzip, deflate, sdch, br\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Accept-Language: en-US,en;q=0.8\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - Cookie: RLT=SKjpfdkFDKjkufd976HJhldds=; secureauth=true; STT=\"LKJSDKJpjslkdjslkjKJSHjfdskjhoLHkjh78dshjhd980szKJH\"; ASP.SessionId=dsliulpoiukj908798dsjkh\n<HTTP_REQUEST_RELEASE>: uid: 382951fe9 - X-Forwarded-For: 10.10.10.22\n<HTTP_REQUEST_RELEASE>: ----------- http_request_release -----------\n \n\n http_request_payload: \n This section will allow you to retrieve the HTTP request body. \n <HTTP_REQUEST>: ----------- http_request_payload -----------\n<HTTP_REQUEST>: uid: 382951fe9 - Content-Length header null in request If GET or POST withtout content)\n<HTTP_REQUEST>: ----------- http_request_payload -----------\n \n\n or \n <HTTP_REQUEST>: ----------- http_request_payload -----------\n<HTTP_REQUEST>: uid: 382951fe9 - post payload: { id: 24, retrive: 'identity', service: 'IT'}\n<HTTP_REQUEST>: ----------- http_request_payload -----------\n \n\n http_lb_selected \n This section will allow you to you to see which pool member has been selected. Once the pool memeber has been selected, you will not see this logs again until another load balancing decision will be made. \n If you want to see the selected pool memeber for each request you can see this information in \"http_response\". \n <HTTP_REQUEST>: ----------- http_lb_selected -----------\n<LB_SELECTED>: uid: 382951fe9 - pool member IP: /Common/pool-name 10.22.33.54 443\n<HTTP_REQUEST>: ----------- http_lb_selected -----------\n \n\n http_response: \n This section will allow you to retrieve the response status and header lines from the server response. \n You can also see which pool member has been selected. \n <HTTP_RESPONSE>: ----------- http_response -----------\n<HTTP_RESPONSE>: uid: 382951fe9 - status: 200\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - pool member IP: /Common/pool-name 10.22.33.54 443\n<HTTP_RESPONSE>: uid: 382951fe9 - Cache-Control: no-cache\n<HTTP_RESPONSE>: uid: 382951fe9 - Pragma: no-cache\n<HTTP_RESPONSE>: uid: 382951fe9 - Content-Type: application/json; charset=utf-8\n<HTTP_RESPONSE>: uid: 382951fe9 - Expires: -1\n<HTTP_RESPONSE>: uid: 382951fe9 - Server: Microsoft-IIS/8.5\n<HTTP_RESPONSE>: uid: 382951fe9 - X-Powered-By: ASP.NET\n<HTTP_RESPONSE>: uid: 382951fe9 - Date: Fri, 28 Oct 2018 06:46:59 GMT\n<HTTP_RESPONSE>: uid: 382951fe9 - Content-Length: 302\n<HTTP_RESPONSE>: ----------- http_response -----------\n \n\n http_response_release: \n This section triggered when the system is about to release HTTP data on the clientside of the connection. This event is triggered after modules process the HTTP response. you can make sure that the answer has not been altering after the f5 process. \n You can also see which pool member has been selected. \n <HTTP_RESPONSE_RELEASE>: ----------- http_response_release -----------\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - status: 200\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - pool member IP: /Common/pool-name 10.22.33.54 443\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Cache-Control: no-cache\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Pragma: no-cache\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Content-Type: application/json; charset=utf-8\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Expires: -1\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Server: Microsoft-IIS/8.5\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - X-Powered-By: ASP.NET\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Date: Fri, 28 Oct 2018 06:46:59 GMT\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Content-Length: 302\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Strict-Transport-Security: max-age=16070400; includeSubDomains\n<HTTP_RESPONSE_RELEASE>: ----------- http_response_release -----------\n \n\n http_response_payload: \n This section will allow you to Collects an amount of HTTP body data that you specify. \n <HTTP_RESPONSE_DATA>: ----------- http_response_payload -----------\n<HTTP_RESPONSE_DATA>: uid: 382951fe9 - Response (Body) payload: { \"username\" : \"youssef\", \"genre\" : \"unknown\", \"validation-factors\" : { \"validationFactors\" : [ { \"name\" : \"remote_address\", \"value\" : \"127.0.0.1\" } ] }}\n<HTTP_RESPONSE_DATA>: ----------- http_response_payload -----------\n \n\n http_time_process: \n this part will allow you to put back information which can be useful to you to target the latency problematic.\nit is clear that it is not precise and that f5 offers other tools for that. but you will be able to quickly see which elements take the most time to be processed.\nyou will be able to see how long f5 takes to process the request, the response and how long the backend server takes time to respond. \n <HTTP_RESPONSE_RELEASE>: ----------- http_time_process -----------\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Time to request (F5 request time) = 5 (ms)\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Time to response (F5 response time) = 0 (ms)\n<HTTP_RESPONSE_RELEASE>: uid: 382951fe9 - Time to server (server backend process time) = 4 (ms)\n<HTTP_RESPONSE_RELEASE>: ----------- http_time_process -----------\n Code : when CLIENT_ACCEPTED {\n\n# set a unique id for transaction\nset uid [string range [AES::key 256] 15 23]\n\n# set what's you want to retrieve 0 or 1\narray set app_arrway_referer {\nclient_dest_ip_port 1\nclient_cert 1\nhttp_request 1\nhttp_request_release 1\nhttp_request_payload 1\nhttp_lb_selected 1\nhttp_response 1\nhttp_response_release 1\nhttp_response_payload 1\nhttp_time_process 1\n}\n\nif {$app_arrway_referer(client_dest_ip_port)} {\nlog local0. \" ----------- client_dest_ip_port ----------- \"\nclientside {\n log local0. \"uid: $uid - Client IP Src: [IP::client_addr]:[TCP::client_port]\"\n}\nlog local0. \"uid: $uid - Client IP Dest:[IP::local_addr]:[TCP::local_port]\"\nlog local0. \" ----------- client_dest_ip_port ----------- \"\nlog local0. \" \"\n}\n}\n\nwhen HTTP_REQUEST {\n\nset http_request_time [clock clicks -milliseconds]\n\n# Triggered when the system receives a certificate message from the client. The message may contain zero or more certificates.\nif {$app_arrway_referer(client_cert)} {\nlog local0. \" ----------- client_cert ----------- \"\n# SSL::cert count - Returns the total number of certificates that the peer has offered.\nif {[SSL::cert count] > 0}{\n# Check if there was no error in validating the client cert against LTM's server cert\nif { [SSL::verify_result] == 0 }{\nfor {set i 0} {$i < [SSL::cert count]} {incr i}{\n log local0. \"uid: $uid - cert number: $i\"\n log local0. \"uid: $uid - subject: [X509::subject [SSL::cert $i]]\"\n log local0. \"uid: $uid - Issuer Info: [X509::issuer [SSL::cert $i]]\"\n log local0. \"uid: $uid - cert serial: [X509::serial_number [SSL::cert $i]]\"\n}\n} else {\n# https://devcentral.f5.com/s/wiki/iRules.SSL__verify_result.ashx (OpenSSL verify result codes)\nlog local0. \"uid: $uid - Cert Info: [X509::verify_cert_error_string [SSL::verify_result]]\"\n}\n} else {\nlog local0. \"uid: $uid - No client certificate provided\"\n}\nlog local0. \" ----------- client_cert ----------- \"\nlog local0. \" \"\n}\n\nif {$app_arrway_referer(http_request)} {\nlog local0. \" ----------- http_request ----------- \"\nif { [PROFILE::exists clientssl] == 1 } {\nlog local0. \"uid: $uid - protocol: https\"\nlog local0. \"uid: $uid - cipher name: [SSL::cipher name]\"\nlog local0. \"uid: $uid - cipher version: [SSL::cipher version]\"\n}\n\nlog local0. \"uid: $uid - VS Name: [virtual]\"\nlog local0. \"uid: $uid - Request: [HTTP::method] [HTTP::host][HTTP::uri]\"\n\nforeach aHeader [HTTP::header names] {\nlog local0. \"uid: $uid - $aHeader: [HTTP::header value $aHeader]\"\n}\nlog local0. \" ----------- http_request ----------- \"\nlog local0. \" \"\n}\n\nset collect_length_request [HTTP::header value \"Content-Length\"]\nset contentlength 1\n\nif {$app_arrway_referer(http_request_payload)} {\nif { [catch {\nif { $collect_length_request > 0 && $collect_length_request < 1048577 } {\nset collect_length $collect_length_request\n} else {\nset collect_length 1048576\n} \nif { $collect_length > 0 } {\nHTTP::collect $collect_length_request\nset contentlength 1\n}\n}] } {\n\n# no DATA in POST Request\nlog local0. \" ----------- http_request_payload ----------- \"\nlog local0. \"uid: $uid - Content-Length header null in request\"\nlog local0. \" ----------- http_request_payload ----------- \"\nlog local0. \" \"\nset contentlength 0\n}\n}\n}\n\nwhen HTTP_REQUEST_DATA {\n\nif {$app_arrway_referer(http_request_payload)} {\nlog local0. \" ----------- http_request_payload ----------- \"\nif {$contentlength} {\nset postpayload [HTTP::payload]\nlog local0. \"uid: $uid - post payload: $postpayload\"\n#HTTP::release\n}\nlog local0. \" ----------- http_request_payload ----------- \"\nlog local0. \" \"\n}\n}\n\nwhen HTTP_REQUEST_RELEASE {\n\nif {$app_arrway_referer(http_request_release)} {\nlog local0. \" ----------- http_request_release ----------- \"\nif { [PROFILE::exists clientssl] == 1 } {\nlog local0. \"uid: $uid - cipher protocol: https\"\nlog local0. \"uid: $uid - cipher name: [SSL::cipher name]\"\nlog local0. \"uid: $uid - cipher version: [SSL::cipher version]\"\n}\n\nlog local0. \"uid: $uid - VS Name: [virtual]\"\nlog local0. \"uid: $uid - Request: [HTTP::method] [HTTP::host][HTTP::uri]\"\n\nforeach aHeader [HTTP::header names] {\nlog local0. \"uid: $uid - $aHeader: [HTTP::header value $aHeader]\"\n}\n\nlog local0. \" ----------- http_request_release ----------- \"\nlog local0. \" \"\n}\nset http_request_time_release [clock clicks -milliseconds]\n}\n\nwhen LB_SELECTED {\nif {$app_arrway_referer(http_lb_selected)} {\nlog local0. \" ----------- http_lb_selected ----------- \"\nlog local0. \"uid: $uid - pool member IP: [LB::server]\"\nlog local0. \" ----------- http_lb_selected ----------- \"\nlog local0. \" \"\n}\n}\n\nwhen HTTP_RESPONSE {\n\nset http_response_time [clock clicks -milliseconds]\nset content_length [HTTP::header \"Content-Length\"]\n\nif {$app_arrway_referer(http_response)} {\nlog local0. \" ----------- http_response ----------- \"\nlog local0. \"uid: $uid - status: [HTTP::status]\"\nlog local0. \"uid: $uid - pool member IP: [LB::server]\"\nforeach aHeader [HTTP::header names] {\nlog local0. \"uid: $uid - $aHeader: [HTTP::header value $aHeader]\"\n}\n\nlog local0. \" ----------- http_response ----------- \"\nlog local0. \" \"\n}\n\nif {$app_arrway_referer(http_response_payload)} {\nif { $content_length > 0 && $content_length < 1048577 } {\nset collect_length $content_length\n} else {\nset collect_length 1048576\n} \n\nif { $collect_length > 0 } {\nHTTP::collect $collect_length\n}\n}\n}\n\nwhen HTTP_RESPONSE_DATA {\n\nif {$app_arrway_referer(http_response_payload)} {\nlog local0. \" ----------- http_response_payload ----------- \"\nset payload [HTTP::payload] \nlog local0. \"uid: $uid - Response (Body) payload: $payload\"\nlog local0. \" ----------- http_response_payload ----------- \"\nlog local0. \" \"\n}\n}\n\nwhen HTTP_RESPONSE_RELEASE {\n\nset http_response_time_release [clock clicks -milliseconds]\n\nif {$app_arrway_referer(http_response_release)} {\nlog local0. \" ----------- http_response_release ----------- \"\nlog local0. \"uid: $uid - status: [HTTP::status]\"\nlog local0. \"uid: $uid - pool member IP: [LB::server]\"\nforeach aHeader [HTTP::header names] {\nlog local0. \"uid: $uid - $aHeader: [HTTP::header value $aHeader]\"\n}\nlog local0. \" ----------- http_response_release ----------- \"\nlog local0. \" \"\n}\n\nif {$app_arrway_referer(http_time_process)} {\nlog local0. \" ----------- http_time_process ----------- \"\nlog local0.info \"uid: $uid - Time to request (F5 request time) = [expr $http_request_time - $http_request_time_release] (ms)\"\nlog local0.info \"uid: $uid - Time to response (F5 response time) = [expr $http_response_time - $http_response_time_release] (ms)\"\nlog local0.info \"uid: $uid - Time to server (server backend process time) = [expr $http_request_time_release - $http_response_time] (ms)\"\nlog local0. \" ----------- http_time_process ----------- \"\nlog local0. \" \"\n}\n} Tested this on version: 13.0","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"18805","kudosSumWeight":6,"repliesCount":12,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:340704":{"__typename":"Conversation","id":"conversation:340704","topic":{"__typename":"TkbTopicMessage","uid":340704},"lastPostingActivityTime":"2025-04-17T04:47:34.748-07:00","solved":false},"User:user:72830":{"__typename":"User","uid":72830,"login":"mihaic","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS03MjgzMC0wQkpPYVo?image-coordinates=0%2C0%2C297%2C297"},"id":"user:72830"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zNDA3MDQtbW9jQ2tW?revision=14\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zNDA3MDQtbW9jQ2tW?revision=14","title":"Screenshot 2025-04-08 131334.png","associationType":"BODY","width":735,"height":720,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zNDA3MDQtaDJBeUhw?revision=14\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zNDA3MDQtaDJBeUhw?revision=14","title":"Screenshot 2025-04-11 151915.png","associationType":"BODY","width":1617,"height":940,"altText":""},"TkbTopicMessage:message:340704":{"__typename":"TkbTopicMessage","subject":"F5 MCP(Model Context Protocol) Server","conversation":{"__ref":"Conversation:conversation:340704"},"id":"message:340704","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:340704","revisionNum":14,"uid":340704,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:72830"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" This project is a MCP( Model Context Protocol ) server designed to interact with F5 devices using the iControl REST API. It provides a set of tools to manage F5 objects such as virtual servers (VIPs), pools, iRules, and profiles. The server is implemented using the FastMCP framework and exposes functionalities for creating, updating, listing, and deleting F5 objects. ","introduction":"MCP servers are all over the Internet these days. Even though they are a new thing, you can already find a lot of information about them, starting with what they are and what they can do, to examples all of sort.","metrics":{"__typename":"MessageMetrics","views":639},"postTime":"2025-04-08T00:14:32.904-07:00","lastPublishTime":"2025-04-17T04:47:34.748-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" In this article, I just want to share my implementation of a F5 MCP server, that can interact with an F5 device to list/show, create, modify/update or delete an object like: vip, pool, profile, irule. \n The F5 MCP server is designed to interact with F5 devices using the iControl REST API. It provides a set of tools to manage F5 objects such as virtual servers (VIPs), pools, iRules, and profiles that an LLM can use. The server is implemented using the FastMCP framework and exposes functionalities for creating, updating, listing, and deleting F5 objects. \n I've started thinking that I have to build a function for each object(vip,pool,etc) and each action (list,create,update,delete). It worked, but it was too complicated. The LLM only needed a way to interact with the device for those specific actions. So, using some careful chosen arguments, I've managed to build a simpler code that provides a tool/function for an action, no matter what the object is. \n Features \n \n Tool-Based API: The project defines tools (list_tool, create_tool, update_tool, delete_tool, show_stats_tool, show_logs_tool) that encapsulate operations on F5 devices. \n REST API Integration: Uses Python's requests library to communicate with F5 devices via the iControl REST API. \n Environment Configuration: Sensitive information like IP addresses and authorization strings are managed through environment variables loaded from a .env file. \n Extensibility: Modular design allows additional tools or functionalities to be added easily. \n Transport Support: The server runs using the stdio transport, making it compatible with various client integrations. \n Dockerfile: If you want to run this as a Docker container \n \n Key Files \n \n F5MCPserver.py: The main server file that initializes the MCP server and defines the tools. \n Tools/F5object.py: A utility class for performing CRUD operations on F5 objects. \n \n I already had some Python scripts built for these actions on F5 objects using iControl REST API, so all I had to do is use/convert them into tools.  \n For example, here is a list/show tool for an F5 object(you can find it in F5MCPserver.py): \n @mcp.tool()\ndef list_tool(object_name: str, object_type: str):\n \"\"\" This tool lists object on an F5 device using the iControl REST API.\n Args:\n object_name is the name of the object. \n object_type can be : virtual,pool,irule or profile \n \"\"\"\n list = F5_object(object_name = object_name, object_type = object_type)\n return list.list() \n And the function that the tool calls(you can find it in F5object.py): \n def list(self):\n \"\"\" This tool lists an object on an F5 device using the iControl REST API. \n \n Args:\n object_name is the name of the object. \n object_type is the type of the object to be created. It can be : virtual,pool,irule or profile.\n \n \"\"\"\n\n url = f\"https://{IP_ADDRESS}/mgmt/tm/ltm/{self.object_type}/{self.object_name}\"\n\n try:\n response = requests.request(\"GET\", url, headers=headers, verify=False, timeout=20)\n response.raise_for_status() \n except requests.exceptions.HTTPError:\n if (response.status_code == 400 or response.status_code == 404):\n return f\"An error occurred while making the request: {response.text}\"\n except requests.exceptions.RequestException as e:\n return f\"An error occurred while making the request: {e}\"\n else:\n return response.text \n Very important are the arguments and their description using docstrings. These will be used by LLM to understand what data it needs to provide to the tool. If, for example, the tool above had an argument named url_body instead of object_name, the LLM would try to put whatever name it finds in your prompt in the url_body. And assuming this url_body it is the payload of the API call, it would put the name in the payload. This will not give you the result you want. In other functions/tools, you will see I've used url_body argument, but in those cases, this was necessary because they are for creating and updating/modifying an object, and the configuration needs to be in the payload of an API call. \n In the end, it was not hard to build an MCP server. It is pretty easy if you already have some Python scripts. You just need to turn them into tools and use docstrings to explain the arguments of the tool. The LLM model will do the rest. Pretty amazing, don't you think? \n   \n Test \n This MCP server was tested using the Claude Desktop app on a Windows 11 machine using WSL. \n Here is a screenshot of how Claude sees the tools: \n \n Claude needs to be configured to connect to the MCP server(it is a Python file, not a VM or container). \n Here is an example of claude_desktop_config.json file : \n {\n\t\"mcpServers\": {\n\t\t\"F5McpServer\": {\n\t\t\t\"command\": \"wsl.exe\",\n\t\t\t\"args\": [\n\t\t\t\t\"bash\", \n\t\t\t\t\"-c\",\n\t\t\t\t\"source /full/path/.venv/bin/activate && python /full/path/F5MCPserver.py\"\n\t\t\t ]\n\t\t}\n\t}\n} \n wsl.exe is used because I am using a Windows 11 machine in Ubuntu in WSL. \n The rest are the commands to run the Python script of the MCP server. \n I've also tested this with a local LLM,  llama3.1, using Ollama. But in this case, it was slow, as I do not have enough resources for this (a laptop without a dedicated GPU).  It works, but it is slow. But also it is PRIVATE. \n Here is an example of show_stats_tool response for all vips, using the prompt \"can you show me the stats for all vips and put them in a markdown table side by side\" : \n \n   \n Code: \n You can find this example of an F5 MCP server here: \n GitHub - czirakim/F5.MCP.server \n   \n   \n   \n   ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"5803","kudosSumWeight":1,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zNDA3MDQtbW9jQ2tW?revision=14\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zNDA3MDQtaDJBeUhw?revision=14\"}"}}],"totalCount":2,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:285134":{"__typename":"Conversation","id":"conversation:285134","topic":{"__typename":"TkbTopicMessage","uid":285134},"lastPostingActivityTime":"2025-03-03T19:46:31.801-08:00","solved":false},"User:user:325385":{"__typename":"User","uid":325385,"login":"Patrik_Jonsson","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0zMjUzODUtMTY0MjJpNDQzQTkxREQwMjBDODY4NQ"},"id":"user:325385"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDZpQUNENUE4MDgyRkFCNEJFNg?revision=12\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDZpQUNENUE4MDgyRkFCNEJFNg?revision=12","title":"Patrik_Jonsson_0-1666904878537.png","associationType":"BODY","width":3456,"height":1434,"altText":"Patrik_Jonsson_0-1666904878537.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDdpNEM5NENFMEJEQUZBNEM1RA?revision=12\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDdpNEM5NENFMEJEQUZBNEM1RA?revision=12","title":"Patrik_Jonsson_1-1666904947099.png","associationType":"BODY","width":3444,"height":642,"altText":"Patrik_Jonsson_1-1666904947099.png"},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDhpMTY5QkUzRjM3OUJCOTM0Rg?revision=12\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDhpMTY5QkUzRjM3OUJCOTM0Rg?revision=12","title":"Patrik_Jonsson_2-1666905155620.png","associationType":"BODY","width":3456,"height":1144,"altText":"Patrik_Jonsson_2-1666905155620.png"},"TkbTopicMessage:message:285134":{"__typename":"TkbTopicMessage","subject":"BIG-IP Report","conversation":{"__ref":"Conversation:conversation:285134"},"id":"message:285134","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:285134","revisionNum":12,"uid":285134,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:325385"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":14775},"postTime":"2021-04-21T22:59:41.000-07:00","lastPublishTime":"2024-10-16T08:53:25.201-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Problem this snippet solves: \n Overview \n This is a script which will generate a report of the BIG-IP LTM configuration on all your load balancers making it easy to find information and get a comprehensive overview of virtual servers and pools connected to them. \n This information is used to relay information to NOC and developers to give them insight in where things are located and to be able to plan patching and deploys. I also use it myself as a quick way get information or gather data used as a foundation for RFC's, ie get a list of all external virtual servers without compression profiles. \n The script has been running on 13 pairs of load balancers, indexing over 1200 virtual servers for several years now and the report is widely used across the company and by many companies and governments across the world. \n It's easy to setup and use and only requires auditor (read-only) permissions on your devices. \n Demo/Preview \n Interactive demo \n http://loadbalancing.se/bigipreportdemo/ \n Screen shots \n The main report: \n The device overview: \n Certificate details: \n How to use this snippet: \n Installation instructions \n BigipReport REST \n This is the only branch we're updating since middle of 2020 and it supports 12.x and upwards (maybe even 11.6). \n \n Downloads: https://loadbalancing.se/downloads/bigipreport-v5.7.13.zip \n Documentation, installation instructions and troubleshooting: https://loadbalancing.se/bigipreport-rest/\n Docker support \n https://loadbalancing.se/2021/01/05/running-bigipreport-on-docker/ \n Kubernetes support \n https://loadbalancing.se/2021/04/16/bigipreport-on-kubernetes/ \n BIG-IP Report (Legacy) \n Older version of the report that only runs on Windows and is depending on a Powershell plugin originally written by Joe Pruitt (F5) \n BIG-IP Report (only download this if you have v10 devices): \n https://loadbalancing.se/downloads/bigipreport-5.4.0-beta.zip \n iControl Snapin \n https://loadbalancing.se/downloads/f5-icontrol.zip \n Documentation and Installation Instructions \n https://loadbalancing.se/bigip-report/ \n Upgrade instructions \n Protect the report using APM and active directory \n Written by DevCentral member Shann_P: \n https://loadbalancing.se/2018/04/08/protecting-bigip-report-behind-an-apm-by-shannon-poole/ \n Got issues/problems/feedback? \n Still have issues? Drop a comment below. We usually reply quite fast. Any bugs found, issues detected or ideas contributed makes the report better for everyone, so it's always appreciated. \n --- \n Join us on Discord: https://discord.gg/7JJvPMYahA \n Code : \n BigIP Report \n Tested this on version: \n 12, 13, 14, 15, 16 \n \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"2647","kudosSumWeight":20,"repliesCount":97,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDZpQUNENUE4MDgyRkFCNEJFNg?revision=12\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDdpNEM5NENFMEJEQUZBNEM1RA?revision=12\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yODUxMzQtMjAzNDhpMTY5QkUzRjM3OUJCOTM0Rg?revision=12\"}"}}],"totalCount":3,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:288311":{"__typename":"Conversation","id":"conversation:288311","topic":{"__typename":"TkbTopicMessage","uid":288311},"lastPostingActivityTime":"2025-02-21T07:28:02.936-08:00","solved":false},"User:user:278861":{"__typename":"User","uid":278861,"login":"Daniel_Tavernie","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/m_assets/avatars/default/avatar-12.svg?time=0"},"id":"user:278861"},"TkbTopicMessage:message:288311":{"__typename":"TkbTopicMessage","subject":"F5 iApp Automated Backup","conversation":{"__ref":"Conversation:conversation:288311"},"id":"message:288311","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:288311","revisionNum":2,"uid":288311,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:278861"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":22516},"postTime":"2018-01-24T15:35:17.000-08:00","lastPublishTime":"2022-02-15T13:09:52.083-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Problem this snippet solves: \n This is now available on GitHub! \n Please look on GitHub for the latest version, and submit any bugs or questions as an \"Issue\" on GitHub: \n (Note: DevCentral admin update - Daniel's project appears abandoned so it's been forked and updated to the link below. @damnski on github added some SFTP code that has been merged in as well.) \n https://github.com/f5devcentral/f5-automated-backup-iapp \n Intro \n Building on the significant work of Thomas Schockaert (and several other DevCentralites) I enhanced many aspects I needed for my own purposes, updated many things I noticed requested on the forums, and added additional documentation and clarification. As you may see in several of my comments on the original posts, I iterated through several 2.2.x versions and am now releasing v3.0.0. Below is the breakdown! \n Also, I have done quite a bit of testing (mostly on v13.1.0.1 lately) and I doubt I've caught everything, especially with all of the changes. Please post any questions or issues in the comments. \n Cheers! \n Daniel Tavernier (tabernarious) \n Related posts: \n \n Git Repository for f5-automated-backup-iapp (https://github.com/tabernarious/f5-automated-backup-iapp) \n https://community.f5.com/t5/technical-articles/f5-automated-backups-the-right-way/ta-p/288454 \n https://community.f5.com/t5/crowdsrc/complete-f5-automated-backup-solution/ta-p/288701 \n https://community.f5.com/t5/crowdsrc/complete-f5-automated-backup-solution-2/ta-p/274252 \n https://community.f5.com/t5/technical-forum/automated-backup-solution/m-p/24551 \n https://community.f5.com/t5/crowdsrc/tkb-p/CrowdSRC \n \n v3.2.1 (20201210) \n \n Merged v3.1.11 and v3.2.0 for explicit SFTP support (separate from SCP). \n Tweaked the SCP and SFTP upload directory handling; detailed instructions are in the iApp. \n Tested on 13.1.3.4 and 14.1.3 \n \n v3.1.11 (20201210) \n \n Better handling of UCS passphrases, and notes about characters to avoid. \n I successfully tested this exact passphrase in the 13.1.3.4 CLI (surrounded with single quote) and GUI (as-is): `~!@#$%^*()aB1-_=+[{]}:./? \n I successfully tested this exact passphrase in 14.1.3 (square-braces and curly-braces would not work): `~!@#$%^*()aB1-_=+:./? \n Though there may be situations these could work, avoid these characters (separated by spaces): \" ' & | ; < > \\ [ ] { } , \n Moved changelog and notes from the template to CHANGELOG.md and README.md. \n Replaced all tabs (\\t) with four spaces. \n \n v3.1.10 (20201209) \n \n Added SMB Version and SMB Security options to support v14+ and newer versions of Microsoft Windows and Windows Server. \n Tested SMB/CIFS on 13.1.3.4 and 14.1.3 against Windows Server 2019 using \"2.0\" and \"ntlmsspi\" \n \n v3.1.0: \n \n Removed \"app-service none\" from iCall objects. The iCall objects are now created as part of the Application Service (iApp) and are properly cleaned up if the iApp is redeployed or deleted. \n Reasonably tested on 11.5.4 HF2 (SMB worked fine using \"mount -t cifs\") and altered requires-bigip-version-min to match. \n Fixing error regarding \"script did not successfully complete: (can't read \"::destination_parameters__protocol_enable\": no such variable\" by encompassing most of the \"implementation\" in a block that first checks $::backup_schedule__frequency_select for \"Disable\". \n Added default value to \"filename format\". \n Changed UCS default value for $backup_file_name_extension to \".ucs\" and added $fname_noext. \n Removed old SFTP sections and references (now handled through SCP/SFTP). \n Adjusted logging: added \"sleep 1\" to ensure proper logging; added $backup_directory to log message. \n Adjusted some help messages. \n \n New v3.0.0 features: \n \n Supports multiple instances! (Deploy multiple copies of the iApp to save backups to different places or perhaps to keep daily backups locally and send weekly backups to a network drive.) \n Fully ConfigSync compatible! (Encrypted values now in $script instead of local file.) \n Long passwords supported! (Using \"-A\" with openssl which reads/writes base64 encoded strings as a single line.) \n Added $script error checking for all remote backup types! (Using 'catch' to prevent tcl errors when $script aborts.) \n Backup files are cleaned up after any $script errors due to new error checking. \n Added logging! (Run logs sent to '/var/log/ltm' via logger command which is compatible with BIG-IP Remote Logging configuration (syslog). Run logs AND errors sent to '/var/tmp/scriptd.out'. Errors may include plain-text passwords which should not be in /var/log/ltm or syslog.) \n Added custom cipher option for SCP! (In case BIG-IP and the destination server are not cipher-compatible out of the box.) \n Added StrictHostKeyChecking=no option. (This is insecure and should only be used for testing--lots of warnings.) \n Combined SCP and SFTP because they are both using SCP to perform the remote copy. (Easier to maintain!) \n \n Original v1.x.x and v2.x.x features kept (copied from an original post): \n \n It allows you to choose between both UCS or SCF as backup-types. (whilst providing ample warnings about SCF not being a very good restore-option due to the incompleteness in some cases) \n It allows you to provide a passphrase for the UCS archives (the standard GUI also does this, so the iApp should too) \n It allows you to not include the private keys (same thing: standard GUI does it, so the iApp does it too) \n It allows you to set a Backup Schedule for every X minutes/hours/days/weeks/months or a custom selection of days in the week \n It allows you to set the exact time, minute of the hour, day of the week or day of the month when the backup should be performed (depending on the usefulness with regards to the schedule type) \n It allows you to transfer the backup files to external devices using 4 different protocols, next to providing local storage on the device itself \n SCP (username/private key without password) \n SFTP (username/private key without password) \n FTP (username/password) \n SMB (now using TMOS v12.x.x compatible 'mount -t cifs', with username/password) \n Local Storage (/var/local/ucs or /var/local/scf) \n It stores all passwords and private keys in a secure fashion: encrypted by the master key of the unit (f5mku), rendering it safe to store the backups, including the credentials off-box \n It has a configurable automatic pruning function for the Local Storage option, so the disk doesn't fill up (i.e. keep last X backup files) \n It allows you to configure the filename using the date/time wildcards from the tcl [clock] command, as well as providing a variable to include the hostname \n It requires only the WebGUI to establish the configuration you desire \n It allows you to disable the processes for automated backup, without you having to remove the Application Service or losing any previously entered settings \n For the external shellscripts it automatically generates, the credentials are stored in encrypted form (using the master key) \n It allows you to no longer be required to make modifications on the linux command line to get your automated backups running after an RMA or restore operation \n It cleans up after itself, which means there are no extraneous shellscripts or status files lingering around after the scripts execute \n \n How to use this snippet: \n \n Find and download the latest iApp template on GitHub (e.g \"f5.automated_backup.v3.2.1.tmpl.tcl\"). \n Import the text file as an iApp Template in the BIG-IP GUI. \n Create an Application Service using the imported Template. \n Answer the questions (paying close attention to the help sections). \n Check /var/tmp/scriptd.out for general logs and errors. \n \n Tested this on version: \n 16.0 ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"7668","kudosSumWeight":5,"repliesCount":102,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:339257":{"__typename":"Conversation","id":"conversation:339257","topic":{"__typename":"TkbTopicMessage","uid":339257},"lastPostingActivityTime":"2025-01-27T10:31:41.756-08:00","solved":false},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctNURzeDJo?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctNURzeDJo?revision=6","title":"image.png","associationType":"BODY","width":1100,"height":713,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctYzlFbUdl?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctYzlFbUdl?revision=6","title":"image.png","associationType":"BODY","width":1150,"height":658,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctZHJYS2pT?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctZHJYS2pT?revision=6","title":"image.png","associationType":"BODY","width":894,"height":729,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctRzR6WkZD?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctRzR6WkZD?revision=6","title":"ce-3.PNG","associationType":"BODY","width":938,"height":919,"altText":""},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctQlUwQ01Q?revision=6\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctQlUwQ01Q?revision=6","title":"image.png","associationType":"BODY","width":763,"height":434,"altText":""},"TkbTopicMessage:message:339257":{"__typename":"TkbTopicMessage","subject":"F5 XC CE Debug commands through GUI cloud console and API","conversation":{"__ref":"Conversation:conversation:339257"},"id":"message:339257","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:communityarticles/message:339257","revisionNum":6,"uid":339257,"depth":0,"board":{"__ref":"Tkb:board:communityarticles"},"author":{"__ref":"User:user:305752"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"The XC Distributed Cloud SiteCLI debug commands were always available using a console connection or SSH access but now with the new Software releases you can send many of the commands using the XC GUI console or even the XC API.Β ","metrics":{"__typename":"MessageMetrics","views":164},"postTime":"2025-01-24T11:04:29.182-08:00","lastPublishTime":"2025-01-27T10:31:41.756-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Why this feature is important and helpful? \n   \n \n With this capability if the IPSEC/SSL tunnels are up from the Customer Edge(CE) to the Regional Edge(RE), there is no need to log into the CE, when troubleshooting is needed. This is possible for Secure Mesh(SM) and Secure Mesh V2 (SMv2) CE deployments. As XC CE are actually SDN-based ADC/proxy devices the option to execute commands from the SDN controller that is the XC cloud seems a logical next step. \n \n   \n Using the XC GUI to send SiteCLI debug commands. \n   \n \n The first example is sending the \"netstat\" command to \"master-3\" of a 3-node CE cluster. This is done under Home > Multi-Cloud Network Connect > Overview > Infrastructure > Sites and finding the site, where you want to trigger the commands. \n \n   \n \n   \n   \n \n In the VPM logs it is possible to see the command that was send in API format by searching for it or for logs starting with \"debug\", as to automate this task. If you capture and review the full log, you will even see not only the API URL endpoint but also the POST body data that needs to be added. The VPM logs that can also be seen from the web console and API, are the best place to start investigating issues. \n \n \n   \n \n XC Commands reference: \n \n Node Serviceability Commands Reference | F5 Distributed Cloud Technical Knowledge \n Troubleshooting Guidelines for Customer Edge Site | F5 Distributed Cloud Technical Knowledge \n Troubleshooting Guide for Secure Mesh Site v2 Deployment | F5 Distributed Cloud Technical Knowledge \n   \n Using the XC API to send SiteCLI debug commands. \n   \n   \n \n The same commands can be send using the XC API and first the commands can be tested and reviewed using the API doc and developer portals. API documentation even has examples of how to run these commands with vesctl that is the XC shell client that can be installed on any computer or curl. \n \n   \n \n   \n \n Postman can also be used instead of curl but the best option to test commands through the API is the developer portal. \n \n   \n \n   \n \n Postman can also be used by the \"old school\" people πŸ˜‰ \n \n \n   \n   \n \n Link reference: \n \n F5 Distributed Cloud Services API for ves.io.schema.operate.debug | F5 Distributed Cloud Technical Knowledge \n F5 Distributed Cloud Dev Portal \n ves-io-schema-operate-debug-CustomPublicAPI-Exec | F5 Distributed Cloud Technical Knowledge \n   \n   \n   \n Summary: \n   \n The option to trigger commands though the XC GUI or even the API is really useful if for example there is a need to periodically monitor the cpu or memory jump with commands like \"execcli check-mem\" or \"execcli top\" or even automating the tcpdump with \"execcli vifdump xxxx\". The use cases for this functionality really are endless. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"2842","kudosSumWeight":0,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctNURzeDJo?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctYzlFbUdl?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctZHJYS2pT?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctRzR6WkZD?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuNHwyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0zMzkyNTctQlUwQ01Q?revision=6\"}"}}],"totalCount":5,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:338179":{"__typename":"Conversation","id":"conversation:338179","topic":{"__typename":"TkbTopicMessage","uid":338179},"lastPostingActivityTime":"2025-01-16T04:53:47.045-08:00","solved":false},"User:user:126518":{"__typename":"User","uid":126518,"login":"Juergen_Mang","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0xMjY1MTgtbDFwdUZs?image-coordinates=19%2C0%2C1004%2C984"},"id":"user:126518"},"TkbTopicMessage:message:338179":{"__typename":"TkbTopicMessage","subject":"List of F5 iControl REST API Endpoints","conversation":{"__ref":"Conversation:conversation:338179"},"id":"message:338179","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:338179","revisionNum":1,"uid":338179,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:126518"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":289},"postTime":"2024-11-28T14:04:48.340-08:00","lastPublishTime":"2024-11-28T14:04:48.340-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" As I could not find a complete API Reference for the F5 iControl REST API, I created a list myself. This list is not (yet) complete. I created it with the help of an API crawler and added manually some endpoints extracted from the F5 documentation. \n It would be great if this list gets more complete by time. Feel free to fork this repository and create a pull requests for additions and corrections. Any help and feedback is very welcome! \n At the moment it is a simple plain text file. My future plans are: \n \n Complete the list of endpoints \n Publish an OpenAPI 3 file \n \n You can find the list in my public GitHub repository. \n Happy RESTing! ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"649","kudosSumWeight":2,"repliesCount":2,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"Conversation:conversation:306690":{"__typename":"Conversation","id":"conversation:306690","topic":{"__typename":"TkbTopicMessage","uid":306690},"lastPostingActivityTime":"2025-01-16T04:16:36.835-08:00","solved":false},"User:user:16006":{"__typename":"User","uid":16006,"login":"xuwen","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0xNjAwNi0yMTc2MGlGMjI4NUU0RTUxNjQ1RUJD"},"id":"user:16006"},"TkbTopicMessage:message:306690":{"__typename":"TkbTopicMessage","subject":"GTM type A and AAAA wideip NetworkMap to generate a json with python f5-sdk","conversation":{"__ref":"Conversation:conversation:306690"},"id":"message:306690","entityType":"TKB_ARTICLE","eventPath":"category:CrowdSRC/community:zihoc95639board:codeshare/message:306690","revisionNum":4,"uid":306690,"depth":0,"board":{"__ref":"Tkb:board:codeshare"},"author":{"__ref":"User:user:16006"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":2321},"postTime":"2022-12-16T05:36:31.249-08:00","lastPublishTime":"2022-12-18T18:32:55.237-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Code is community submitted, community supported, and recognized as β€˜Use At Your Own Risk’. Short Description GTM type A and AAAA NetworkMap to a json with python f5-sdk, code support check AS3 wideip. test well in BIGIP VE V14.1.5 and V16.1.2, code should work on version V12+ BIGIP Important:  gtm/ltm server name can not contains character \":\" and \"\\\" and \"/\" and gtm server virtual server name(VS NAME) also can not contains character \":\" and \"\\\",  because I use fullPath.split(':')  to read GTM-Server Name and Virtual server name(correct example such as \"fullPath\":\"/Common/DC-2-GTM-ipv4:/Common/vs_cmcc_99_22\" ) otherwise it will raise HTTP 404, below is the error format example: GTM Server name ZSCTEST:DC-1-LTM-ZSC-ipv4 GTM Server Virtual Server Name(VS NAME) test:vs \"name\":\"ZSCTEST\\\\:DC-1-LTM-ZSC-ipv4:test:vs\",\"partition\":\"Common\",\"fullPath\":\"/Common/ZSCTEST\\\\:DC-1-LTM-ZSC-ipv4:test:vs\" Problem solved by this Code Snippet collect GTM type A and AAAA data and generate a json file How to use this Code Snippet Firstly, install python f5 sdk pip install f5-sdk Secondly, modify the following IP, account and password corresponding to your BIGIP GTM device           mgmt = ManagementRoot('192.168.5.109', 'admin', 'xt32112300')           python f5-sdk send a GET request to GTM in the form of  ~partition~name, but the format of the GET request for the AS3 published wideip should be ~partition~Folder~name, so when retrieving the AS3 published wideip, the URL constructed will report HTTP 404. After reading the error source code  sitepackages\\icontrol\\session.py There is a function def _ validate_ name_ partition_ Subpath (element):           def _validate_name_partition_subpath(element):\n # '/' and '~' are illegal characters in most cases, however there are\n # few exceptions (GTM Regions endpoint being one of them where the\n # validation of name should not apply.\n \"\"\"\n if '~' in element:\n error_message =\\\n \"instance names and partitions cannot contain '~', but it's: %s\"\\\n % element\n raise InvalidInstanceNameOrFolder(error_message)\n \"\"\"           the determination of whether the name carries the character ~ will cause the structure of AS3 name=i.subPath + '~' + i.name doesn't work. so, delete the judgment of  ~  or use \"\"\" \"\"\" notes code will support AS3 wideip check Finally, if the code runs no error, it will generate a \"F5-GTM-Wideip-XXX(date format)-NetworkMap.json\" file in your local working directory Code Snippet Meta Information Version: 1.0 Coding Language: python Full Code Snippet           from f5.bigip import ManagementRoot\nimport json\nimport time\n\nwideip_NetworkMap = {}\nmgmt = ManagementRoot('192.168.5.109', 'admin', 'xt32112300')\ngtm_wideip = []\n\"\"\"\nauthor: xuwen\nemail: 1099061067@qq.com\ndate: 2022/12/16\n\"\"\"\n# GTM A Wideip\nfor i in mgmt.tm.gtm.wideips.a_s.get_collection():\n try:\n type_A_wideip = mgmt.tm.gtm.wideips.a_s.a.load(name=i.subPath + '~' + i.name if hasattr(i, 'subPath') else i.name, partition=i.partition)\n except Exception as e:\n print('type A widip name {} error msg is '.format(i.name) + str(e))\n else:\n gtm_A_wideip = {}\n type_A_wideip_name = i.name\n type_A_wideip_partition = i.partition\n if hasattr(type_A_wideip, 'aliases'):\n gtm_A_wideip['aliases'] = type_A_wideip.aliases\n\n if hasattr(type_A_wideip, 'rules'):\n gtm_A_wideip['iRules'] = type_A_wideip.rules\n\n if hasattr(type_A_wideip, 'enabled'):\n gtm_A_wideip['enabled'] = True\n else:\n gtm_A_wideip['disabled'] = True\n if hasattr(type_A_wideip, 'subPath'):\n gtm_A_wideip['subPath'] = type_A_wideip.subPath\n\n gtm_A_wideip.update(name=type_A_wideip_name, partition=type_A_wideip_partition, wideip_type='A',\n poolLbMode=type_A_wideip.poolLbMode, persistence=type_A_wideip.persistence,\n lastResortPool=type_A_wideip.lastResortPool, fullPath=type_A_wideip.fullPath)\n # print(gtm_A_wideip)\n if hasattr(type_A_wideip, 'pools'):\n gtm_A_wideip['pools'] = []\n for pool_name in type_A_wideip.pools:\n gtm_A_pool = {}\n # gtm_A_pool_name = pool_name['name']\n gtm_A_pool['name'] = pool_name['name']\n gtm_A_pool['partition'] = pool_name['partition']\n gtm_A_pool['type'] = 'A'\n gtm_A_pool['order'] = pool_name['order']\n gtm_A_pool['ratio'] = pool_name['ratio']\n if 'subPath' in pool_name.keys():\n gtm_A_pool['subPath'] = pool_name['subPath']\n gslb_A_pool = mgmt.tm.gtm.pools.a_s.a.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])\n # gslb_A_pool = mgmt.tm.gtm.pools.a_s.a.load(name=pool_name['subPath'] + '~' + pool_name['name'] if 'subPath' in pool_name.keys() else pool_name['name'], partition=pool_name['partition'])\n else:\n gslb_A_pool = mgmt.tm.gtm.pools.a_s.a.load(name=pool_name['name'], partition=pool_name['partition'])\n gtm_A_pool['fullPath'] = gslb_A_pool.fullPath\n gtm_A_pool['ttl'] = gslb_A_pool.ttl\n gtm_A_pool['loadBalancingMode'] = gslb_A_pool.loadBalancingMode\n gtm_A_pool['alternateMode'] = gslb_A_pool.alternateMode\n gtm_A_pool['fallbackMode'] = gslb_A_pool.fallbackMode\n gtm_A_pool['fallbackIp'] = gslb_A_pool.fallbackIp\n gtm_A_pool['Members'] = []\n\n # gslb_pool_members_vs_name_list = [str(mem.raw) for mem in gslb_A_pool.members_s.get_collection()]\n gslb_pool_members_vs_fullPath_list = [(mem.memberOrder, mem.fullPath, mem.ratio) for mem in\n gslb_A_pool.members_s.get_collection()]\n for pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_vs_fullPath_list:\n # print(pool_member_fullPath)\n # \"fullPath\":\"/Common/DC-2-GTM-ipv4:/Common/vs_cmcc_99_22\"\n gtm_server_name = pool_member_fullPath.split(':')[0]\n gtm_pool_members_member_name = pool_member_fullPath.split(':')[1]\n dc_gtm_virtualserver = mgmt.tm.gtm.servers.server.load(name=gtm_server_name.split('/')[2],\n partition=gtm_server_name.split('/')[1])\n\n virtualservers_virtualserver = dc_gtm_virtualserver.virtual_servers_s.virtual_server.load(\n name=gtm_pool_members_member_name\n )\n virtualserver_destination = virtualservers_virtualserver.destination\n virtualserver_Member_Address = virtualserver_destination.split(':')[0]\n virtualserver_Service_Port = virtualserver_destination.split(':')[1]\n gtm_A_pool['Members'].append({\n 'Member': gtm_pool_members_member_name,\n 'Member Order': pool_memberOrder,\n 'ratio': pool_member_ratio,\n 'Member Address': virtualserver_Member_Address,\n 'Service Port': virtualserver_Service_Port,\n 'Translation Address': virtualservers_virtualserver.translationAddress,\n 'Translation Service Port': virtualservers_virtualserver.translationPort\n })\n gtm_A_wideip['pools'].append(gtm_A_pool)\n\n if hasattr(type_A_wideip, 'poolsCname'):\n gtm_A_wideip['poolsCname'] = []\n for pool_name in type_A_wideip.poolsCname:\n gtm_A_cnamepool = {}\n # gtm_A_pool_name = pool_name['name']\n gtm_A_cnamepool['name'] = pool_name['name']\n gtm_A_cnamepool['partition'] = pool_name['partition']\n gtm_A_cnamepool['type'] = 'CNAME'\n gtm_A_cnamepool['order'] = pool_name['order']\n gtm_A_cnamepool['ratio'] = pool_name['ratio']\n if 'subPath' in pool_name.keys():\n gtm_A_cnamepool['subPath'] = pool_name['subPath']\n gslb_A_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])\n\n else:\n gslb_A_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['name'], partition=pool_name['partition'])\n gtm_A_cnamepool['fullPath'] = gslb_A_cnamepool.fullPath\n gtm_A_cnamepool['ttl'] = gslb_A_cnamepool.ttl\n gtm_A_cnamepool['loadBalancingMode'] = gslb_A_cnamepool.loadBalancingMode\n gtm_A_cnamepool['alternateMode'] = gslb_A_cnamepool.alternateMode\n gtm_A_cnamepool['fallbackMode'] = gslb_A_cnamepool.fallbackMode\n gtm_A_cnamepool['Members'] = []\n gslb_pool_members_domainname_fullPath_list = [(mem.name, mem.memberOrder, mem.fullPath, mem.ratio)\n for mem in gslb_A_cnamepool.members_s.get_collection()]\n for pool_member_name, pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_domainname_fullPath_list:\n gtm_A_cnamepool['Members'].append({\n 'Member': pool_member_name,\n 'Member Order': pool_memberOrder,\n 'ratio': pool_member_ratio,\n 'fullPath': pool_member_fullPath\n })\n gtm_A_wideip['poolsCname'].append(gtm_A_cnamepool)\n # print(gtm_A_wideip)\n gtm_wideip.append(gtm_A_wideip)\n\n\n# GTM AAAA Wideip\nfor i in mgmt.tm.gtm.wideips.aaaas.get_collection():\n try:\n type_AAAA_wideip = mgmt.tm.gtm.wideips.aaaas.aaaa.load(name=i.subPath + '~' + i.name if hasattr(i, 'subPath') else i.name, partition=i.partition)\n except Exception as e:\n print('type AAAA widip name {} error msg is '.format(i.name) + str(e))\n else:\n gtm_AAAA_wideip = {}\n type_AAAA_wideip_name = i.name\n type_AAAA_wideip_partition = i.partition\n if hasattr(type_AAAA_wideip, 'aliases'):\n gtm_AAAA_wideip['aliases'] = type_AAAA_wideip.aliases\n\n if hasattr(type_AAAA_wideip, 'rules'):\n gtm_AAAA_wideip['iRules'] = type_AAAA_wideip.rules\n\n if hasattr(type_AAAA_wideip, 'enabled'):\n gtm_AAAA_wideip['enabled'] = True\n else:\n gtm_AAAA_wideip['disabled'] = True\n if hasattr(type_AAAA_wideip, 'subPath'):\n gtm_AAAA_wideip['subPath'] = type_AAAA_wideip.subPath\n\n gtm_AAAA_wideip.update(name=type_AAAA_wideip_name, partition=type_AAAA_wideip_partition, wideip_type='AAAA',\n poolLbMode=type_AAAA_wideip.poolLbMode, persistence=type_AAAA_wideip.persistence,\n lastResortPool=type_AAAA_wideip.lastResortPool, fullPath=type_AAAA_wideip.fullPath)\n\n if hasattr(type_AAAA_wideip, 'pools'):\n gtm_AAAA_wideip['pools'] = []\n for pool_name in type_AAAA_wideip.pools:\n gtm_AAAA_pool = {}\n # gtm_A_pool_name = pool_name['name']\n gtm_AAAA_pool['name'] = pool_name['name']\n gtm_AAAA_pool['partition'] = pool_name['partition']\n gtm_AAAA_pool['type'] = 'AAAA'\n gtm_AAAA_pool['order'] = pool_name['order']\n gtm_AAAA_pool['ratio'] = pool_name['ratio']\n if 'subPath' in pool_name.keys():\n gtm_AAAA_pool['subPath'] = pool_name['subPath']\n gslb_AAAA_pool = mgmt.tm.gtm.pools.aaaas.aaaa.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])\n\n else:\n gslb_AAAA_pool = mgmt.tm.gtm.pools.aaaas.aaaa.load(name=pool_name['name'], partition=pool_name['partition'])\n gtm_AAAA_pool['fullPath'] = gslb_AAAA_pool.fullPath\n gtm_AAAA_pool['ttl'] = gslb_AAAA_pool.ttl\n gtm_AAAA_pool['loadBalancingMode'] = gslb_AAAA_pool.loadBalancingMode\n gtm_AAAA_pool['alternateMode'] = gslb_AAAA_pool.alternateMode\n gtm_AAAA_pool['fallbackMode'] = gslb_AAAA_pool.fallbackMode\n gtm_AAAA_pool['fallbackIp'] = gslb_AAAA_pool.fallbackIp\n gtm_AAAA_pool['Members'] = []\n\n # gslb_pool_members_vs_name_list = [str(mem.raw) for mem in gslb_A_pool.members_s.get_collection()]\n gslb_pool_members_vs_fullPath_list = [(mem.memberOrder, mem.fullPath, mem.ratio) for mem in\n gslb_AAAA_pool.members_s.get_collection()]\n for pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_vs_fullPath_list:\n # print(pool_member_fullPath)\n # \"fullPath\":\"/Common/DC-2-GTM-ipv4:/Common/vs_cmcc_99_22\"\n gtm_server_name = pool_member_fullPath.split(':')[0]\n gtm_pool_members_member_name = pool_member_fullPath.split(':')[1]\n dc_gtm_virtualserver = mgmt.tm.gtm.servers.server.load(name=gtm_server_name.split('/')[2],\n partition=gtm_server_name.split('/')[1])\n\n virtualservers_virtualserver = dc_gtm_virtualserver.virtual_servers_s.virtual_server.load(\n name=gtm_pool_members_member_name\n )\n virtualserver_destination = virtualservers_virtualserver.destination\n virtualserver_Member_Address = virtualserver_destination.split('.')[0]\n virtualserver_Service_Port = virtualserver_destination.split('.')[1]\n gtm_AAAA_pool['Members'].append({\n 'Member': gtm_pool_members_member_name,\n 'Member Order': pool_memberOrder,\n 'ratio': pool_member_ratio,\n 'Member Address': virtualserver_Member_Address,\n 'Service Port': virtualserver_Service_Port,\n 'Translation Address': virtualservers_virtualserver.translationAddress,\n 'Translation Service Port': virtualservers_virtualserver.translationPort\n })\n gtm_AAAA_wideip['pools'].append(gtm_AAAA_pool)\n\n if hasattr(type_AAAA_wideip, 'poolsCname'):\n gtm_AAAA_wideip['poolsCname'] = []\n for pool_name in type_AAAA_wideip.poolsCname:\n gtm_AAAA_cnamepool = {}\n\n gtm_AAAA_cnamepool['name'] = pool_name['name']\n gtm_AAAA_cnamepool['partition'] = pool_name['partition']\n gtm_AAAA_cnamepool['type'] = 'CNAME'\n gtm_AAAA_cnamepool['order'] = pool_name['order']\n gtm_AAAA_cnamepool['ratio'] = pool_name['ratio']\n if 'subPath' in pool_name.keys():\n gtm_AAAA_cnamepool['subPath'] = pool_name['subPath']\n gslb_AAAA_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['subPath'] + '~' + pool_name['name'], partition=pool_name['partition'])\n\n else:\n gslb_AAAA_cnamepool = mgmt.tm.gtm.pools.cnames.cname.load(name=pool_name['name'], partition=pool_name['partition'])\n gtm_AAAA_cnamepool['fullPath'] = gslb_AAAA_cnamepool.fullPath\n gtm_AAAA_cnamepool['ttl'] = gslb_AAAA_cnamepool.ttl\n gtm_AAAA_cnamepool['loadBalancingMode'] = gslb_AAAA_cnamepool.loadBalancingMode\n gtm_AAAA_cnamepool['alternateMode'] = gslb_AAAA_cnamepool.alternateMode\n gtm_AAAA_cnamepool['fallbackMode'] = gslb_AAAA_cnamepool.fallbackMode\n gtm_AAAA_cnamepool['Members'] = []\n gslb_pool_members_domainname_fullPath_list = [(mem.name, mem.memberOrder, mem.fullPath, mem.ratio)\n for mem in gslb_AAAA_cnamepool.members_s.get_collection()]\n for pool_member_name, pool_memberOrder, pool_member_fullPath, pool_member_ratio in gslb_pool_members_domainname_fullPath_list:\n gtm_AAAA_cnamepool['Members'].append({\n 'Member': pool_member_name,\n 'Member Order': pool_memberOrder,\n 'ratio': pool_member_ratio,\n 'fullPath': pool_member_fullPath\n })\n gtm_AAAA_wideip['poolsCname'].append(gtm_AAAA_cnamepool)\n # print(gtm_AAAA_wideip)\n gtm_wideip.append(gtm_AAAA_wideip)\n\n\ngtm_networkmap = {}\ngtm_networkmap.update(wideips=gtm_wideip)\nprint(gtm_networkmap)\n\nwith open(r\"./F5-GTM-Wideip-{}-NetworkMap.json\".format(time.strftime(\"%Y-%m-%d\", time.localtime())), \"w\") as f:\n f.write(json.dumps(gtm_networkmap, indent=4, ensure_ascii=False))             ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"17554","kudosSumWeight":2,"repliesCount":7,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:text:en_US-components/community/Navbar-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1751558338022","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","migrated-link-9":"Groups","migrated-link-7":"Technical Articles","migrated-link-8":"DevCentral News","migrated-link-1":"Technical Forum","migrated-link-10":"Community Groups","migrated-link-2":"Water Cooler","migrated-link-11":"F5 Groups","Common-external-link":"How Do I...?","migrated-link-0":"Forums","article-series":"Article Series","migrated-link-5":"Community Articles","migrated-link-6":"Articles","security-insights":"Security Insights","migrated-link-3":"CrowdSRC","migrated-link-4":"CodeShare","migrated-link-12":"Events","migrated-link-13":"Suggestions"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1751558338022","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1751558338022","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1751558338022","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1751558338022","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1751558338022","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagSubscriptionAction-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagSubscriptionAction-1751558338022","value":{"success.follow.title":"Following Tag","success.unfollow.title":"Unfollowed Tag","success.follow.message.followAcrossCommunity":"You will be notified when this tag is used anywhere across the community","success.unfollowtag.message":"You will no longer be notified when this tag is used anywhere in this place","success.unfollowtagAcrossCommunity.message":"You will no longer be notified when this tag is used anywhere across the community","unexpected.error.title":"Error - Action Failed","unexpected.error.message":"An unidentified problem occurred during the action you took. Please try again later.","buttonTitle":"{isSubscribed, select, true {Unfollow} false {Follow} other{}}","unfollow":"Unfollow"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1751558338022","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1751558338022","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListTabs-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListTabs-1751558338022","value":{"mostKudoed":"{value, select, IDEA {Most Votes} other {Most Likes}}","mostReplies":"Most Replies","mostViewed":"Most Viewed","newest":"{value, select, IDEA {Newest Ideas} OCCASION {Newest Events} other {Newest Topics}}","newestOccasions":"Newest Events","mostRecent":"Most Recent","noReplies":"No Replies Yet","noSolutions":"No Solutions Yet","solutions":"Solutions","mostRecentUserContent":"Most Recent","trending":"Trending","draft":"Drafts","spam":"Spam","abuse":"Abuse","moderation":"Moderation","tags":"Tags","PAST":"Past","UPCOMING":"Upcoming","sortBymostRecent":"Sort By Most Recent","sortBymostRecentUserContent":"Sort By Most Recent","sortBymostKudoed":"Sort By Most Likes","sortBymostReplies":"Sort By Most Replies","sortBymostViewed":"Sort By Most Viewed","sortBynewest":"Sort By Newest Topics","sortBynewestOccasions":"Sort By Newest Events","otherTabs":" Messages list in the {tab} for {conversationStyle}","guides":"Guides","archives":"Archives"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewInline-1751558338022","value":{"bylineAuthor":"{bylineAuthor}","bylineBoard":"{bylineBoard}","anonymous":"Anonymous","place":"Place {bylineBoard}","gotoParent":"Go to parent {name}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Pager/PagerLoadMore-1751558338022","value":{"loadMore":"Show More"},"localOverride":false},"CachedAsset:text:en_US-components/customComponent/CustomComponent-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/customComponent/CustomComponent-1751558338022","value":{"errorMessage":"Error rendering component id: {customComponentId}","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/OverflowNav-1751558338022","value":{"toggleText":"More"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1751558338022","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1751558338022","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1751558338022","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1751558338022","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1751558338022","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageUnreadCount-1751558338022","value":{"unread":"{count} unread","comments":"{count, plural, one { unread comment} other{ unread comments}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageViewCount-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageViewCount-1751558338022","value":{"textTitle":"{count, plural,one {View} other{Views}}","views":"{count, plural, one{View} other{Views}}"},"localOverride":false},"CachedAsset:text:en_US-components/kudos/KudosCount-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/kudos/KudosCount-1751558338022","value":{"textTitle":"{count, plural,one {{messageType, select, IDEA{Vote} other{Like}}} other{{messageType, select, IDEA{Votes} other{Likes}}}}","likes":"{count, plural, one{like} other{likes}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRepliesCount-1751558338022","value":{"textTitle":"{count, plural,one {{conversationStyle, select, IDEA{Comment} OCCASION{Comment} other{Reply}}} other{{conversationStyle, select, IDEA{Comments} OCCASION{Comments} other{Replies}}}}","comments":"{count, plural, one{Comment} other{Comments}}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1751558338022":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1751558338022","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false}}}},"page":"/tags/TagPage/TagPage","query":{"nodeId":"category:CrowdSRC","messages.widget.messagelistfornodebyrecentactivitywidget-tab-main-messages-list-for-tag-widget-0":"mostRecent","tagName":"devops"},"buildId":"3XH0qYWYCnEYycuN5W4S8","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","surveysEnabled":true,"openTelemetry":{"clientEnabled":false,"configName":"f5","serviceVersion":"25.4.0","universe":"prod","collector":"http://localhost:4318","logLevel":"error","routeChangeAllowedTime":"5000","headers":"","enableDiagnostic":"false","maxAttributeValueLength":"4095"},"apolloDevToolsEnabled":false,"quiltLazyLoadThreshold":"3"},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["components_customComponent_CustomComponent","components_community_Navbar_NavbarWidget","components_community_Breadcrumb_BreadcrumbWidget","components_tags_TagsHeaderWidget","components_messages_MessageListForNodeByRecentActivityWidget","components_tags_TagSubscriptionAction","components_customComponent_CustomComponentContent_TemplateContent","shared_client_components_common_List_ListGroup","components_messages_MessageView","components_messages_MessageView_MessageViewInline","shared_client_components_common_Pager_PagerLoadMore","components_customComponent_CustomComponentContent_HtmlContent","components_customComponent_CustomComponentContent_CustomComponentScripts"],"appGip":true,"scriptLoader":[]}